Runtime files
For compiling a bytecode executable to JavaScript, one often need to pass JavaScript runtime files for some OCaml libraries used by the executable. Tracking the required runtime files is done using the de-facto standard for library management in OCaml, Findlib.
Listing js runtime files
To list all JavaScript runtime files for a set of libraries:
ocamlfind query -format "%+(jsoo_runtime)" -r LIB1 LIB2 ... | grep -v "^$"
For example, for base and time_now
$ ocamlfind query -format "%+(jsoo_runtime)" -r base time_now | grep -v "^$" ~/.opam/4.14.0/lib/base/base_internalhash_types/runtime.js ~/.opam/4.14.0/lib/base/runtime.js ~/.opam/4.14.0/lib/time_now/runtime.js
Here is minimal example of manually compiling a single ml file program:
$ export LIBS=base,time_now $ ocamlfind ocamlc -package $LIBS -linkpkg main.ml -o main.byte $ js_of_ocaml $(ocamlfind query -format "%+(jsoo_runtime)" -r $LIBS) main.byte
Declaring runtime JavaScript files inside a META file
The jsoo_runtime variable is used to declare one or more runtime files. Files must be coma-separated and should be plain names relative to the package directory.
For example, to declare that mypackage.sublib requires the file mypackage/subdir/runtime.js
cat mypackage/META package "sublib" ( directory = "subdir" jsoo_runtime = "runtime.js" )
While the mechanism allows arbitrary naming for the javascript files, if there is only one file, we suggest naming it runtime.js by convention.
The old deprecated way
Before dune and its native support for js_of_ocaml, the (hacky) way to rely on Findlib was to use a linkopts variable with a javascript predicate linkopts(javascript) and have js_of_ocaml be responsible for looking up the files in the right directory.
This approach is not very satisfying:
- It makes it harder for a build system to know the set of dependencies.
- The js_of_ocaml compiler needs to perform findlib resolution itself.
Listing linkopts
To list all linkopts(javascript) for a set of libraries:
ocamlfind query -o-format -r -predicates javascript LIB1 LIB2 ...
For example, for base and time_now
$ ocamlfind query -o-format -r -predicates javascript base time_now +base/base_internalhash_types/runtime.js +base/runtime.js +time_now/runtime.js
Declaring runtime JavaScript files inside META files
The content of linkopts(javascript) is given directly to the js_of_ocaml compiler. To be able reference files independently of the installation path, we rely on js_of_ocaml's findlib support (see Command-Line findlib support below).
For example, to declare that mypackage.sublib requires the file mypackage/subdir/runtime.js
cat mypackage/META package "sublib" ( directory = "subdir" linkopts(javascript) = "+mypackage/sublib/runtime.js" )
Command line findlib support (deprecated)
If js_of_ocaml is compiled with findlib support, one can use the following syntax to reference JavaScript files:
- +{findlib-package}/{javascript-file}
- +{javascript-file}
The file javascript-file will be looked up inside the findlib-package lib directory.
When no package is provided, the compiler will look inside js_of_ocaml-compiler lib directory.
For example, if findlib install all libraries inside ${LIBDIR}:
- +mypackage/jsfile.js resolves to ${LIBDIR}/mypackage/jsfile.js
- +mypackage/dir/jsfile.js resolves to ${LIBDIR}/mypackage/dir/jsfile.js
- +toplevel.js resolves to ${LIBDIR}/js_of_ocaml-compiler/jsfile.js
Compatibility
dune generate META files that are usable with the old deprecated way. However, it only uses jsoo_runtime to look up information.
js_of_ocaml-ocamlbuild uses jsoo_runtime by default starting with version 5.0.