This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
|
|
@ -0,0 +1,3 @@
|
|||
(rule
|
||||
(alias default)
|
||||
(action (run ./exe/test.exe)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 3.7)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(executable
|
||||
(name test)
|
||||
(libraries foolib))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
let () =
|
||||
Foolib.Foo.Bar.run ();
|
||||
Foolib.Foo.A.B.run ()
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(include_subdirs qualified)
|
||||
|
||||
(library (name foolib))
|
||||
|
|
@ -0,0 +1 @@
|
|||
let run () = print_endline "hello from nested module B"
|
||||
|
|
@ -0,0 +1 @@
|
|||
let run () = print_endline "hello from nested module bar"
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Basic test showcasing the feature. Every directory creates a new level of aliasing.
|
||||
$ dune build
|
||||
hello from nested module bar
|
||||
hello from nested module B
|
||||
|
||||
$ find _build -iname "*.ml-gen" | sort | while read file; do echo "contents of $file"; cat $file; echo "--------"; done;
|
||||
contents of _build/default/lib/foolib.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Foo *)
|
||||
module Foo = Foolib__Foo
|
||||
--------
|
||||
contents of _build/default/lib/foolib__Foo.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Foo.A *)
|
||||
module A = Foolib__Foo__A
|
||||
|
||||
(** @canonical Foolib.Foo.Bar *)
|
||||
module Bar = Foolib__Foo__Bar
|
||||
--------
|
||||
contents of _build/default/lib/foolib__Foo__A.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Foo.A.B *)
|
||||
module B = Foolib__Foo__A__B
|
||||
--------
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (executable
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ mkdir -p bar/baz/ baz/
|
||||
$ touch bar/baz/baz.ml baz/bar.ml
|
||||
$ cat >foo.ml <<EOF
|
||||
> module X = Baz.Bar
|
||||
> module Y = Bar.Baz
|
||||
> EOF
|
||||
|
||||
$ dune exec ./foo.exe
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
When (include_subdirs qualified) is enabled, we should forbid the same module
|
||||
to be defined by both a normal compilation unit and a directory of modules
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (executable
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ cat >foo.ml <<EOF
|
||||
> module X = Mod
|
||||
> EOF
|
||||
$ touch mod.ml
|
||||
$ mkdir mod
|
||||
$ touch mod/baz.ml
|
||||
|
||||
$ dune build foo.exe
|
||||
File "dune", line 1, characters 0-0:
|
||||
Error: The following module and module group cannot co-exist in the same
|
||||
executable or library because they correspond to the same module path
|
||||
- module mod.ml
|
||||
- module group mod/
|
||||
[1]
|
||||
|
||||
Another type of overlap:
|
||||
|
||||
$ rm mod/baz.ml
|
||||
$ touch mod/mod.ml
|
||||
|
||||
$ dune build foo.exe
|
||||
File "dune", line 1, characters 0-0:
|
||||
Error: The following module and module group cannot co-exist in the same
|
||||
executable or library because they correspond to the same module path
|
||||
- module mod.ml
|
||||
- module group mod/
|
||||
[1]
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
It should be possible to install sources with the same file name when
|
||||
(include_subirs qualified) is used
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> (package
|
||||
> (name foo))
|
||||
> EOF
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (public_name foo))
|
||||
> EOF
|
||||
|
||||
First we test the case without any sources. To make sure we can at least
|
||||
install empty libraries.
|
||||
|
||||
$ dune build foo.install
|
||||
|
||||
Now we add some source with duplicate base names and test again:
|
||||
|
||||
$ mkdir bar
|
||||
$ touch baz.ml bar/baz.ml
|
||||
$ dune build foo.install
|
||||
$ cat _build/default/foo.install | grep .ml
|
||||
"_build/install/default/lib/foo/bar/bar.ml" {"bar/bar.ml"}
|
||||
"_build/install/default/lib/foo/bar/baz.ml" {"bar/baz.ml"}
|
||||
"_build/install/default/lib/foo/baz.ml"
|
||||
"_build/install/default/lib/foo/foo.ml"
|
||||
|
||||
$ cat _build/install/default/lib/foo/dune-package | grep ".ml"
|
||||
bar/bar.ml
|
||||
bar/baz.ml
|
||||
baz.ml
|
||||
foo.ml
|
||||
(source (path Foo) (impl (path foo.ml-gen))))
|
||||
(source (path Bar Bar) (impl (path foo__Bar.ml-gen))))
|
||||
(source (path Bar Baz) (impl (path bar/baz.ml))))))
|
||||
(source (path Baz) (impl (path baz.ml))))))
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
We shouldn't allow foo/y/$x.ml to depend on foo/foo.ml
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat > dune << EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ mkdir -p x/y
|
||||
$ touch x/x.ml
|
||||
$ cat >x/y/z.ml <<EOF
|
||||
> let () = X.f
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
Error: Module Z in directory _build/default depends on X.
|
||||
This doesn't make sense to me.
|
||||
|
||||
X 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.
|
||||
-> required by _build/default/.foo.objs/foo__X__Y__Z.impl.all-deps
|
||||
-> required by _build/default/.foo.objs/byte/foo__X__Y__Z.cmo
|
||||
-> required by _build/default/foo.cma
|
||||
-> required by alias all
|
||||
-> required by alias default
|
||||
[1]
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
We shouldn't allow foo/$x.ml to depend on foo/foo.ml
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat > dune << EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ mkdir baz
|
||||
$ touch baz/baz.ml
|
||||
$ cat >baz/bar.ml <<EOF
|
||||
> let () = Baz.f
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
Error: Module Bar in directory _build/default depends on Baz.
|
||||
This doesn't make sense to me.
|
||||
|
||||
Baz 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.
|
||||
-> required by _build/default/.foo.objs/foo__Baz__Bar.impl.all-deps
|
||||
-> required by _build/default/.foo.objs/byte/foo__Baz__Bar.cmo
|
||||
-> required by _build/default/foo.cma
|
||||
-> required by alias all
|
||||
-> required by alias default
|
||||
[1]
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
We should forbid lib interfaces modules from depending on themselves:
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat > dune << EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ cat > foo.ml <<EOF
|
||||
> let () = Foo.f ()
|
||||
> EOF
|
||||
|
||||
$ touch bar.ml
|
||||
|
||||
$ dune build @check
|
||||
File "foo.ml", line 1, characters 9-14:
|
||||
1 | let () = Foo.f ()
|
||||
^^^^^
|
||||
Error: Unbound module Foo
|
||||
[1]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(rule
|
||||
(alias default)
|
||||
(action (run ./exe/test.exe)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 3.7)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(executable
|
||||
(name test)
|
||||
(libraries foolib))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
let () =
|
||||
Foolib.Foo.Bar.run ();
|
||||
Foolib.Foo.A.B.run ()
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(include_subdirs qualified)
|
||||
|
||||
(library
|
||||
(name foolib)
|
||||
(modules :standard \ excluded))
|
||||
|
|
@ -0,0 +1 @@
|
|||
let run () = print_endline "hello from nested module B"
|
||||
|
|
@ -0,0 +1 @@
|
|||
let run () = print_endline "hello from nested module bar"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
Demonstrate building a `include_subdirs qualified` project with `(modules
|
||||
:standard \ exclusion)`
|
||||
|
||||
$ dune build
|
||||
hello from nested module bar
|
||||
hello from nested module B
|
||||
|
||||
$ find _build -iname "*.ml-gen" | sort | while read file; do echo "contents of $file"; cat $file; echo "--------"; done;
|
||||
contents of _build/default/lib/foolib.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Foo *)
|
||||
module Foo = Foolib__Foo
|
||||
--------
|
||||
contents of _build/default/lib/foolib__Foo.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Foo.A *)
|
||||
module A = Foolib__Foo__A
|
||||
|
||||
(** @canonical Foolib.Foo.Bar *)
|
||||
module Bar = Foolib__Foo__Bar
|
||||
--------
|
||||
contents of _build/default/lib/foolib__Foo__A.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Foo.A.B *)
|
||||
module B = Foolib__Foo__A__B
|
||||
--------
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(rule
|
||||
(alias default)
|
||||
(action (run ./exe/test.exe)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 3.7)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(executable
|
||||
(libraries foolib)
|
||||
(name test))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
let () =
|
||||
Foolib.Bar.Fake.run ();
|
||||
Foolib.Bar.Baz.run ()
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module Fake = struct
|
||||
let run () =
|
||||
print_endline "defined in lib interface file"
|
||||
end
|
||||
module Baz = Baz
|
||||
|
|
@ -0,0 +1 @@
|
|||
let run () = print_endline "hello from baz"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(include_subdirs qualified)
|
||||
|
||||
(library
|
||||
(name foolib))
|
||||
|
|
@ -0,0 +1 @@
|
|||
module Bar = Bar
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
We are also allowed to write lib interface files at each level.
|
||||
$ dune build
|
||||
defined in lib interface file
|
||||
hello from baz
|
||||
|
||||
$ find _build -iname "*.cmi" | sort
|
||||
_build/default/exe/.test.eobjs/byte/dune__exe__Test.cmi
|
||||
_build/default/lib/.foolib.objs/byte/foolib.cmi
|
||||
_build/default/lib/.foolib.objs/byte/foolib__.cmi
|
||||
_build/default/lib/.foolib.objs/byte/foolib__Bar.cmi
|
||||
_build/default/lib/.foolib.objs/byte/foolib__Bar__.cmi
|
||||
_build/default/lib/.foolib.objs/byte/foolib__Bar__Baz.cmi
|
||||
_build/default/lib/.foolib.objs/byte/foolib__Private.cmi
|
||||
|
||||
$ find _build -iname "*.ml-gen" | sort | while read file; do echo "contents of $file"; cat $file; echo "--------"; done;
|
||||
contents of _build/default/lib/foolib__.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Bar *)
|
||||
module Bar = Foolib__Bar
|
||||
|
||||
(** @canonical Foolib.Private *)
|
||||
module Private = Foolib__Private
|
||||
|
||||
module Foolib__ = struct end
|
||||
[@@deprecated "this module is shadowed"]
|
||||
--------
|
||||
contents of _build/default/lib/foolib__Bar__.ml-gen
|
||||
(* generated by dune *)
|
||||
|
||||
(** @canonical Foolib.Bar.Baz *)
|
||||
module Baz = Foolib__Bar__Baz
|
||||
|
||||
module Foolib__Bar__ = struct end
|
||||
[@@deprecated "this module is shadowed"]
|
||||
--------
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 3.7)
|
||||
|
|
@ -0,0 +1 @@
|
|||
let run = print_endline
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(include_subdirs qualified)
|
||||
|
||||
(library
|
||||
(name impl)
|
||||
(implements vlib))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
We can nested modules virtual
|
||||
$ dune build @all
|
||||
File "vlib/dune", line 5, characters 18-26:
|
||||
5 | (virtual_modules bar/virt))
|
||||
^^^^^^^^
|
||||
Error: Module Bar/virt doesn't exist.
|
||||
[1]
|
||||
|
|
@ -0,0 +1 @@
|
|||
val run : string -> unit
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(include_subdirs qualified)
|
||||
|
||||
(library
|
||||
(name vlib)
|
||||
(virtual_modules bar/virt))
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
We should forbid lib interfaces modules from depending on themselves:
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat > dune << EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ cat > foo.ml <<EOF
|
||||
> let () = Foo.f ()
|
||||
> EOF
|
||||
|
||||
$ touch bar.ml
|
||||
|
||||
$ dune build @check
|
||||
File "foo.ml", line 1, characters 9-14:
|
||||
1 | let () = Foo.f ()
|
||||
^^^^^
|
||||
Error: Unbound module Foo
|
||||
[1]
|
||||
|
||||
We also forbid submodules from depending on their interface modules:
|
||||
|
||||
$ rm foo.ml bar.ml
|
||||
$ mkdir baz
|
||||
$ touch baz/baz.ml
|
||||
$ cat >baz/bar.ml <<EOF
|
||||
> let () = Baz.f
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
Error: Module Bar in directory _build/default depends on Baz.
|
||||
This doesn't make sense to me.
|
||||
|
||||
Baz 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.
|
||||
-> required by _build/default/.foo.objs/foo__Baz__Bar.impl.all-deps
|
||||
-> required by _build/default/.foo.objs/byte/foo__Baz__Bar.cmo
|
||||
-> required by _build/default/foo.cma
|
||||
-> required by alias all
|
||||
-> required by alias default
|
||||
[1]
|
||||
|
||||
Or their parent interface modules:
|
||||
|
||||
$ rm -rf baz
|
||||
$ mkdir -p baz/foo/
|
||||
$ cat >baz/foo/z.ml <<EOF
|
||||
> let () = Baz.f
|
||||
> EOF
|
||||
$ dune build
|
||||
Error: Module Z in directory _build/default depends on Baz.
|
||||
This doesn't make sense to me.
|
||||
|
||||
Baz 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.
|
||||
-> required by _build/default/.foo.objs/foo__Baz__Foo__Z.impl.all-deps
|
||||
-> required by _build/default/.foo.objs/byte/foo__Baz__Foo__Z.cmo
|
||||
-> required by _build/default/foo.cma
|
||||
-> required by alias all
|
||||
-> required by alias default
|
||||
[1]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
Preprocessing should work when there's modules with the same name
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foo)
|
||||
> (preprocess (action (system "cat %{input-file}"))))
|
||||
> EOF
|
||||
|
||||
$ mkdir bar/
|
||||
$ touch baz.ml bar/baz.ml
|
||||
|
||||
$ dune build @check
|
||||
|
|
@ -0,0 +1 @@
|
|||
let x = 42
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(include_subdirs qualified)
|
||||
|
||||
(library
|
||||
(name foolib)
|
||||
(preprocess
|
||||
(per_module
|
||||
((action
|
||||
(run cat %{input-file})) bar/ppme))))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 3.7)
|
||||
|
|
@ -0,0 +1 @@
|
|||
module Bar = Bar.Ppme
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
We can set preprocessing options for nested modules
|
||||
$ dune build @all
|
||||
File "dune", line 8, characters 30-38:
|
||||
8 | (run cat %{input-file})) bar/ppme))))
|
||||
^^^^^^^^
|
||||
Error: "bar/ppme" is an invalid module name.
|
||||
Module names must be non-empty, start with a letter, and composed only of the
|
||||
following characters: 'A'..'Z', 'a'..'z', '_', ''' or '0'..'9'.
|
||||
Hint: barppme would be a correct module name
|
||||
[1]
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Marking modules as private
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foolib)
|
||||
> (private_modules baz/foo))
|
||||
> EOF
|
||||
|
||||
$ mkdir baz
|
||||
$ touch baz/foo.ml
|
||||
|
||||
$ dune build
|
||||
File "dune", line 4, characters 18-25:
|
||||
4 | (private_modules baz/foo))
|
||||
^^^^^^^
|
||||
Error: Module Baz/foo doesn't exist.
|
||||
[1]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
Libraries designed as the "stdlib" may not use (include_subdirs qualified)
|
||||
|
||||
Although it's just an artificial limitation and when we can lift it if the need
|
||||
arises to.
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> (using experimental_building_ocaml_compiler_with_dune 0.1)
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (name foo)
|
||||
> (stdlib))
|
||||
> EOF
|
||||
|
||||
$ dune build @check
|
||||
File "dune", line 1, characters 0-27:
|
||||
1 | (include_subdirs qualified)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Error: a library with (stdlib ...) may not use (include_subdirs qualified)
|
||||
[1]
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Unwrapped libraries and (include_subdirs unqualified)
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
|
||||
$ mkdir lib/ && cd lib
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (include_subdirs qualified)
|
||||
> (library
|
||||
> (wrapped false)
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
$ mkdir x
|
||||
$ cat >x/x.ml <<EOF
|
||||
> let run () = Foo.run ()
|
||||
> EOF
|
||||
$ cat >x/foo.ml <<EOF
|
||||
> let run () = print_endline "Foo"
|
||||
> EOF
|
||||
|
||||
$ mkdir y
|
||||
$ cat >y/z.ml <<EOF
|
||||
> let run () = print_endline "Z"
|
||||
> EOF
|
||||
|
||||
$ cd ..
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (executable
|
||||
> (libraries foo)
|
||||
> (name main))
|
||||
> EOF
|
||||
|
||||
$ cat >main.ml <<EOF
|
||||
> let () = X.run (); Y.Z.run ()
|
||||
> EOF
|
||||
|
||||
$ dune exec ./main.exe
|
||||
Foo
|
||||
Z
|
||||
Loading…
Add table
Add a link
Reference in a new issue