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

Do not run ocamldep on single module buildables #3847

Merged
merged 5 commits into from
Oct 9, 2020
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
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ Unreleased
native, dynlink) are disabled. Previously, dune would generate all archives
for regardless of settings. (#3829, @rgrinberg)

- Do no run ocamldep to for single module executables & libraries. The
dependency graph for such artifacts is trivial (#3847, @rgrinberg)

2.7.1 (2/09/2020)
-----------------

Expand Down
14 changes: 10 additions & 4 deletions src/dune_rules/dep_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,14 @@ let rec deps_of cctx ~ml_kind (m : Modules.Sourced_module.t) =
| Intf -> deps_of cctx ~ml_kind (Imported_from_vlib m)
| Impl -> deps_of cctx ~ml_kind (Normal m) )

let for_module cctx module_ =
Ml_kind.Dict.of_func (fun ~ml_kind -> deps_of cctx ~ml_kind (Normal module_))

let rules cctx ~modules =
let dir = Compilation_context.dir cctx in
Ml_kind.Dict.of_func (fun ~ml_kind ->
let per_module = Modules.obj_map modules ~f:(deps_of cctx ~ml_kind) in
Dep_graph.make ~dir ~per_module)
match Modules.as_singleton modules with
| Some m -> Dep_graph.Ml_kind.dummy m
| None ->
let dir = Compilation_context.dir cctx in
Ml_kind.Dict.of_func (fun ~ml_kind ->
let per_module = Modules.obj_map modules ~f:(deps_of cctx ~ml_kind) in
Dep_graph.make ~dir ~per_module)
3 changes: 3 additions & 0 deletions src/dune_rules/dep_rules.mli
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
(** Get dependencies for a set of modules using either ocamldep or ocamlobjinfo *)
open! Dune_engine

val for_module :
Compilation_context.t -> Module.t -> Module.t list Build.t Ml_kind.Dict.t

val rules :
Compilation_context.t -> modules:Modules.t -> Dep_graph.t Ml_kind.Dict.t
20 changes: 7 additions & 13 deletions src/dune_rules/menhir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -193,21 +193,15 @@ module Run (P : PARAMS) : sig end = struct
in
Module.of_source ~visibility:Public ~kind:Impl source
in
let modules =
(* The following incantation allows the mock [.ml] file to be preprocessed
by the user-specified [ppx] rewriters. *)
let mock_module =
Preprocessing.pp_module_as
(Compilation_context.preprocessing cctx)
name mock_module ~lint:false
in
Modules.singleton_exe mock_module
let mock_module =
Preprocessing.pp_module_as
(Compilation_context.preprocessing cctx)
name mock_module ~lint:false
in
let dep_graphs = Dep_rules.rules cctx ~modules in
let cctx = Compilation_context.without_bin_annot cctx in
Modules.iter_no_vlib modules ~f:(fun m ->
Module_compilation.ocamlc_i ~dep_graphs cctx m
~output:(inferred_mli base));
let deps = Dep_rules.for_module cctx mock_module in
Module_compilation.ocamlc_i ~deps cctx mock_module
~output:(inferred_mli base);
(* 3. A second invocation of Menhir reads the inferred [.mli] file. *)
rule
(menhir
Expand Down
5 changes: 2 additions & 3 deletions src/dune_rules/module_compilation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,17 @@ let build_module ~dep_graphs ?(precompiled_cmi = false) cctx m =
SC.add_rules sctx ~dir
(Jsoo_rules.build_cm cctx ~js_of_ocaml ~src ~target))

let ocamlc_i ?(flags = []) ~dep_graphs cctx (m : Module.t) ~output =
let ocamlc_i ?(flags = []) ~deps cctx (m : Module.t) ~output =
let sctx = CC.super_context cctx in
let obj_dir = CC.obj_dir cctx in
let dir = CC.dir cctx in
let ctx = SC.context sctx in
let src = Option.value_exn (Module.file m ~ml_kind:Impl) in
let dep_graph = Ml_kind.Dict.get dep_graphs Impl in
let sandbox = Compilation_context.sandbox cctx in
let cm_deps =
Build.dyn_paths_unit
(let open Build.O in
let+ deps = Dep_graph.deps_of dep_graph m in
let+ deps = Ml_kind.Dict.get deps Impl in
List.concat_map deps ~f:(fun m ->
[ Path.build (Obj_dir.Module.cm_file_exn obj_dir m ~kind:Cmi) ]))
in
Expand Down
2 changes: 1 addition & 1 deletion src/dune_rules/module_compilation.mli
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ val build_module :

val ocamlc_i :
?flags:string list
-> dep_graphs:Dep_graph.Ml_kind.t
-> deps:Module.t list Build.t Ml_kind.Dict.t
-> Compilation_context.t
-> Module.t
-> output:Path.Build.t
Expand Down
4 changes: 4 additions & 0 deletions src/dune_rules/modules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,10 @@ let is_empty = function
| Unwrapped w -> Module_name.Map.is_empty w
| Wrapped w -> Wrapped.empty w

let as_singleton = function
| Singleton m -> Some m
| _ -> None

let source_dirs =
fold_user_written ~init:Path.Set.empty ~f:(fun m acc ->
Module.sources m
Expand Down
2 changes: 2 additions & 0 deletions src/dune_rules/modules.mli
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ val relocate_alias_module : t -> src_dir:Path.t -> t

val is_empty : t -> bool

val as_singleton : t -> Module.t option

val source_dirs : t -> Path.Set.t
1 change: 0 additions & 1 deletion test/blackbox-tests/test-cases/all-alias.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

$ dune build --display short --root private-lib @all
Entering directory 'private-lib'
ocamldep .bar.objs/bar.ml.d
ocamlc .bar.objs/byte/bar.{cmi,cmo,cmt}
ocamlopt .bar.objs/native/bar.{cmx,o}
ocamlc bar.cma
Expand Down
11 changes: 4 additions & 7 deletions test/blackbox-tests/test-cases/byte-code-only.t/run.t
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
$ env ORIG_PATH="$PATH" PATH="$PWD/ocaml-bin:$PATH" dune build @all --display short
ocamldep bin/.toto.eobjs/toto.ml.d
ocamldep src/.foo.objs/foo.ml.d
ocamlc build-info/.build_info.objs/byte/build_info.{cmi,cmo,cmt}
ocamldep build-info/.build_info.objs/build_info_data.mli.d
ocamldep bin-with-build-info/.print_version.eobjs/print_version.ml.d
ocamlc bin/.toto.eobjs/byte/dune__exe__Toto.{cmi,cmo,cmt}
ocamlc src/.foo.objs/byte/foo.{cmi,cmo,cmt}
ocamlc build-info/build_info.cma
ocamlc build-info/.build_info.objs/byte/build_info__Build_info_data.{cmi,cmti}
ocamlc build-info/.build_info.objs/byte/build_info.{cmi,cmo,cmt}
ocamldep build-info/.build_info.objs/build_info_data.mli.d
ocamlc bin/toto.exe
ocamlc bin/toto.bc
ocamlc src/foo.cma
ocamlc build-info/build_info.cma
ocamlc build-info/.build_info.objs/byte/build_info__Build_info_data.{cmi,cmti}
ocamlc bin-with-build-info/.print_version.eobjs/byte/build_info__Build_info_data.{cmo,cmt}
ocamlc bin-with-build-info/.print_version.eobjs/byte/dune__exe__Print_version.{cmi,cmo,cmt}
ocamlc bin-with-build-info/print_version.bc
Expand Down
6 changes: 2 additions & 4 deletions test/blackbox-tests/test-cases/cross-compilation.t/run.t
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
$ env OCAMLFIND_CONF=$PWD/etc/findlib.conf dune build --display short -x foo file @install --promote-install-files
ocamldep lib/.p.objs/p.ml.d [default.foo]
ocamldep bin/.blah.eobjs/blah.ml.d [default.foo]
ocamldep lib/.p.objs/p.ml.d
ocamldep bin/.blah.eobjs/blah.ml.d
ocamlc lib/.p.objs/byte/p.{cmi,cmo,cmt} [default.foo]
ocamldep bin/.blah.eobjs/blah.ml.d [default.foo]
ocamlc lib/.p.objs/byte/p.{cmi,cmo,cmt}
ocamldep bin/.blah.eobjs/blah.ml.d
ocamlopt lib/.p.objs/native/p.{cmx,o} [default.foo]
ocamlc lib/p.cma [default.foo]
ocamlopt lib/.p.objs/native/p.{cmx,o}
Expand Down
1 change: 0 additions & 1 deletion test/blackbox-tests/test-cases/dune-init.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ Can init and build a new library project

$ dune runtest --root test_lib_proj --display short
Entering directory 'test_lib_proj'
ocamldep test/.test_lib_proj.eobjs/test_lib_proj.ml.d
ocamlc test/.test_lib_proj.eobjs/byte/dune__exe__Test_lib_proj.{cmi,cmo,cmt}
ocamlopt test/.test_lib_proj.eobjs/native/dune__exe__Test_lib_proj.{cmx,o}
ocamlopt test/test_lib_proj.exe
Expand Down
3 changes: 0 additions & 3 deletions test/blackbox-tests/test-cases/dune-ppx-driver-system.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ Test that going through the -ppx option of the compiler works

$ dune build --root driver-tests test_ppx_staged.cma
Entering directory 'driver-tests'
ocamldep .test_ppx_staged.objs/test_ppx_staged.ml.d
tool name: ocamldep
args:--as-ppx -arg1 -arg2 -arg3=Oreo -foo bar Snickerdoodle --cookie france="Petit Beurre" --cookie italy="Biscotti" --cookie library-name="test_ppx_staged"
ocamlc .test_ppx_staged.objs/byte/test_ppx_staged.{cmi,cmo,cmt}
tool name: ocamlc
args:--as-ppx -arg1 -arg2 -arg3=Oreo -foo bar Snickerdoodle --cookie france="Petit Beurre" --cookie italy="Biscotti" --cookie library-name="test_ppx_staged"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
$ dune build @install --display short
ocamldep a1/.a.objs/a.ml.d
ocamldep a2/.a.objs/a.ml.d
ocamlc a1/.a.objs/byte/a.{cmi,cmo,cmt}
ocamlc a2/.a.objs/byte/a.{cmi,cmo,cmt}
ocamlopt a1/.a.objs/native/a.{cmx,o}
Expand Down
1 change: 0 additions & 1 deletion test/blackbox-tests/test-cases/intf-only.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Successes:
ocamldep .foo.objs/foo.ml.d
ocamlc .foo.objs/byte/foo__.{cmi,cmo,cmt}
ocamldep .foo.objs/intf.mli.d
ocamldep test/.bar.objs/bar.ml.d
ocamlopt .foo.objs/native/foo__.{cmx,o}
ocamlc .foo.objs/byte/foo__Intf.{cmi,cmti}
ocamlc .foo.objs/byte/foo.{cmi,cmo,cmt}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ Anonymous projects have explicit_js_mode enabled
$ dune build --display short @all
Info: Creating file dune-project with this contents:
| (lang dune 2.8)
ocamldep .foo.objs/foo.ml.d
ocamlc .foo.objs/byte/foo.{cmi,cmo,cmt}
ocamlopt .foo.objs/native/foo.{cmx,o}
ocamlc foo.cma
Expand Down
2 changes: 0 additions & 2 deletions test/blackbox-tests/test-cases/menhir/general.t/dune-project

This file was deleted.

14 changes: 14 additions & 0 deletions test/blackbox-tests/test-cases/menhir/general.t/run.t
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
Build and run a source file that requires a menhir parser.

$ cat >dune-project <<EOF
> (lang dune 1.0)
> (using menhir 1.0)
> EOF

$ dune build ./src/test.exe --debug-dependency-path
$ ls _build/default/src/test.exe
_build/default/src/test.exe

$ cat >dune-project <<EOF
> (lang dune 2.0)
> (using menhir 2.0)
> EOF

$ dune build ./src/test.exe --debug-dependency-path
$ ls _build/default/src/test.exe
_build/default/src/test.exe
17 changes: 17 additions & 0 deletions test/blackbox-tests/test-cases/ocaml-dep-single-exe.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
When creating single module libraries & executables, running ocamldep isn't
necessary.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> EOF
$ cat >dune <<EOF
> (executable (name foo))
> EOF
$ cat >foo.ml <<EOF
> print_endline "hello world"
> EOF
$ dune exec ./foo.exe
hello world

We check to see if ocamldep artifacts have been created:
$ find _build/default -name "*.all-deps" -or -name "*.d"
74 changes: 74 additions & 0 deletions test/blackbox-tests/test-cases/ocamldep-error-check.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Dune uses ocamldep to prevent a module from depending on itself.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (wrapped_executables false)
> EOF

$ mkdir lib
$ cat >lib/dune <<EOF
> (library
> (name foo))
> EOF
$ cat >lib/bar.ml <<EOF
> Foo.bar
> EOF
$ dune build @all
Error: Module Bar in directory _build/default/lib depends on Foo.
This doesn't make sense to me.

Foo is the main module of the library and is the only module exposed outside
of the library. Consequently, it should be the one depending on all the other
modules in the library.
[1]

$ rm lib/bar.ml

This check doesn't apply to single module libraries:

$ cat >lib/foo.ml <<EOF
> let x = Foo.x
> EOF
$ dune build @all
File "lib/foo.ml", line 1, characters 8-13:
1 | let x = Foo.x
^^^^^
Error: Unbound module Foo
[1]
$ rm lib/foo.ml

However, we'll demonstrate that this check isn't applicable to executables:

$ cat >lib/bar.ml <<EOF
> let run () = print_endline "Hello World"
> EOF

$ mkdir exe
$ cat >exe/dune <<EOF
> (executable
> (name foo)
> (libraries foo))
> EOF
$ cat >exe/foo.ml <<EOF
> Foo.Bar.run ();;
> EOF

Although we get slightly different behavior if warpping is on or off:

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (wrapped_executables false)
> EOF
$ dune exec ./exe/foo.exe
File "exe/foo.ml", line 1, characters 0-11:
1 | Foo.Bar.run ();;
^^^^^^^^^^^
Error: Unbound module Foo
[1]

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (wrapped_executables true)
> EOF
$ dune exec ./exe/foo.exe
Hello World
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ This test checks that there is no clash when two private libraries have the same

$ dune build --display short @doc-private
odoc _doc/_html/highlight.pack.js,_doc/_html/odoc.css
ocamldep a/.test.objs/test.ml.d
ocamldep b/.test.objs/test.ml.d
ocamlc a/.test.objs/byte/test.{cmi,cmo,cmt}
ocamlc b/.test.objs/byte/test.{cmi,cmo,cmt}
odoc a/.test.objs/byte/test.odoc
Expand Down
22 changes: 8 additions & 14 deletions test/blackbox-tests/test-cases/plugin-mode.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -80,33 +80,27 @@ Testsuite for (mode plugin).
> EOF

$ dune build --display short @all 2>&1 | dune_cmd sanitize
ocamldep $ext_lib.eobjs/a.ml.d
ocamldep foo/.foo.objs/foo.ml.d
ocamldep .b.eobjs/b.ml.d
ocamldep foo/.bar.objs/bar.ml.d
ocamldep main/.main.eobjs/main.ml.d
ocamldep main2/.main.eobjs/main.ml.d
ocamlc foo/.foo.objs/byte/foo.{cmi,cmo,cmt}
ocamlc main2/.main.eobjs/byte/dune__exe__Main.{cmi,cmo,cmt}
ocamlopt foo/.foo.objs/native/foo.{cmx,o}
ocamlc foo/.bar.objs/byte/bar.{cmi,cmo,cmt}
ocamlc $ext_lib.eobjs/byte/dune__exe__A.{cmi,cmo,cmt}
ocamlc foo/.bar.objs/byte/bar.{cmi,cmo,cmt}
ocamlopt foo/.foo.objs/native/foo.{cmx,o}
ocamlc foo/foo.cma
ocamlopt main2/.main.eobjs/native/dune__exe__Main.{cmx,o}
ocamlopt foo/foo.{a,cmxa}
ocamlopt $ext_lib.eobjs/native/dune__exe__A.{cmx,o}
ocamlopt foo/.bar.objs/native/bar.{cmx,o}
ocamlc foo/bar.cma
ocamlopt $ext_lib.eobjs/native/dune__exe__A.{cmx,o}
ocamlopt foo/foo.{a,cmxa}
ocamlopt main2/main.exe
ocamlopt a.cmxs
ocamlopt foo/bar.{a,cmxa}
ocamlopt a.exe
ocamlc .b.eobjs/byte/dune__exe__B.{cmi,cmo,cmt}
ocamlopt foo/foo.cmxs
ocamlc main/.main.eobjs/byte/dune__exe__Main.{cmi,cmo,cmt}
ocamlopt foo/bar.{a,cmxa}
ocamlopt a.cmxs
ocamlopt a.exe
ocamlopt foo/bar.cmxs
ocamlopt .b.eobjs/native/dune__exe__B.{cmx,o}
ocamlopt main/.main.eobjs/native/dune__exe__Main.{cmx,o}
ocamlopt foo/bar.cmxs
ocamlopt b.cmxs
ocamlopt main/main.exe

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ On the other hand, public libraries may have private preprocessors
ocamlopt ppx_internal.{a,cmxa}
ocamlopt .ppx/be26d3600214af2fa78c2c9ef25e9069/ppx.exe
ppx mylib.pp.ml
ocamldep .mylib.objs/mylib.pp.ml.d
ocamlc .mylib.objs/byte/mylib.{cmi,cmo,cmt}
ocamlopt .mylib.objs/native/mylib.{cmx,o}
ocamlc mylib.cma
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ prefixed and unprefixed modules are built.
$ ./sdune clean
$ ./sdune build --display short @t1
ocamldep .a1.objs/a.ml.d
ocamldep .b.eobjs/b.ml.d
ocamldep .c1.objs/c.ml.d
ocamldep .c2.objs/d.ml.d
ocamlc .a1.objs/byte/a1.{cmi,cmo,cmt}
ocamlc .b.eobjs/byte/dune__exe__B.{cmi,cmo,cmt}
ocamlc .c1.objs/byte/c.{cmi,cmo,cmt}
ocamldep .c2.objs/d.ml.d
ocamlc .a1.objs/byte/a1.{cmi,cmo,cmt}
ocamlc .c2.objs/byte/c2.{cmi,cmo,cmt}
ocamlc .a1.objs/byte/a1__A.{cmi,cmo,cmt}
ocamlc .c2.objs/byte/c2__D.{cmi,cmo,cmt}
Expand Down Expand Up @@ -182,7 +180,6 @@ public library defined in a subdirectory.

$ ./sdune clean
$ ./sdune build --display short @t10
ocamldep .c1.objs/c.ml.d
ocamlc .c1.objs/byte/c.{cmi,cmo,cmt}
ocamlc c1.cma

Expand Down
Loading