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

Add support for (include_subdirs qualified) #1084

Closed
ghost opened this issue Aug 1, 2018 · 14 comments · Fixed by #6594 or ocaml/opam-repository#23349
Closed

Add support for (include_subdirs qualified) #1084

ghost opened this issue Aug 1, 2018 · 14 comments · Fixed by #6594 or ocaml/opam-repository#23349
Assignees
Milestone

Comments

@ghost
Copy link

ghost commented Aug 1, 2018

With the following project:

./src:
dune       # containing (include_subdirs qualified)
x.ml

./src/a:
y.ml

./src/a/b:
z.ml

x.ml would see y.ml as A.Y and z.ml as A.B.Z. Then y.ml would see z.ml as B.Z but couldn't see x.ml.

This should allow to organize the modules using the FS layout.

I'm interested in this as it would allow to port Camlp4 to dune, which would simplify it's maintenance, and it's also a nice feature to have. However, I'm not planning to work on this in the near future, so anyone should feel free to assign themselves this feature if they are interested in it.

@rgrinberg rgrinberg self-assigned this Aug 6, 2018
@rgrinberg rgrinberg added this to the 1.2.0 milestone Aug 6, 2018
@rgrinberg rgrinberg removed this from the 1.2.0 milestone Feb 12, 2019
@rgrinberg
Copy link
Member

There's a few complications that have kept this feature on the back burner. I'll just list them here to note that I haven't forgotten about this feature:

  • Our current code relies on passing around a lot of maps keyed by the module name. Naturally, this doesn't quite work anymore since the module names are no longer unique.

  • I'd like to it be possible to define a lib interface module for every subdirectory. Our codebase currently assumes there's only one such module in many places.

@Lupus
Copy link

Lupus commented Mar 5, 2020

Will it still be possible to add some custom rules in dune files within the FS hierarchy that form one dune lib? Or define some aliases? I.e. will dune files within such hierarchy be treated as normal dune files with all features available?

Also will it be possible to customize compiler flags for certain submodules? Like I want to have -open Base, but it won't work with atdgen modules, currently I'm moving them to separate lib so that I can tune the compiler flags there.

May be ability for tuning ppx-es that are used will be nice to have. When using ppx_deriving with protobuf plug-in, sexp derivers stop working, I had to move protobuf types to separate library to just change ppx set used.

@ghost
Copy link
Author

ghost commented Mar 5, 2020

Will it still be possible to add some custom rules in dune files within the FS hierarchy that form one dune lib? Or define some aliases? I.e. will dune files within such hierarchy be treated as normal dune files with all features available?

It will be the same as for (include_subdirs unqualified). You'll be able to do everything except defining libraries or executables.

Also will it be possible to customize compiler flags for certain submodules? Like I want to have -open Base, but it won't work with atdgen modules, currently I'm moving them to separate lib so that I can tune the compiler flags there.

Probably not in the first version. But in the future, why not.

May be ability for tuning ppx-es that are used will be nice to have. When using ppx_deriving with protobuf plug-in, sexp derivers stop working, I had to move protobuf types to separate library to just change ppx set used.

You can already do that: https://dune.readthedocs.io/en/stable/concepts.html#per-module-preprocessing-specification

@rgrinberg
Copy link
Member

rgrinberg commented Mar 5, 2020

Just so I don't forget this later on, here's quick brain dump that's blocking
this issue. The main problem is the layout of the alias module. Consider this
directory structure:

$ ls -R .
  dune
  y.ml
  x/
    foo.ml
    bar.ml
    x.ml
$ cat dune
  (include_subdirs qualified)
  (library (name lib))

In this setup, it's important to note that x/x.ml is a lib interface module
and that y.ml may not access foo.ml and bar.ml. We might consider the
following alias map that works for such a file:

$ cat lib__.ml
module X__ = struct
  module Foo = Lib__X__Foo
  module Bar = Lib__X__Bar
end
module X = Lib__X
module Y = Lib__Y

When compiling {foo,bar}.ml, we use the flags -open Lib__ -open X__.
When compiling y.ml, we use the flags -open Lib__.

This looks great except for one little blemish: now Y can see this ugly X__
name. I can't think of a way to avoid this downside without making the alising a
lot more complicated and using multiple alias files.

@diml, @aalekseyev, perhaps you guys have a suggestion?

@aalekseyev
Copy link
Collaborator

Will X__ also appear in module type of Lib?
My first reaction is that multiple alias modules seems reasonable and having X__ in the module type of Lib is not reasonable.

(we use multiple alias modules when we have multiple libraries right now so I'm not surprised if we need multiple alias modules when we have multiple include_qualified directories (I think about them roughly as libraries))

@aalekseyev
Copy link
Collaborator

aalekseyev commented Mar 6, 2020

Wait, doesn't something like this work?

module Lib__ = struct
  module To_open = struct
    module X = Lib__X
    module Y = Lib__Y
  end
  module X = struct
    module To_open = struct
      module Foo = Lib__X__Foo
      module Bar = Lib__X__Bar
    end
  end
end

When compiling {foo,bar}.ml, we use the flags -open Lib__.To_open -open Lib__.X.To_open.
When compiling y.ml, we use the flags -open Lib__.To_open.

(instead of multiple opens you can put a statement include To_open on top of X.To_open, which I think should also work if you've got the compiler that allows include shadowing)

@aalekseyev

This comment has been minimized.

@rgrinberg
Copy link
Member

By the way, in your original message you probably wanted to say "y.ml may not access foo.ml and bar.ml", I suggest you edit that before others are confused.

Corrected. Thanks.

Wait, doesn't something like this work?

That seems like it's worth trying, but I'm not confident that these To_open identifiers aren't going to leak when doing type inference, completion in merlin. At least with the __, merlin knows to hide these symbols from the user.

I suppose there's no harm trying this out. Generating the alias module is a fairly small piece of the work anyway.

@aalekseyev
Copy link
Collaborator

[To_open does not contain __]

We could call it O__, or something like that. Thinking again, it seems we don't really need the surrounding modules at all:

module To_open_in_Lib__ = struct
  module X = Lib__X
  module Y = Lib__Y
end
module To_open_in_Lib__X__ = struct
  module Foo = Lib__X__Foo
  module Bar = Lib__X__Bar
end

Or maybe I'm missing something?

@rgrinberg
Copy link
Member

rgrinberg commented Mar 6, 2020 via email

@OndrejPopp
Copy link

OndrejPopp commented Nov 12, 2020

Ok cool... I would like to have this feature too! 👨‍💻
In the meantime I have settled for this,

  • leave include_subdirs as default no, so each sub directory will be compiled into a seperate library, I figured better this than to have the whole FS hierarchy flattened into the root dir.
  • then dune file for the toplevel lib : (library (name lib) (libraries x))
  • dune file for the x subdir : (library (name x))
  • move the x.ml file one level up, containing,
    module Foo = X__Foo
    module Bar = X__Bar
  • drop the lib__.ml file, not needed in this setup, because of the moved x.ml file

now Lib.X.{Foo,Bar} are visible, the only drawback is that X.{Foo, Bar} is visible as well and so on for every subdirectory, library, in the FS hierarchy. But I guess just ignore those until this feature gets available?

Or is there still a better way to achieve this in the meantime?
Thanks ☺️

@OndrejPopp
Copy link

👨‍💻 Ok... I just checked whether this approach still works for next subdirectory levels, if X would have have a subdirectory Z with modules Mx and My. And it does! To add Z to X you need to do,

  • create the subdirectory Z and inside it the M{x,y}.ml files
  • the dune file for Z : (library (name z))
  • add this to the dune file for X : (libraries z)
  • create a Z.ml file inside X and alias the modules of Z, :
    module Mx = Z__Mx
    module My = Z__My
  • add this to the X.ml file inside lib : module Z = X__Z
  • done! Now Lib.X.Z.M{x,y} are visible.

So this approach works, and you can write a script to automate this. The only drawback is again that you have all these sub libraries created, but aside from that it could maybe serve as a basis to implement this feature in dune?

Tx. 😃

@Richard-Degenne
Copy link

Hello!

Can we get an update on the priority of this feature? I understand it was not too pressing back in 2020, how is it looking now?

It's a feature I've been looking forward to for a long time, coming from other languages where namespaces are very predominant.

@rgrinberg
Copy link
Member

I would say there's more than a few issues with higher priority. Therefore the chances that we will work on this feature this year are slim without additional resources.

@rgrinberg rgrinberg linked a pull request Nov 27, 2022 that will close this issue
@rgrinberg rgrinberg linked a pull request Nov 27, 2022 that will close this issue
6 tasks
@rgrinberg rgrinberg added this to the 3.7.0 milestone Nov 28, 2022
emillon added a commit to emillon/opam-repository that referenced this issue Feb 6, 2023
…, dune-rpc, dune-rpc-lwt, dune-private-libs, dune-glob, dune-configurator, dune-build-info, dune-action-plugin and chrome-trace (3.7.0~alpha1)

CHANGES:

- Fix parsing of OCaml errors that contain code excerpts with `...` in them.
  (ocaml/dune#7008, @rgrinberg)

- Pre-emptively clear screen in watch mode (ocaml/dune#6987, fixes ocaml/dune#6884, @rgrinberg)

- Fix cross compilation configuration when a context with targets is itself a
  host of another context (ocaml/dune#6958, fixes ocaml/dune#6843, @rgrinberg)

- Fix parsing of the `<=` operator in *blang* expressions of `dune` files.
  Previously, the operator would be interpreted as `,`. (ocaml/dune#6928, @tatchi)

- Fix `--trace-file` output. Dune now emits a single *complete* event for every
  executed process. Unterminated *async* events are no longer written. (ocaml/dune#6892,
  @rgrinberg)

- Fix preprocessing with `staged_pps` (ocaml/dune#6748, fixes ocaml/dune#6644, @rgrinberg)

- Use colored output with MDX when Dune colors are enabled.
  (ocaml/dune#6462, @MisterDA)

- Make `dune describe workspace` return consistent dependencies for
  executables and for libraries. By default, compile-time dependencies
  towards PPX-rewriters are from now not taken into account (but
  runtime dependencies always are). Compile-time dependencies towards
  PPX-rewriters can be taken into account by providing the
  `--with-pps` flag. (ocaml/dune#6727, fixes ocaml/dune#6486, @esope)

- Print missing newline after `$ dune exec`. (ocaml/dune#6821, fixes ocaml/dune#6700, @rgrinberg,
  @Alizter)

- Fix binary corruption when installing or promoting in parallel (ocaml/dune#6669, fixes
  ocaml/dune#6668, @edwintorok)

- Use colored output with GCC and Clang when compiling C stubs. The
  flag `-fdiagnostics-color=always` is added to the `:standard` set of
  flags. (ocaml/dune#4083, @MisterDA)

- Fix the parsing of decimal and hexadecimal escape literals in `dune`,
  `dune-package`, and other dune s-expression based files (ocaml/dune#6710, @shym)

- Report an error if `dune init ...` would create a "dune" file in a location
  which already contains a "dune" directory (ocaml/dune#6705, @gridbugs)

- Fix the parsing of alerts. They will now show up in diagnostics correctly.
  (ocaml/dune#6678, @rginberg)

- Fix the compilation of modules generated at link time when
  `implicit_transitive_deps` is enabled (ocaml/dune#6642, @rgrinberg)

- Allow `$ dune utop` to load libraries defined in data only directories
  defined using `(subdir ..)` (ocaml/dune#6631, @rgrinberg)

- Format dune files when they are named `dune-file`. This occurs when we enable
  the alternative file names project option. (ocaml/dune#6566, @rgrinberg)

- Move `$ dune ocaml-merlin -dump-config=$dir` to `$ dune ocaml merlin
  dump-config $dir`. (ocaml/dune#6547, @rgrinberg)

- Allow compilation rules to be impacted by `(env ..)` stanzas that modify the
  environment or set binaries. (ocaml/dune#6527, @rgrinberg)

- Coq native mode is now automatically detected by Dune starting with Coq lang
  0.7. `(mode native)` has been deprecated in favour of detection from the
  configuration of Coq. (ocaml/dune#6409, @Alizter)

- Print "Leaving Directory" whenever "Entering Directory" is printed. (ocaml/dune#6149,
  fixes ocaml/dune#138, @cpitclaudel, @rgrinberg)

- Allow `$ dune ocaml dump-dot-merlin` to run in watch mode. Also this command
  shouldn't print "Entering Directory" mesages. (ocaml/dune#6497, @rgrinberg)

- `dune clean` should no longer fail under Windows due to the inability to
  remove the `.lock` file. Also, bring the implementation of the global lock
  under Windows closer to that of Unix. (ocaml/dune#6523, @nojb)

- Remove "Entering Directory" messages for `$ dune install`. (ocaml/dune#6513,
  @rgrinberg)

- Stop passing `-q` flag in `dune coq top`, which allows for `.coqrc` to be
  loaded. (ocaml/dune#6848, fixes ocaml/dune#6847, @Alizter)

- Fix missing dependencies when detecting the kind of C compiler we're using
  (ocaml/dune#6610, fixes ocaml/dune#6415, @emillon)

- Allow `(include_subdirs qualified)` for OCaml projects. (ocaml/dune#6594, fixes ocaml/dune#1084,
  @rgrinberg)

- Accurately determine merlin configuration for all sources selected with
  `copy#` and `copy_files#`. The old heuristic of looking for a module in
  parent directories is removed (ocaml/dune#6594, @rgrinberg)

- Fix inline tests with *js_of_ocaml* and whole program compilation mode
  enabled (ocaml/dune#6645, @hhugo)

- Fix *js_of_ocaml* separate compilation rules when `--enable=effects`
  ,`--enable=use-js-string` or `--toplevel` is used. (ocaml/dune#6714, ocaml/dune#6828, ocaml/dune#6920, @hhugo)

- Fix *js_of_ocaml* separate compilation in presence of linkall (ocaml/dune#6832, ocaml/dune#6916, @hhugo)

- Remove spurious build dir created when running `dune init proj ...` (ocaml/dune#6707,
  fixes ocaml/dune#5429, @gridbugs)

- Allow `--sandbox` to affect `ocamldep` invocations. Previously, they were
  wrongly marked as incompatible (ocaml/dune#6749, @rgrinberg)

- Validate the command line arguments for `$ dune ocaml top-module`. This
  command requires one positional argument (ocaml/dune#6796, fixes ocaml/dune#6793, @rgrinberg)

- Add a `dune cache size` command for displaying the size of the cache (ocaml/dune#6638,
  @Alizter)

- Add 4.14.0 MSVC to CI (ocaml/dune#6917, @jonahbeckford)

- Fix dependency cycle when installing files to the bin section with
  `glob_files` (ocaml/dune#6764, fixes ocaml/dune#6708, @gridbugs)

- Handle "Too many links" errors when using Dune cache on Windows (ocaml/dune#6993, @nojb)
emillon added a commit to emillon/opam-repository that referenced this issue Feb 17, 2023
…, dune-rpc, dune-rpc-lwt, dune-private-libs, dune-glob, dune-configurator, dune-build-info, dune-action-plugin and chrome-trace (3.7.0)

CHANGES:

- Allow running `$ dune exec` in watch mode (with the `-w` flag). In watch mode,
  `$ dune exec` the executed binary whenever it is recompiled. (ocaml/dune#6966,
  @gridbugs)

- `coqdep` is now called once per theory, instead of one time per Coq
  file. This should significantly speed up some builds, as `coqdep`
  startup time is often heavy (ocaml/dune#7048, @Alizter, @ejgallego)

- Add `map_workspace_root` dune-project stanza to allow disabling of
  mapping of workspace root to `/workspace_root`. (ocaml/dune#6988, fixes ocaml/dune#6929,
  @richardlford)

- Fix handling of support files generated by odoc. (ocaml/dune#6913, @jonludlam)

- Fix parsing of OCaml errors that contain code excerpts with `...` in them.
  (ocaml/dune#7008, @rgrinberg)

- Pre-emptively clear screen in watch mode (ocaml/dune#6987, fixes ocaml/dune#6884, @rgrinberg)

- Fix cross compilation configuration when a context with targets is itself a
  host of another context (ocaml/dune#6958, fixes ocaml/dune#6843, @rgrinberg)

- Fix parsing of the `<=` operator in *blang* expressions of `dune` files.
  Previously, the operator would be interpreted as `<`. (ocaml/dune#6928, @tatchi)

- Fix `--trace-file` output. Dune now emits a single *complete* event for every
  executed process. Unterminated *async* events are no longer written. (ocaml/dune#6892,
  @rgrinberg)

- Fix preprocessing with `staged_pps` (ocaml/dune#6748, fixes ocaml/dune#6644, @rgrinberg)

- Use colored output with MDX when Dune colors are enabled.
  (ocaml/dune#6462, @MisterDA)

- Make `dune describe workspace` return consistent dependencies for
  executables and for libraries. By default, compile-time dependencies
  towards PPX-rewriters are from now not taken into account (but
  runtime dependencies always are). Compile-time dependencies towards
  PPX-rewriters can be taken into account by providing the
  `--with-pps` flag. (ocaml/dune#6727, fixes ocaml/dune#6486, @esope)

- Print missing newline after `$ dune exec`. (ocaml/dune#6821, fixes ocaml/dune#6700, @rgrinberg,
  @Alizter)

- Fix binary corruption when installing or promoting in parallel (ocaml/dune#6669, fixes
  ocaml/dune#6668, @edwintorok)

- Use colored output with GCC and Clang when compiling C stubs. The
  flag `-fdiagnostics-color=always` is added to the `:standard` set of
  flags. (ocaml/dune#4083, @MisterDA)

- Fix the parsing of decimal and hexadecimal escape literals in `dune`,
  `dune-package`, and other dune s-expression based files (ocaml/dune#6710, @shym)

- Report an error if `dune init ...` would create a "dune" file in a location
  which already contains a "dune" directory (ocaml/dune#6705, @gridbugs)

- Fix the parsing of alerts. They will now show up in diagnostics correctly.
  (ocaml/dune#6678, @rginberg)

- Fix the compilation of modules generated at link time when
  `implicit_transitive_deps` is enabled (ocaml/dune#6642, @rgrinberg)

- Allow `$ dune utop` to load libraries defined in data only directories
  defined using `(subdir ..)` (ocaml/dune#6631, @rgrinberg)

- Format dune files when they are named `dune-file`. This occurs when we enable
  the alternative file names project option. (ocaml/dune#6566, @rgrinberg)

- Move `$ dune ocaml-merlin -dump-config=$dir` to `$ dune ocaml merlin
  dump-config $dir`. (ocaml/dune#6547, @rgrinberg)

- Allow compilation rules to be impacted by `(env ..)` stanzas that modify the
  environment or set binaries. (ocaml/dune#6527, @rgrinberg)

- Coq native mode is now automatically detected by Dune starting with Coq lang
  0.7. `(mode native)` has been deprecated in favour of detection from the
  configuration of Coq. (ocaml/dune#6409, @Alizter)

- Print "Leaving Directory" whenever "Entering Directory" is printed. (ocaml/dune#6419,
  fixes ocaml/dune#138, @cpitclaudel, @rgrinberg)

- Allow `$ dune ocaml dump-dot-merlin` to run in watch mode. Also this command
  shouldn't print "Entering Directory" mesages. (ocaml/dune#6497, @rgrinberg)

- `dune clean` should no longer fail under Windows due to the inability to
  remove the `.lock` file. Also, bring the implementation of the global lock
  under Windows closer to that of Unix. (ocaml/dune#6523, @nojb)

- Remove "Entering Directory" messages for `$ dune install`. (ocaml/dune#6513,
  @rgrinberg)

- Stop passing `-q` flag in `dune coq top`, which allows for `.coqrc` to be
  loaded. (ocaml/dune#6848, fixes ocaml/dune#6847, @Alizter)

- Fix missing dependencies when detecting the kind of C compiler we're using
  (ocaml/dune#6610, fixes ocaml/dune#6415, @emillon)

- Allow `(include_subdirs qualified)` for OCaml projects. (ocaml/dune#6594, fixes ocaml/dune#1084,
  @rgrinberg)

- Accurately determine merlin configuration for all sources selected with
  `copy#` and `copy_files#`. The old heuristic of looking for a module in
  parent directories is removed (ocaml/dune#6594, @rgrinberg)

- Fix inline tests with *js_of_ocaml* and whole program compilation mode
  enabled (ocaml/dune#6645, @hhugo)

- Fix *js_of_ocaml* separate compilation rules when `--enable=effects`
  ,`--enable=use-js-string` or `--toplevel` is used. (ocaml/dune#6714, ocaml/dune#6828, ocaml/dune#6920, @hhugo)

- Fix *js_of_ocaml* separate compilation in presence of linkall (ocaml/dune#6832, ocaml/dune#6916, @hhugo)

- Remove spurious build dir created when running `dune init proj ...` (ocaml/dune#6707,
  fixes ocaml/dune#5429, @gridbugs)

- Allow `--sandbox` to affect `ocamldep` invocations. Previously, they were
  wrongly marked as incompatible (ocaml/dune#6749, @rgrinberg)

- Validate the command line arguments for `$ dune ocaml top-module`. This
  command requires one positional argument (ocaml/dune#6796, fixes ocaml/dune#6793, @rgrinberg)

- Add a `dune cache size` command for displaying the size of the cache (ocaml/dune#6638,
  @Alizter)

- Fix dependency cycle when installing files to the bin section with
  `glob_files` (ocaml/dune#6764, fixes ocaml/dune#6708, @gridbugs)

- Handle "Too many links" errors when using Dune cache on Windows (ocaml/dune#6993, @nojb)

- Allow the `cinaps` stanza to set a custom alias. By default, if the alias is
  not set then the cinaps actions will be attached to both `@cinaps` and
  `@runtest` (ocaml/dune#6991, @rgrinberg)

- Add `(using ctypes 0.3)`. When used, paths in `(ctypes)` are interpreted
  relative to where the stanza is defined. (ocaml/dune#6883, fixes ocaml/dune#5325, @emillon)

- Auto-detect `dune-workspace` files as `dune` files in Emacs (ocaml/dune#7061,
  @ilankri)

- Add native support for polling mode on Windows (ocaml/dune#7010, @yams-yams, @nojb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment