Skip to content

Commit 1f3ecf6

Browse files
authored
Doc: document findlib interaction (#1323)
1 parent 48dd3c2 commit 1f3ecf6

File tree

5 files changed

+124
-23
lines changed

5 files changed

+124
-23
lines changed

manual/linker.wiki

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,19 @@
22
The Js_of_ocaml compiler accepts JavaScript files provided on the command-line.
33
The main purpose is to provide (external) primitives needed by the bytecode program.
44

5-
Most of the primitives from the standard library are already implemented and loaded by default (located in "runtime.js").
5+
Most of the primitives from the standard library are already implemented and loaded by default.
66

7-
Additionally, some other primitives are installed but not loaded by default:
8-
* "+toplevel.js" : when compiling toplevel
7+
Additionally, some other primitives are available but not loaded by default:
8+
* "+toplevel.js" and "+dynlink.js" when compiling toplevel and/or using dynlink.
99

1010
== Command-line
1111
Pass the JavaScript file (must have a ".js" extension)
1212
<<code |
1313
js_of_ocaml jsfile.js a.byte
1414
>>
1515

16-
Or load it from a findlib package
17-
<<code |
18-
js_of_ocaml +mypackage/jsfile.js a.byte
19-
>>
20-
The file **jsfile.js** will be looked up inside **mypackage** lib directory.
21-
When no package is provided, the compiler will look inside js_of_ocaml-compiler lib directory.
16+
See the <<a_manual chapter="runtime-files" |runtime files>> chapter for how to
17+
discover runtime files.
2218

2319
== Provide your own JavaScript
2420
You may need to provide extra JavaScript files to provide missing primitives or to override existing ones.

manual/menu.wiki

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
==[[tailcall|About tailcall optimization]]
2222

2323
=Misc
24+
==[[runtime-files|How to look up runtime files]]
2425
==[[debug|How to debug a program]]
2526
==[[contribute|How to contribute]]
2627
==[[performances|Performances]]

manual/overview.wiki

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ For alternatives, see <<a_manual chapter="install" |Install>>.
4747

4848
=== with ocamlbuild and oasis ===
4949
Js_of_ocaml also provide an ocamlbuild plugin.
50-
See <<a_api subproject="js_of_ocaml-ocamlbuild"|module Ocamlbuild_js_of_ocaml>>.
50+
See [[https://github.com/ocsigen/js_of_ocaml-ocamlbuild/blob/master/ocamlbuild_js_of_ocaml.mli|js_of_ocaml-ocamlbuild>>.
5151
5252
=== with dune ===
5353
Dune has native support for js_of_ocaml.

manual/runtime-files.wiki

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
= Runtime files =
2+
3+
For compiling a bytecode executable to JavaScript, one often need to pass
4+
JavaScript runtime files for some OCaml libraries used by the
5+
executable. Tracking the required runtime files is done using the de-facto
6+
standard for library management in OCaml, Findlib.
7+
8+
9+
== Listing js runtime files
10+
11+
To list all JavaScript runtime files for a set of libraries:
12+
13+
{{{
14+
ocamlfind query -format "%+(jsoo_runtime)" -r LIB1 LIB2 ... | grep -v "^$"
15+
}}}
16+
17+
For example, for **base** and **time_now**
18+
19+
{{{
20+
$ ocamlfind query -format "%+(jsoo_runtime)" -r base time_now | grep -v "^$"
21+
~/.opam/4.14.0/lib/base/base_internalhash_types/runtime.js
22+
~/.opam/4.14.0/lib/base/runtime.js
23+
~/.opam/4.14.0/lib/time_now/runtime.js
24+
}}}
25+
26+
Here is minimal example of manually compiling a single ml file program:
27+
{{{
28+
$ export LIBS=base,time_now
29+
$ ocamlfind ocamlc -package $LIBS -linkpkg main.ml -o main.byte
30+
$ js_of_ocaml $(ocamlfind query -format "%+(jsoo_runtime)" -r $LIBS) main.byte
31+
}}}
32+
33+
== Declaring runtime JavaScript files inside a META file
34+
35+
The **jsoo_runtime** variable is used to declare one or more runtime files.
36+
Files must be coma-separated and should be plain names relative to the package directory.
37+
38+
For example, to declare that **mypackage.sublib** requires the file **mypackage/subdir/runtime.js**
39+
{{{
40+
cat mypackage/META
41+
package "sublib" (
42+
directory = "subdir"
43+
jsoo_runtime = "runtime.js"
44+
)
45+
}}}
46+
47+
While the mechanism allows arbitrary naming for the javascript files,
48+
if there is only one file, we suggest naming it **runtime.js** by
49+
convention.
50+
51+
== The old deprecated way
52+
53+
Before dune and its native support for js_of_ocaml, the (hacky) way
54+
to rely on Findlib was to use a **linkopts** variable with a **javascript**
55+
predicate {{{linkopts(javascript)}}} and have js_of_ocaml be responsible for
56+
looking up the files in the right directory.
57+
58+
This approach is not very satisfying:
59+
* It makes it harder for a build system to know the set of dependencies.
60+
* The js_of_ocaml compiler needs to perform findlib resolution itself.
61+
62+
=== Listing linkopts
63+
64+
To list all {{{linkopts(javascript)}}} for a set of libraries:
65+
66+
{{{
67+
ocamlfind query -o-format -r -predicates javascript LIB1 LIB2 ...
68+
}}}
69+
70+
For example, for **base** and **time_now**
71+
72+
{{{
73+
$ ocamlfind query -o-format -r -predicates javascript base time_now
74+
+base/base_internalhash_types/runtime.js
75+
+base/runtime.js
76+
+time_now/runtime.js
77+
}}}
78+
79+
=== Declaring runtime JavaScript files inside META files
80+
81+
The content of {{{linkopts(javascript)}}} is given directly to the
82+
js_of_ocaml compiler. To be able reference files independently of the
83+
installation path, we rely on js_of_ocaml's findlib support (see Command-Line findlib support below).
84+
85+
For example, to declare that **mypackage.sublib** requires the file **mypackage/subdir/runtime.js**
86+
87+
{{{
88+
cat mypackage/META
89+
package "sublib" (
90+
directory = "subdir"
91+
linkopts(javascript) = "+mypackage/sublib/runtime.js"
92+
)
93+
}}}
94+
95+
== Command line findlib support (deprecated)
96+
If js_of_ocaml is compiled with findlib support, one can use the
97+
following syntax to reference JavaScript files:
98+
* {{{ +{findlib-package}/{javascript-file} }}}
99+
* {{{ +{javascript-file} }}}
100+
101+
The file **javascript-file** will be looked up inside the **findlib-package** lib directory.
102+
103+
When no package is provided, the compiler will look inside js_of_ocaml-compiler lib directory.
104+
105+
For example, if findlib install all libraries inside ${LIBDIR}:
106+
* {{{+mypackage/jsfile.js}}} resolves to {{{${LIBDIR}/mypackage/jsfile.js}}}
107+
* {{{+mypackage/dir/jsfile.js}}} resolves to {{{${LIBDIR}/mypackage/dir/jsfile.js}}}
108+
* {{{+toplevel.js}}} resolves to {{{${LIBDIR}/js_of_ocaml-compiler/jsfile.js}}}
109+
110+
== Compatibility
111+
112+
**dune** generate META files that are usable with the old deprecated
113+
way. However, it only uses **jsoo_runtime** to look up information.
114+
115+
**js_of_ocaml-ocamlbuild** uses **jsoo_runtime** by default starting with version 5.0.

manual/separate-compilation.wiki

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,8 @@ Additional runtime files are sometime needed and can be passed on the
3838
command line. In particular, some packages/libraries come with their
3939
own runtime file.
4040

41-
As an example, compiling a program that has a dependency on {{{base}}}
42-
will require the {{{runtime.js}}}} file provided by base.
43-
44-
{{{
45-
js_of_ocaml --runtime-only -o my-runtime.js PATH_TO_BASE_LIB/runtime.js dummy
46-
}}}
47-
48-
If js_of_ocaml is compiled with findlib support, one can also use the
49-
following syntax {{{ +{findlib-package}/{javascript-file} }}}.
50-
51-
{{{
52-
js_of_ocaml --runtime-only -o my-runtime.js +base/runtime.js dummy
53-
}}}
41+
See the <<a_manual chapter="runtime-files" |runtime files>> chapter for how to
42+
discover these files.
5443

5544
=== 2. Build compilation units
5645

0 commit comments

Comments
 (0)