Skip to content
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

fix(melange): depend on selected impl when setting up JS rules for virtual lib #10051

Merged
merged 3 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ppx_inline_test \
ppxlib \
ctypes \
"utop>=2.6.0" \
"melange>=3.0.0"
"melange"
# Dependencies recommended for developing dune locally,
# but not wanted in CI
DEV_DEPS := \
Expand Down Expand Up @@ -74,14 +74,22 @@ install-ocamlformat:
dev-depext:
opam depext -y $(TEST_DEPS)

.PHONY: melange
melange:
opam pin add -n melange.dev https://github.com/melange-re/melange.git#v4-414-dev

.PHONY: dev-deps
dev-deps:
dev-deps: melange
opam install -y $(TEST_DEPS)

.PHONY: coverage-deps
coverage-deps:
opam install -y bisect_ppx

.PHONY: dev-deps-sans-melange
dev-deps-sans-melange:
opam install -y $(TEST_DEPS)

.PHONY: dev-switch
dev-switch:
opam update
Expand Down Expand Up @@ -109,6 +117,9 @@ test-melange: $(BIN)
test-all: $(BIN)
$(BIN) build @runtest @runtest-js @runtest-coq @runtest-melange

test-all-sans-melange: $(BIN)
$(BIN) build @runtest @runtest-js @runtest-coq

test-coverage: $(BIN)
- $(BIN) build --instrument-with bisect_ppx --force @runtest
bisect-ppx-report send-to Coveralls
Expand Down
10 changes: 8 additions & 2 deletions ci/build-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,16 @@ windows_*)
opamrun pin remove ppx_expect --no-action
opamrun pin remove time_now --no-action

opamrun exec -- make dev-deps
# This should have been:
# opam exec -- make dev-deps
# but melange requires ocaml 4.14 (DKML hasn't been updated as of 2022-11)
opamrun exec -- make dev-deps-sans-melange

echo ======== Run test suite on Unix
opamrun exec -- make test
# This should have been:
# opam exec -- make test
# but melange requires ocaml 4.14 (DKML hasn't been updated as of 2022-11)
opamrun exec -- make test-all-sans-melange
esac

echo ======== Build configurator
Expand Down
3 changes: 3 additions & 0 deletions doc/changes/10051.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- melange: fix inconsistency in virtual library implementation. Concrete
modules within a virtual library can now refer to its virtual modules too
(#10051, fixes #7104, @anmonteiro)
14 changes: 7 additions & 7 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
inputs.flake-utils.follows = "flake-utils";
};
melange = {
# When moving the compiler tests to OCaml 5.1, change to v3-51
url = "github:melange-re/melange/v3-414";
# When moving the compiler tests to OCaml 5.1, change to v4-51-dev
url = "github:melange-re/melange/v4-414-dev";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
Expand Down
27 changes: 21 additions & 6 deletions src/dune_rules/melange/melange_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -456,12 +456,27 @@ let setup_js_rules_libraries
let* vlib = Resolve.Memo.read_memo vlib in
let* includes =
let+ requires_link =
Lib.Compile.for_lib
~allow_overlaps:mel.allow_overlapping_dependencies
(Scope.libs scope)
vlib
|> Lib.Compile.requires_link
|> Memo.Lazy.force
let+ requires_link =
Lib.Compile.for_lib
~allow_overlaps:mel.allow_overlapping_dependencies
(Scope.libs scope)
vlib
|> Lib.Compile.requires_link
|> Memo.Lazy.force
in
let open Resolve.O in
let+ requires_link = requires_link in
(* Whenever a `concrete_lib` implementation contains a field
`(implements virt_lib)`, we also set up the JS targets for the
modules defined in `virt_lib`.

In the cases where `virt_lib` (concrete) modules depend on any
virtual modules (i.e. programming against the interface), we
need to make sure that the JS rules that dune emits for
`virt_lib` depend on `concrete_lib`, such that Melange can find
the correct `.cmj` file, which is needed to emit the correct
path in `import` / `require`. *)
lib :: requires_link
Copy link
Collaborator Author

@anmonteiro anmonteiro Feb 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the callout here is:

  • the JS targets of the virtual lib depend on the library artifacts (e.g. .cm{i,j,t}) of the selected (concrete) implementation

This is analogous to adding the correct .cmx to the link path in native compilation.

in
cmj_includes ~requires_link ~scope
in
Expand Down
4 changes: 2 additions & 2 deletions test/blackbox-tests/test-cases/melange/private-lib-dep.t
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ Melange public library depends on private library
// Generated by Melange
'use strict';

var Priv = require("priv/priv.js");
let Priv = require("priv/priv.js");

var x = "public lib uses " + Priv.x;
const x = "public lib uses " + Priv.x;

exports.x = x;
/* No side effect */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
(target output)
(alias mel)
(modules mel)
(emit_stdlib false)
(libraries vlib impl_melange))
Original file line number Diff line number Diff line change
@@ -1 +1 @@
print_endline Virt.t
let () = print_endline Vlib_impl.hello
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ The native build passes
ocamlopt ml.exe
Hello from ml

Melange can't produce a `.cmj` solely from a virtual module `.cmi`, because it
needs to consult the `.cmj` files of dependencies to know where the require
call should be emitted
Any module requiring a virtual module (including modules within the virtual
library itself) needs to consult the `.cmj` file for the concrete
implementation being seleced to know where to `import` from in the generated
JS. The following build works because Dune tracks concrete implementation
`.cmj` files as dependencies of the JS rules.

$ dune build @mel --display=short 2>&1 | grep -v 'node_modules/melange'
melc vlib/.vlib.objs/melange/virt.{cmi,cmti}
ocamldep impl_melange/.impl_melange.objs/virt.impl.d
melc vlib/.vlib.objs/melange/vlib_impl.{cmi,cmj,cmt} (exit 2)
File "vlib/vlib_impl.ml", line 1:
Error: Virt not found, it means either the module does not exist or it is a namespace
melc vlib/.vlib.objs/melange/vlib_impl.{cmi,cmj,cmt}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the description in line 22 needs to be updated.

melc vlib/.vlib.objs/melange/shared.{cmi,cmj,cmt}
melc impl_melange/.impl_melange.objs/melange/virt.{cmj,cmt}
melc .output.mobjs/melange/melange__Mel.{cmi,cmj,cmt}
melc output/impl_melange/virt.js
melc output/vlib/shared.js
melc output/vlib/vlib_impl.js
melc output/mel.js

$ output=_build/default/output/mel.js
$ test -f "$output" && node "$output"
[1]
Hello from melange

Loading