-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wasm_of_ocaml support #11093
Wasm_of_ocaml support #11093
Conversation
3c35724
to
8122af8
Compare
doc/wasmoo.rst
Outdated
.. code:: console | ||
|
||
$ dune build ./foo.bc.wasm.js | ||
$ node _build/default/foo.bc.wasm.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do I need to specify the submodes here? Dune could find out what to build for this wasm.js target on its own, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation has not been updated. That should be the following above:
(executable (name foo) (modes wasm))
But yes, you can just use dune build
.
Not that this was just copied from the Js_of_ocaml part of the doc:
Lines 38 to 44 in b409963
And then request the ``.js`` target: | |
.. code:: console | |
$ dune build ./foo.bc.js | |
$ node _build/default/foo.bc.js | |
hello from js |
83731d5
to
ec321a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a quick look, I think I prefer this approach better.
It seems you have not implemented the generation of a bc.js when js_of_ocaml is disabled, do you still want it ?
src/dune_rules/exe_rules.ml
Outdated
Js_of_ocaml.Mode.Set.inter jsoo_enabled_modes jsoo_is_whole_program | ||
in | ||
let bytecode_exe_needed = | ||
L.Map.foldi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
L.Map.exists
src/dune_rules/inline_tests.ml
Outdated
| Wasm -> Exe.Linkage.wasm | ||
in | ||
if Js_of_ocaml.Mode.Pair.select ~mode:jsoo_mode jsoo_is_whole_program | ||
then [ Exe.Linkage.byte_for_jsoo; linkage ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we have an issue if byte_for_jsoo
appears twice (once for js and once for wasm)
src/dune_rules/jsoo/js_of_ocaml.ml
Outdated
| JS | ||
| Wasm | ||
|
||
let equal = Poly.equal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let equal = Poly.equal | |
let equal (a : t) b = Poly.equal a b |
src/dune_rules/jsoo/js_of_ocaml.ml
Outdated
let union = Pair.map2 ~f:( || ) | ||
let is_empty (x : t) = not (x.js || x.wasm) | ||
|
||
let to_list (x : t) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let to_list (x : t) = | |
let to_list ({ wasm; js}: t) = |
src/dune_rules/jsoo/js_of_ocaml.ml
Outdated
match mode with | ||
| Mode.JS -> "js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
match mode with | |
| Mode.JS -> "js" | |
match (mode : Mode.t) with | |
| JS -> "js" |
src/dune_rules/jsoo/js_of_ocaml.ml
Outdated
@@ -242,6 +358,7 @@ module Env = struct | |||
; sourcemap = None | |||
; runtest_alias = None | |||
; flags = Flags.default ~profile | |||
; enabled_if = Some Blang.true_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Some
and not None
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so that we don't need a case for None
there:
dune/src/dune_rules/jsoo/jsoo_rules.ml
Lines 18 to 20 in ec321a5
(match parent.enabled_if with | |
| Some (Const default) -> default | |
| _ -> assert false) |
dune/src/dune_rules/jsoo/jsoo_rules.ml
Lines 603 to 605 in ec321a5
(match js_of_ocaml.enabled_if with | |
| Some (Const default) -> Memo.return default | |
| _ -> assert false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be either to read if there were less hidden invariants. What do you think of the following ?
diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml
index dc2fad30a..2c8c8e185 100644
--- a/src/dune_rules/jsoo/js_of_ocaml.ml
+++ b/src/dune_rules/jsoo/js_of_ocaml.ml
@@ -358,7 +358,7 @@ module Env = struct
; sourcemap = None
; runtest_alias = None
; flags = Flags.default ~profile
- ; enabled_if = Some Blang.true_
+ ; enabled_if = None
}
;;
end
diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml
index b10ac8f27..98b29afeb 100644
--- a/src/dune_rules/jsoo/jsoo_rules.ml
+++ b/src/dune_rules/jsoo/jsoo_rules.ml
@@ -12,18 +12,16 @@ let compute_env ~mode =
let local = Js_of_ocaml.Mode.select ~mode local.js_of_ocaml local.wasm_of_ocaml in
let* parent = parent in
let+ enabled_if =
- match local.enabled_if with
- | None ->
- Memo.return
- (match parent.enabled_if with
- | Some (Const default) -> default
- | _ -> assert false)
- | Some enabled_if -> Expander.eval_blang expander enabled_if
+ match Option.first_some local.enabled_if parent.enabled_if with
+ | Some enabled_if ->
+ let+ v = Expander.eval_blang expander enabled_if in
+ Some (Blang.Const v)
+ | None -> Memo.return None
in
{ Js_of_ocaml.Env.compilation_mode =
Option.first_some local.compilation_mode parent.compilation_mode
; sourcemap = Option.first_some local.sourcemap parent.sourcemap
- ; enabled_if = Some (Const enabled_if)
+ ; enabled_if
; runtest_alias = Option.first_some local.runtest_alias parent.runtest_alias
; flags =
Js_of_ocaml.Flags.make
@@ -601,8 +599,8 @@ let jsoo_enabled
| None ->
let* js_of_ocaml = jsoo_env ~dir ~mode in
(match js_of_ocaml.enabled_if with
- | Some (Const default) -> Memo.return default
- | _ -> assert false)
+ | Some enabled_if -> eval enabled_if
+ | None -> Memo.return true)
;;
let jsoo_enabled_modes ~expander ~dir ~in_context =
| Some x -> Memo.return x | ||
in | ||
let runtime_files = javascript_files @ wasm_files in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks weird. Is it the case that wasm_files is always empty when mode is js ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's the case:
dune/src/dune_rules/jsoo/js_of_ocaml.ml
Lines 227 to 234 in ec321a5
and+ wasm_files = | |
match mode with | |
| Mode.JS -> return [] | |
| Wasm -> | |
field | |
"wasm_files" | |
(Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> repeat string) | |
~default:[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could add an assertion.
@vouillon could you submit a version of ocsigen/js_of_ocaml#1724 using this PR ? |
It does not fit well. For the wasm_of_ocaml test suite, I have switched to using dune test stanzas and only had to add a few rules to copy a bc.wasm.js file to bc.js. |
9f3eb50
to
4a389d5
Compare
This looks good, I left one last suggestion. The documentation still needs to be updated |
04c28d2
to
a837c52
Compare
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
afff2b0
to
eba508f
Compare
Signed-off-by: Jérôme Vouillon <[email protected]>
eba508f
to
d31295f
Compare
@@ -110,11 +110,17 @@ end = struct | |||
(List.rev_concat_map | |||
~f:(List.rev_map ~f:(fun f -> Section.Lib, f)) | |||
(let { Mode.Dict.byte; native } = Lib_info.archives lib in | |||
let jsoo_files = | |||
(* A same runtime file can be used both for jsoo and wasmoo *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that comment still make sense now that jsoo and wasm options are different ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it still makes sense. In particular, one may want to pass a JavaScript file to wasm_of_ocaml to get some primitive purity information. Or one need to include some JavaScript code both when generating JavaScript and Wasm code. For instance, I have this for the virtual_dom
package:
(js_of_ocaml
(javascript_files ../lib/virtualdom.compiled.js ./thunk.js ./hooks.js))
(wasm_of_ocaml
(javascript_files ../lib/virtualdom.compiled.js ./thunk.js ./hooks.js))
src/dune_rules/jsoo/jsoo_rules.ml
Outdated
let name = Path.basename fn in | ||
let dir = in_build_dir build_context ~config [ lib_name ] in | ||
let in_context = | ||
{ Js_of_ocaml.In_context.flags = Js_of_ocaml.Flags.standard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be Js_of_ocaml.In_context.default
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is your code...
But yes, that should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is your code...
I know
src/dune_rules/stanzas/buildable.ml
Outdated
(Js_of_ocaml.In_buildable.decode ~executable ~mode:JS) | ||
~default:Js_of_ocaml.In_buildable.default | ||
and+ wasm_of_ocaml = | ||
let executable = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be lifted up and shared with the one inside js_of_ocaml above
I don't know either. We could also let dune complain if one tries to use |
Signed-off-by: Jérôme Vouillon <[email protected]>
daa107e
to
be2bd4a
Compare
Or rather it should complain for |
src/dune_rules/jsoo/js_of_ocaml.ml
Outdated
"compilation_mode" | ||
(Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Compilation_mode.decode) | ||
else return None | ||
only_in_library |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be only_in_executable
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
734967d
to
aea189c
Compare
================= | ||
|
||
Dune has full support for building wasm_of_ocaml libraries and executables transparently. | ||
There's no need to customise or enable anything to compile OCaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the documentation mention the external dependencies that are required for the build ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now explicitly point to the github repository above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved. One will need to squash commits before merging
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
Signed-off-by: Jérôme Vouillon <[email protected]>
9c5c761
to
f76b05e
Compare
I have made another clean-up pass. |
.github/workflows/workflow.yml
Outdated
with: | ||
ocaml-compiler: 4.14.x | ||
opam-pin: false | ||
opam-depext: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opam depext is unused in setup-ocaml v3
Signed-off-by: Jérôme Vouillon <[email protected]>
LGTM. Feel free to send the docs in another PR |
@hhugo @rgrinberg This is an alternative design. What do you think about it?
This adds a
wasm
mode. All thejs_of_ocaml
options are duplicated aswasm_of_ocaml
options. There is a(js_of_ocaml (enabled_if <blang expression>))
and(wasm_of_ocaml (enabled_if <blang expression>))
option inenv
andexecutable
stanzas to control whether thejs
andwasm
modes are enabled.I have not updated the documentation yet.