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

Sites, locations, relocation #3104

Merged
merged 2 commits into from
Sep 3, 2020
Merged

Sites, locations, relocation #3104

merged 2 commits into from
Sep 3, 2020

Conversation

bobot
Copy link
Collaborator

@bobot bobot commented Feb 8, 2020

This PR adds the notion of sites which are subdirectories of section directories (share, lib, ...) directory. These directories are at different places, in the local directory during development, in the install directory after installation. Moreover other packages could need to install files in another package directory such as plugins.

Sum-up of the features

  • site can be defined in the package definition in dune-project. A site is a sub-directory in the share, lib, or other section of the package
  • Other package can specify the site of another package in its install stanza in order to install files.
  • site are not associated to a unique directory because a package A can be installed but we are building another package B which installs file in the site of A. So the directories associated to the site foo of A are $lib/A/foo and _build/install/lib/A/foo.
  • a new plugin stanza allows to create a plugin in the site of another package. Currently it is restricted to an empty library which depends on other libraries
  • a new generate_module stanza allows to create a module which for each site, lists the directories of this site. This module use the same infrastructure than the build-info. So the site is substituted during promote and installation. An environment variable allows also to append to the site directory.
  • The generate_module gives also facilities for knowing the OCAMLPATH but more importantly to configure findlib so that fl_dynload could be used trivially.
  • dune install as a new option --relocatable which will create a relocatable directory. All the libraries needed by the plugins or which have some external data, must be in the local workspace (not installed by opam).

The complete documentation is available in the diff

FAQ

  • Which plugins are available? The installed plugins and all the plugins that have been built locally (the package dependency should be used) are available

@bobot
Copy link
Collaborator Author

bobot commented Mar 31, 2020

Relocation mode is implemented. But since findlib loads the META files of all the dependencies, copying the local libraries META are not sufficient. For example the META for the thread library is not present. Creating a dumb META file is sufficient (done is the test in the run.t).

There are some solution:

  • Let the developers create the missing META files (The whole MR is an experimental feature)
  • Creating the one from ocaml, but we will need to keep that up-to-date
  • replacing findlib.dynload based on our own META parsing:
    • using existing one but it depends on stdune
    • creating one that just look for the plugin(...) using just ocamllex, but its another META parser

@diml do you have an opinion?

EDIT: the existing parser can be made independent of stdune, which seems the best option

@bobot bobot changed the title [WIP] Sites, locations, relocation Sites, locations, relocation Mar 31, 2020
@bobot
Copy link
Collaborator Author

bobot commented Mar 31, 2020

A first round of review can be done.

@bobot
Copy link
Collaborator Author

bobot commented Mar 31, 2020

@nojb I would appreciate if you could take a look. The relocatable part is implemented and should work if you can put all your dependencies in the workspace (except for a misfeature for the libraries installed from OCaml, cf above comment). The tests in sites_locations shows how to use it. I'm going to test the relocation part with why3.

@bobot
Copy link
Collaborator Author

bobot commented Apr 1, 2020

Artefact_substitution is here done on libraries, so cmx hash is at the end wrong in some sense. With sufficient Sys.opaque, it should not create bugs but it is fragile. If the generated module was always compiled with -opaque it would work.

@ghost
Copy link

ghost commented Apr 1, 2020

Doesn't ocamlfind install these meta files?

@nojb
Copy link
Collaborator

nojb commented Apr 1, 2020

@nojb I would appreciate if you could take a look. The relocatable part is implemented and should work if you can put all your dependencies in the workspace (except for a misfeature for the libraries installed from OCaml, cf above comment). The tests in sites_locations shows how to use it. I'm going to test the relocation part with why3.

I will try, but won't be able to do so until next week the earliest (too many things on my plate at the moment).

@bobot
Copy link
Collaborator Author

bobot commented Apr 2, 2020

Doesn't ocamlfind install these meta files?

It does but we need to copy all of them during the creation of the installation directory during for relocation, in fact we still need to copy the cmxs and cma which is not yet done.

It is perhaps overkill for the little problem but now it is independent of findlib. The advantages are that it follows now the same rules than dune for the hardcoded ocamlpath; plugins can have the same name than librairies; we don't have to initialize multiple times findlib; no cache to cleanup. The drawbacks is 200 lines of code.

@bobot
Copy link
Collaborator Author

bobot commented Apr 2, 2020

Thanks a lot @nojb. The implementation is finished and you will maybe appreciate that there is no more findlib dependency. I'm going to write the documentation.

@bobot
Copy link
Collaborator Author

bobot commented Apr 3, 2020

I'm splitting this MR in understandable part:

@ghost
Copy link

ghost commented Apr 7, 2020

Thanks for splitting!

src/dune/dune_file.mli Outdated Show resolved Hide resolved
src/dune/install.mli Outdated Show resolved Hide resolved
src/dune/install.mli Outdated Show resolved Hide resolved
@bobot
Copy link
Collaborator Author

bobot commented Sep 2, 2020

All the requests have been fixed in ebf35fc and the branch has been rebased. During the rebase I had to move Install to dune_engine.

@@ -6,6 +6,9 @@ type t =
; build_dir : Path.Build.t
; env : Env.t
; host : t option
; stdlib_dir : Path.t (** todo try to remove it *)
Copy link
Member

Choose a reason for hiding this comment

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

@cwong-ocaml @aalekseyev this change is unfortunate, but it seems inevitable if artifact substitution is part of the engine.

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 it might be a good idea to see if we can rewrite Install in terms of a lower-level filesystem-as-known-to-dune API (I can also work on putting something like that together); I'm sure this isn't the only module that would benefit from it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

My hope would be that artifact substitution could be a part of the rules, instead. (I don't think we should think too much about that for this PR, though)

@rgrinberg
Copy link
Member

@aalekseyev I'd appreciate a second glance at the documentation if you have some time. This doesn't have to delay the PR however.

I'll merge the PR today or tomorrow after one last pass.


The installation can be done in specific mode (``--relocation``) for creating a
directory that can be moved around. In that case the executables installed will
lookup the sites (cf :ref:`sites`) of the packages relatively to its location.
Copy link
Collaborator

@aalekseyev aalekseyev Sep 2, 2020

Choose a reason for hiding this comment

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

I think it's hard to figure out what its location is referring to here. Should it say the location of the executable? (is that even correct?)

@aalekseyev
Copy link
Collaborator

I had a quick look at the documentation and it sounds reasonable, but I really can't say I fully understand why the sites and plugins have to be related. It seems pretty sensible to me to collect non-plugin configurations in a site, or to store a plugin separately in a package that defines it, passing it to the runner exe by an alternative mechanism.

One technical question that I'm curious about: if you run a plugin-bearing executable from a dune rule, for example to test it, what happens? What site locations does it observe and what plugins will it find there? What is the correct way to declare dependencies for such a rule?

@rgrinberg rgrinberg force-pushed the relocation branch 2 times, most recently from 7186bab to 37bbcc8 Compare September 3, 2020 01:54
Signed-off-by: François Bobot <[email protected]>
 - Add sites declaration in package definition
 - Add generate_module and plugin stanza
 - Add sites as destination of install stanza

Signed-off-by: François Bobot <[email protected]>
Signed-off-by: Rudi Grinberg <[email protected]>
@rgrinberg
Copy link
Member

@bobot merged!

don't forget to address any remaining comments here.

@bobot
Copy link
Collaborator Author

bobot commented Sep 3, 2020

It seems pretty sensible to me to collect non-plugin configurations in a site, or to store a plugin separately in a package that defines it, passing it to the runner exe by an alternative mechanism.

Things can be duplicated, but the declaration, the installation machinery, the passing of the directory localisation in every case is the same for sites and for plugins. Plugins are in fact built on top of sites. I could have splitted the MR this way.

One technical question that I'm curious about: if you run a plugin-bearing executable from a dune rule, for example to test it, what happens?

If we have pkg1 which has an executable exe which accept plugins, and pkg2 defines such a plugin:

  • If when testing exe you want to use the plugin pkg2 the right dependency is (package pkg2)
  • The site for pkg1 are located in _build/install/default/{share,lib}/pkg1/ and directly available from a module generated by (generate_module (name mod) (sites pkg1) ...)

Even if pkg1 is also installed globally, the local exe will not see those directories.

If pkg1 is installed but pkg2 is a local package:

  • same dependencies
  • The installed site of pkg1 and the local _build/.../pkg1/ are the location of the site. That's why it is not a unique directory but a list of directories.

Do you think such precision should be added in the documentation? In concept? In (generate_module doc?

@aalekseyev
Copy link
Collaborator

Thanks. I'm just trying to understand for now.

If a package pkg3 is later added and it installs a new plugin into the site of pkg1, then the behavior of exe may change based on the existence of that plugin (it scans for all the plugins in a directory, right?). If that dependency is not tracked, then we have a problem (sandboxing may help, but if we're relying on sandboxing then we should make that explicit).

Maybe we could/should instead make it so that merely depending on (package pkg1) forces all its sites to be fully populated?

Alternatively, we could declare that the user must use sandboxing when depending on a package that has any sites.

I think a clarification on what happens when you depend on a (package ...) that has any sites can go into Dependency specification section in concepts.rst, the (package <pkg>) bullet point.

@bobot bobot mentioned this pull request Sep 14, 2020
@rgrinberg
Copy link
Member

@bobot Jeremie and I reviewed the docs and we think this feature is better documented in its own section (like js_of_ocaml for example). Additionally, it would also be nice to start the doc with a tutorial style introduction that does not assume much prior knowledge, in the style of tests.rst. We feel that such a feature needs a little more narrative for the user to better understand when it should be used.

@bobot
Copy link
Collaborator Author

bobot commented Sep 16, 2020

There is already a section in advanced topic about sites/plugins, is it this kind of example you want me to move to its own file? like jsoo.rst?

@ghost
Copy link

ghost commented Sep 16, 2020

The topic we are covering here is "how to load additional files at runtime". It feels important enough to get its own chapter in the manual, explaining each concept and feature one by one from the simpler ones to the most advanced ones. doc/tests.rst is a good example of that.

Initially, the manual was written in a "reference manual" style, because there was a lot to document and just describing what was there was the quickest way to mint the manual. However, while a reference manual is good it is not the easiest for users. So we are trying to move away from a reference manual and move towards a more classic book about to learn Dune.

Here, my reasoning is the following; as an application grows and becomes more complex, there will be a point were the developers will want to add support for loading additional files (including plugins) at runtime. To learn how to do that, they should look for a chapter in the manual that explains how to load additional files at runtime in applications developed with Dune. This chapter should explain everything from the ground up, so that at the end of it the developer knows what is a site, how Dune installs such additional files, etc...

@bobot
Copy link
Collaborator Author

bobot commented Sep 16, 2020

Ok, done in #3794. Thank you for the explanation, I will add some more in this direction.

rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Jan 13, 2021
…ne-action-plugin, dune-private-libs and dune-glob (2.8.0)

CHANGES:

- `dune rules` accepts aliases and other non-path rules (ocaml/dune#4063, @mrmr1993)

- Action `(diff reference test_result)` now accept `reference` to be absent and
  in that case consider that the reference is empty. Then running `dune promote`
  will create the reference file. (ocaml/dune#3795, @bobot)

- Ignore special files (BLK, CHR, FIFO, SOCKET), (ocaml/dune#3570, fixes ocaml/dune#3124, ocaml/dune#3546,
  @ejgallego)

- Experimental: Simplify loading of additional files (data or code) at runtime
  in programs by introducing specific installation sites. In particular it allow
  to define plugins to be installed in these sites. (ocaml/dune#3104, ocaml/dune#3794, fixes ocaml/dune#1185,
  @bobot)

- Move all temporary files created by dune to run actions to a single directory
  and make sure that actions executed by dune also use this directory by setting
  `TMPDIR` (or `TEMP` on Windows). (ocaml/dune#3691, fixes ocaml/dune#3422, @rgrinberg)

- Fix bootstrap script with custom configuration. (ocaml/dune#3757, fixes ocaml/dune#3774, @marsam)

- Add the `executable` field to `inline_tests` to customize the compilation
  flags of the test runner executable (ocaml/dune#3747, fixes ocaml/dune#3679, @lubegasimon)

- Add `(enabled_if ...)` to `(copy_files ...)` (ocaml/dune#3756, @nojb)

- Make sure Dune cleans up the status line before exiting (ocaml/dune#3767,
  fixes ocaml/dune#3737, @alan-j-hu)

- Add `{gitlab,bitbucket}` as options for defining project sources with `source`
  stanza `(source (<host> user/repo))` in the `dune-project` file.  (ocaml/dune#3813,
  @rgrinberg)

- Fix generation of `META` and `dune-package` files when some targets (byte,
  native, dynlink) are disabled. Previously, dune would generate all archives
  for regardless of settings. (ocaml/dune#3829, ocaml/dune#4041, @rgrinberg)

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

- Fix cram tests inside vendored directories not being interpreted correctly.
  (ocaml/dune#3860, fixes ocaml/dune#3843, @rgrinberg)

- Add `package` field to private libraries. This allows such libraries to be
  installed and to be usable by other public libraries in the same project
  (ocaml/dune#3655, fixes ocaml/dune#1017, @rgrinberg)

- Fix the `%{make}` variable on Windows by only checking for a `gmake` binary
  on UNIX-like systems as a unrelated `gmake` binary might exist on Windows.
  (ocaml/dune#3853, @kit-ty-kate)

- Fix `$ dune install` modifying the build directory. This made the build
  directory unusable when `$ sudo dune install` modified permissions. (fix
  ocaml/dune#3857, @rgrinberg)

- Fix handling of aliases given on the command line (using the `@` and `@@`
  syntax) so as to correctly handle relative paths. (ocaml/dune#3874, fixes ocaml/dune#3850, @nojb)

- Allow link time code generation to be used in preprocessing executable. This
  makes it possible to use the build info module inside the preprocessor.
  (ocaml/dune#3848, fix ocaml/dune#3848, @rgrinberg)

- Correctly call `git ls-tree` so unicode files are not quoted, this fixes
  problems with `dune subst` in the presence of unicode files. Fixes ocaml/dune#3219
  (ocaml/dune#3879, @ejgallego)

- `dune subst` now accepts common command-line arguments such as
  `--debug-backtraces` (ocaml/dune#3878, @ejgallego)

- `dune describe` now also includes information about executables in addition to
  that of libraries. (ocaml/dune#3892, ocaml/dune#3895, @nojb)

- instrumentation backends can now receive arguments via `(instrumentation
  (backend <name> <args>))`. (ocaml/dune#3906, ocaml/dune#3932, @nojb)

- Tweak auto-formatting of `dune` files to improve readability. (ocaml/dune#3928, @nojb)

- Add a switch argument to opam when context is not default. (ocaml/dune#3951, @tmattio)

- Avoid pager when running `$ git diff` (ocaml/dune#3912, @AltGr)

- Add `(root_module ..)` field to libraries & executables. This makes it
  possible to use library dependencies shadowed by local modules (ocaml/dune#3825,
  @rgrinberg)

- Allow `(formatting ...)` field in `(env ...)` stanza to set per-directory
  formatting specification. (ocaml/dune#3942, @nojb)

- [coq] In `coq.theory`, `:standard` for the `flags` field now uses the
  flags set in `env` profile flags (ocaml/dune#3931 , @ejgallego @rgrinberg)

- [coq] Add `-q` flag to `:standard` `coqc` flags , fixes ocaml/dune#3924, (ocaml/dune#3931 , @ejgallego)

- Add support for Coq's native compute compilation mode (@ejgallego, ocaml/dune#3210)

- Add a `SUFFIX` directive in `.merlin` files for each dialect with no
  preprocessing, to let merlin know of additional file extensions (ocaml/dune#3977,
  @vouillon)

- Stop promoting `.merlin` files. Write per-stanza Merlin configurations in
  binary form. Add a new subcommand `dune ocaml-merlin` that Merlin can use to
  query the configuration files. The `allow_approximate_merlin` option is now
  useless and deprecated. Dune now conflicts with `merlin < 3.4.0` and
  `ocaml-lsp-server < 1.3.0` (ocaml/dune#3554, @voodoos)

- Configurator: fix a bug introduced in 2.6.0 where the configurator V1 API
  doesn't work at all when used outside of dune. (ocaml/dune#4046, @aalekseyev)

- Fix `libexec` and `libexec-private` variables. In cross-compilation settings,
  they now point to the file in the host context. (ocaml/dune#4058, fixes ocaml/dune#4057,
  @TheLortex)

- When running `$ dune subst`, use project metadata as a fallback when package
  metadata is missing. We also generate a warning when `(name ..)` is missing in
  `dune-project` files to avoid failures in production builds.

- Remove support for passing `-nodynlink` for executables. It was bypassed in
  most cases and not correct in other cases in particular on arm32.
  (ocaml/dune#4085, fixes ocaml/dune#4069, fixes ocaml/dune#2527, @emillon)

- Generate archive rules compatible with 4.12. Dune longer attempt to generate
  an archive file if it's unnecessary (ocaml/dune#3973, fixes ocaml/dune#3766, @rgrinberg)

- Fix generated Merlin configurations when multiple preprocessors are defined
  for different modules in the same folder. (ocaml/dune#4092, fixes ocaml/dune#2596, ocaml/dune#1212 and
  ocaml/dune#3409, @voodoos)

- Add the option `use_standard_c_and_cxx_flags` to `dune-project` that 1.
  disables the unconditional use of the `ocamlc_cflags` and `ocamlc_cppflags`
  from `ocamlc -config` in C compiler calls, these flags will be present in the
  `:standard` set instead; and 2. enables the detection of the C compiler family
  and populates the `:standard` set of flags with common default values when
  building CXX stubs. (ocaml/dune#3875, ocaml/dune#3802, fix ocaml/dune#3718 and ocaml/dune#3528, @voodoos)
@Alizter Alizter deleted the relocation branch November 10, 2022 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants