Skip to content

Prefer findlib over PATH#1707

Closed
rgrinberg wants to merge 3 commits intoocaml:mainfrom
rgrinberg:correct-toolchain
Closed

Prefer findlib over PATH#1707
rgrinberg wants to merge 3 commits intoocaml:mainfrom
rgrinberg:correct-toolchain

Conversation

@rgrinberg
Copy link
Copy Markdown
Member

Attempt to fix #1701

By default, dune basically uses OCAMLPATH and whatever is available in PATH. This seems a bit inconsistent and surprising as I think that most would expect dune to use whatever configuration findlib is using.

On the other hand, this is technically a breaking change. A possibility to avoid it is to turn this option off by default, and make it possible to toggle it in the workspace file. But this seems like it's just going to add entropy to an already complicated part of the code.

The first commit can be merged on its own as it's just fixing dune's ability to understand toolchains defined in the same config file.

Would like to hear some feedback about how accurately dune should emulate findlib (@nojb, @bobot, @emillon)

@rauanmayemir
Copy link
Copy Markdown

rauanmayemir commented Dec 23, 2018

Would it still be a breaking change if, by default, dune used findlib only if $OCAMLFIND_CONF were set and kept using OCAMLPATH or whatever is available in PATH otherwise?

ability to understand toolchains defined in the same config file.

Dune used to fail unless variable(toolchain) = "value" was set in a separate file like findlib.conf.d/toolchain.conf. Was it ocamlfind's or dune's constraint? (UPD: Never mind, just read the commit comment.)

@rauanmayemir
Copy link
Copy Markdown

most would expect dune to use whatever configuration findlib is using.

Given the drop of direct dependency on ocamlfind in beta19, the whole behaviour is now actually undefined. 😁

@rgrinberg
Copy link
Copy Markdown
Member Author

Would it still be a breaking change if, by default, dune used findlib only if $OCAMLFIND_CONF were set and kept using OCAMLPATH or whatever is available in PATH otherwise?

Why would this be desirable? Dune should simply uses findlib whenever it is present. I assume that users who have findlib installed are assuming that its settings are being fully respected.

Given the drop of direct dependency on ocamlfind in beta19, the whole behaviour is now actually undefined. 😁

I think there's a bit of confusion here. Dune never used findlib via the ocamlfind binary. It has always used its own implementation of findlib to understand various findlib settings and interpret META files. The only reason we depended on findlib before was to avoid a race condition at installation time. Eventually, we found a better way to avoid the race condition, so we dropped the dependency on findlib. But we never used the ocamlfind binary even before beta19.

The issue in my opinion that dune is currently picking and choosing which findlib features it implements. This is why there are some limitations on things like defining toolchains in one file and allowing to set the libraries path via the ocamlfind config. In my opinion, dune should mimic findlib faithfully whenever it is available. Of course, there should be a way to turn this off.

@rauanmayemir
Copy link
Copy Markdown

Thanks for clarifying, it all makes sense now.

@ghost
Copy link
Copy Markdown

ghost commented Jan 7, 2019

@rgrinberg can you think of a real scenario where this PR would change the behavior? The only I can think of is the following:

  • you have a global installation of ocaml with a findlib.conf file that uses absolute paths for ocamlc, ocamlopt, ...
  • then you do a manual build & install of ocaml and edit your PATH

with this PR, dune would still pick up the global ocaml rather than the manually installed one. However, absolute paths in findlib.conf don't seem to be very common. For instance, the findlib.conf file installed via opam install ocamlfind still causes the various tools to be looked up in the PATH:

$ cat `ocamlfind printconf conf`
[...]
ocamlc="ocamlc.opt"
ocamlopt="ocamlopt.opt"
ocamldep="ocamldep.opt"
ocamldoc="ocamldoc.opt"

Given that, I tend to think that we can reasonably expect that this PR won't be noticeable for users.

@rgrinberg
Copy link
Copy Markdown
Member Author

There's a couple of differences this PR brings (some are unrelated to each other):

  • Cross compilation now works without findlib being installed. This seems useful for tools like esy that are planning to configure host/targets combinations using findlib.

  • Toolchains are now defineable in multiple files without any requirement on file convention. I think defining multiple toolchains in one file is cleaner.

Additionally, if we were to go ahead with this PR, I would improve the emulation of findlib further. For example, path in findlib.conf can also be parameterized by the toolchain name. I think that's fairly useful as well.

@ghost
Copy link
Copy Markdown

ghost commented Jan 8, 2019

I see. Personally I'm fine with these changes.

@rgrinberg rgrinberg added this to the 1.7.0 milestone Jan 14, 2019
@jordwalke
Copy link
Copy Markdown
Contributor

  • you have a global installation of ocaml with a findlib.conf file that uses absolute paths for ocamlc, ocamlopt, ...

Does/will opam construct such a thing which people put in their global environment by way of sourcing the opam init?

If so, it would conflict with local esy builds when people also happen to have an opam environment initialized. If not, I think there's no worry (that I can think of).

Previously, toolchains were only allowed to be defined in their own files. This
isn't really how findlib works at the moment. Findlib simply allows for extra
configuration files to be present in the .d directory. We should simply read
this directory like findlib does.

Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
@rgrinberg
Copy link
Copy Markdown
Member Author

If so, it would conflict with local esy builds when people also happen to have an opam environment initialized. If not, I think there's no worry (that I can think of).

Does esy set the findlib config explicitly anyway? If it does, then it has nothing to worry about.

The way to address the problem diml pointed out is by explicit configuration. The way I see it, dune respects the findlib configuration by default but should allow users to override it.

Using absolute paths in the findlib.conf will also cause problems if we build the compiler with dune and compose it in another build. I'm ok with having users manually override their findlib installs if those are not properly configured.

Currently, dune prefers ocamlc, ocamlopt, etc. from PATH

Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
@rauanmayemir
Copy link
Copy Markdown

@rgrinberg Esy will set findlib config explicitly as soon as we merge it (we will temporarily set OCAMLPATH as well for older dune to keep working).

@rgrinberg
Copy link
Copy Markdown
Member Author

Looking at the current code, whenever we have opam installed, then we use it to discover where the libraries should be sourced from rather than $ ocamlfind printconf path. That seems a bit off to me and we should change it to respect the findlib configuration. Should we add a Build_environment_kind that reflects a findlib based setup. Opam2/Opam1 can be used whenever no findlib.conf is given.

@ghost
Copy link
Copy Markdown

ghost commented Feb 11, 2019

It does seem like we have too many entry points for the user to configure things, and it is starting to become hard to understand how all these interact between each other.

Rather than fiddle around, I suggest to start a discussion with the authors of the various tools to see if we can reach an agreement. If we can agree on a blessed way to setup the environment for OCaml compilation, then we don't need to support every possible combination.

@rgrinberg
Copy link
Copy Markdown
Member Author

Sure, I agree with that. I just thought that findlib was basically that standard already. Let me cc @andreypopp here as well. If there's a consensus from the esy team on what exactly dune should support to configure compilation environments, that would be an important step forward already.

@rgrinberg rgrinberg removed this from the 1.7.0 milestone Feb 11, 2019
@ghost
Copy link
Copy Markdown

ghost commented Feb 13, 2019

Well, that's almost true. Over the years, findlib has mostly become the standard. There is however one catch: ocamlfind is not mandatory and is not always installed. This is a big issue when you have several installations of OCaml, such as a system one, an opam one and/or an esy one on top.

If we agree that variables such as OCAMLPATH have authority and specify the ocaml installation to use, then that's fine. However, all the various tools and in particular opam must set this variable consistently.

There is still an issue regarding findlib.conf: currently the only way to locate it is to call ocamlfind printconf conf. However, the ocamlfind binary that is in the path might not be the one from the right installation. For instance, if you have an ocamlfind installed via your distribution, and you are using opam but didn't install ocamlfind, then ocamlfind printconf conf won't report the right configuration file :/

@rgrinberg
Copy link
Copy Markdown
Member Author

There is still an issue regarding findlib.conf: currently the only way to locate it is to call ocamlfind printconf conf. However, the ocamlfind binary that is in the path might not be the one from the right installation. For instance, if you have an ocamlfind installed via your distribution, and you are using opam but didn't install ocamlfind, then ocamlfind printconf conf won't report the right configuration file :/

Okay, I'm convinced that we shouldn't use findlib as the default for this reason. On the other hand, I think we should go for full findlib support whenever OCAMLFIND_CONF or OCAMLFIND_TOOLCHAIN are set. I think the possibility for these variables to be set accidentally is quite low.

@rauanmayemir
Copy link
Copy Markdown

I think we should go for full findlib support whenever OCAMLFIND_CONF or OCAMLFIND_TOOLCHAIN are set.

This would be most preferable.

madroach pushed a commit to madroach/dune that referenced this pull request Aug 12, 2019
This helps me solve the following problem when porting for OpenBSD:

The OCaml libdir on OpenBSD is ``/usr/local/lib/ocaml``.
When creating binary packages the installation is made into a "fake"
root, which results in a libdir like
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``

Now, since the pre-dune era, we set OCAMLFIND_DESTDIR to
``/usr/local/lib/ocaml`` when building a port, but to e.g.
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
when (fake-)installing a port. This is not exactly how a ``DESTDIR`` is supposed to
work, but it did the job.

Now dune actually respects ``DESTDIR`` and will prepend in to
``OCAMLFIND_DESTDIR``, which will then result in
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
during (fake-)installation.

To solves this I currently need to special treat all ports using dune and
unset ``OCAMLFIND_DESTDIR`` for them.

Actually ocamlfind is to be blamed here, because it gets the concept of
``DESTDIR`` wrong. I don't expect this to change.

For me it would be convenient if I could directly configure dune by
environment variables and bypass ocamlfind completely.

This commit accomplishes this only for ``dune install``. It would be nice if
dune would respect ``DUNE_LIBDIR`` for ``dune build``, too.

This may be related to ocaml#1707.

Here's GNU's definition of DESTDIR, LIBDIR, PREFIX and so on:
https://www.gnu.org/prep/standards/html_node/DESTDIR.html
https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
madroach pushed a commit to madroach/dune that referenced this pull request Aug 12, 2019
This helps me solve the following problem when porting for OpenBSD:

The OCaml libdir on OpenBSD is ``/usr/local/lib/ocaml``.
When creating binary packages the installation is made into a "fake"
root, which results in a libdir like
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
which is constructed from ``PREFIX`` and ``DESTDIR``:
``${DESTDIR}/${TRUEPREFIX}/lib/ocaml``

Now, since the pre-dune era, we set ``OCAMLFIND_DESTDIR`` to
``/usr/local/lib/ocaml`` when building a port, but to
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
when (fake-)installing a port. This is not exactly how a ``DESTDIR`` is supposed to
work, but it did the job.

Now dune actually respects ``DESTDIR`` and will prepend it to
``OCAMLFIND_DESTDIR``, which will then result in
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
during (fake-)installation, which is obviously not what I want.

To solve this I currently need to special treat all ports using dune and
unset ``OCAMLFIND_DESTDIR`` for them.

For me it would be convenient if I could directly configure dune by
environment variables and bypass ocamlfind completely.

This commit accomplishes this only for ``dune install``. It would be nice if
dune would respect ``DUNE_LIBDIR`` for ``dune build``, too.

This may be related to ocaml#1707.

Here's GNU's definition of DESTDIR, LIBDIR, PREFIX and so on:
https://www.gnu.org/prep/standards/html_node/DESTDIR.html
https://www.gnu.org/prep/standards/html_node/Directory-Variables.html

Signed-off-by: Christopher Zimmermann <chrisz@openbsd.org>
madroach pushed a commit to madroach/dune that referenced this pull request Aug 12, 2019
This helps me solve the following problem when porting for OpenBSD:

The OCaml libdir on OpenBSD is ``/usr/local/lib/ocaml``.
When creating binary packages the installation is made into a "fake"
root, which results in a libdir like
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
which is constructed from ``PREFIX`` and ``DESTDIR``:
``${DESTDIR}/${TRUEPREFIX}/lib/ocaml``

Now, since the pre-dune era, we set ``OCAMLFIND_DESTDIR`` to
``/usr/local/lib/ocaml`` when building a port, but to
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
when (fake-)installing a port. This is not exactly how a ``DESTDIR`` is supposed to
work, but it did the job.

Now dune actually respects ``DESTDIR`` and will prepend it to
``OCAMLFIND_DESTDIR``, which will then result in
``/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/ports/pobj/dune-1.10.0/fake-amd64/usr/local/lib/ocaml``
during (fake-)installation, which is obviously not what I want.

To solve this I currently need to special treat all ports using dune and
unset ``OCAMLFIND_DESTDIR`` for them.

For me it would be convenient if I could directly configure dune by
environment variables and bypass ocamlfind completely.

This commit accomplishes this only for ``dune install``. It would be nice if
dune would respect ``DUNE_LIBDIR`` for ``dune build``, too.

This may be related to ocaml#1707.

Here's GNU's definition of DESTDIR, LIBDIR, PREFIX and so on:
https://www.gnu.org/prep/standards/html_node/DESTDIR.html
https://www.gnu.org/prep/standards/html_node/Directory-Variables.html

Signed-off-by: Christopher Zimmermann <madroach@gmerlin.de>
@rgrinberg rgrinberg marked this pull request as draft April 29, 2020 15:07
Base automatically changed from master to main January 14, 2021 17:08
@rgrinberg
Copy link
Copy Markdown
Member Author

@jeremiedimino I'm wondering if we should revive this PR but modify a couple of things. We'll just respect OCAMLFIND_TOOLCHAIN and OCAMLFIND_CONF and completely ignore the ocamlfind binary otherwise. To me this seems like the most consistent way of dune working. I don't quite like the current behavior that we got rid of ocamlfind in the regular path, but still keep it around for cross compilation.

@ghost
Copy link
Copy Markdown

ghost commented Mar 1, 2021

Agreed that the current state is a bit wonky. Why do we need to support OCAMLFIND_TOOLCHAIN and OCAMLFIND_CONF at all?

For cross-compilation, it feels like we could just look for $OPAM_SWITCH_PREFIX/lib/findlib.conf.d/<target>.conf and be done with it.

@bobot
Copy link
Copy Markdown
Collaborator

bobot commented Mar 1, 2021

I wonder if it is not used for cross-compilation in distribution. For example ocaml-mingw-w64-x86-64 defines an etc/x86_64-w64-mingw32-ocamlfind.conf. However I haven't found how it is used. Moreover we could find a simpler way to support this use case with dune.

@ghost
Copy link
Copy Markdown

ghost commented Mar 1, 2021

Ah, I wasn't aware distributions also installed such a configuration file. One idea would be to allow to configure a pattern for such configuration at compile time. That would be in-line with the optional compile-time configuration of the library path.

@rgrinberg
Copy link
Copy Markdown
Member Author

Agreed that the current state is a bit wonky. Why do we need to support OCAMLFIND_TOOLCHAIN and OCAMLFIND_CONF at all?

To make it easy for opam-cross maintainers to adapt. IIRC, they still have non dune packages.

For cross-compilation, it feels like we could just look for $OPAM_SWITCH_PREFIX/lib/findlib.conf.d/.conf and be done with it.

Let's see if @toots is fine with that.

Ah, I wasn't aware distributions also installed such a configuration file. One idea would be to allow to configure a pattern for such configuration at compile time. That would be in-line with the optional compile-time configuration of the library path.

That seems good.

@toots
Copy link
Copy Markdown
Contributor

toots commented Mar 3, 2021

Cross compilation is pretty tightly tied to opam so I believe, as long as we honor OPAM_SWITCH_PREFIX we should be fine since it looks like opam is currently setting it.

As a side note, we're pretty much stuck with updating dune for cross-compilation until #3751 is merged/fixed.

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.

Dune doesn't use ocamlfind config in default context

5 participants