-
Notifications
You must be signed in to change notification settings - Fork 640
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
Fix ocamlpath order in findlib init #16428
Conversation
I don't have the time, sorry The way I experience the bug is to run |
I think it is impossible to test it in Coq itself. But here is how I tested my patch manually:
let _ = Mltop.add_known_module "coq-foo.foo"
let () = Printf.printf "foo 1\n%!"
Declare ML Module "coq-foo.foo".
ocamlfind ocamlopt -package coq-core.toplevel -rectypes -thread -shared foo.ml -o foo.cmxs
coqc -I . foo.v
DIR=$(ocamlfind printconf destdir)/coq-foo
mkdir $DIR
cp foo.cmxs $DIR/
grep -v 'directory *=' META.coq-foo > $DIR/META
coqc foo.v
sed -i -e 's/foo 1/foo 2/' foo.ml
ocamlfind ocamlopt -package coq-core.toplevel -rectypes -thread -shared foo.ml -o foo.cmxs
coqc -I . foo.v |
I think you can set the right env variables (see http://projects.camlcity.org/projects/dl/findlib-1.9.5/doc/ref-html/lib/Findlib.html) to have an alternate tree / config for findlib in the test suite which is reproducible. |
sysinit/coqinit.ml
Outdated
try Sys.getenv "OCAMLPATH" ^ ocamlpathsep ^ ocamlpath | ||
with Not_found -> ocamlpath in | ||
let env_ocamlpath = try Sys.getenv "OCAMLPATH" :: ml_load_path with Not_found -> ml_load_path in | ||
let env_ocamlpath = String.concat ocamlpathsep (List.rev env_ocamlpath) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the issue, using List.rev
is an unfortunate choice, since it causes -I
directories to be scanned right-to-left, while the vast majority of compilers (e.g., gcc
, ocamlc
) use a left-to-right policy.
- "Directories specified with -I options are scanned in left-to-right order."
- "Directories added with -I are searched [...] in the order in which they were given on the command line"
I guess we don't document the effect of order for -I so either is technically correct, but shouldn't we keep the past behaviour? |
24ea74c
to
c5e01fc
Compare
Changed: when passed |
c5e01fc
to
c87c455
Compare
sysinit/coqargs.ml
Outdated
@@ -448,7 +448,12 @@ let build_load_path opts = | |||
else | |||
let coqenv = Boot.Env.init () in | |||
Coqloadpath.init_load_path ~coqenv in | |||
ml_path @ opts.pre.ml_includes , | |||
let ocamlpathsep = if Sys.unix then ':' else ';' in | |||
let env_ocamlpath = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't we say that when -boot is set, we don't use OCAMLPATH?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the opposite of what I understood.
-boot is about not binding the stdlib, so it is unrelated to OCAMLPATH
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, OCAMLPATH should always be used (e.g., critical on Nix). Otherwise, dependencies will not be found.
Will that not break the compilation of Coq when there is already a release of Coq installed on the system? Indeed, the currently compiled Coq will look for its plugins in |
@silene compilation of Coq has moved to using less implicit stuff, so indeed the standard library is compiled using |
Dune is also scheduled to use |
Isn't dune setting OCAMLPATH to point to the _build directory? |
Yes, as part of the workspace configuration. |
sysinit/coqargs.ml
Outdated
try String.split_on_char ocamlpathsep (Sys.getenv "OCAMLPATH") | ||
with Not_found -> [] | ||
in | ||
opts.pre.ml_includes @ env_ocamlpath @ ml_path , |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it on purpose that the content of $OCAMLPATH
is passed to Mltop.add_ml_dir
? This seems like a very bad idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think this part should be reverted until we remove the legacy loading method in 8.17
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This point came up at the call, but nobody could find the problem. What is it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the content of $OCAMLPATH is passed to Mltop.add_ml_dir? This seems like a very bad idea.
what is the problem when doing that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that, on some systems (e.g., Nix), $OCAMLPATH
contains the whole world. Thus, when trying to load a legacy plugin, Coq will scan a bunch of directories that are completely unrelated to Coq. (Notice that this pull request scans env_ocamlpath
before ml_path
, where the legacy plugins lie.) In fact, if by sheer luck Coq were to actually find a plugin with the searched name in one of these directories, it is guaranteed to be a broken one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, then I think @SkySkimmer should avoid this, and that requires changing the API IMO, since you need to separate the paths from OCAMPATH from the others.
I keep the occasion, in case Nix people are listening, to remind that OCAMLPATH is there to let one override the system config, not a place to store it. If they want to stay with env variables, they should add a nix specific one to findlib, eg NIX_OCAMLPATH, and have findlib honor both, giving OCAMLPATH precedence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only need to change the API if you want $OCAMLPATH
to be searched after opts.pre.ml_includes
but before ml_path
. But why do you even want that in the first place? Why should the Coq directories in ml_path
not take precedence over OCAMLPATH
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remind that OCAMLPATH is there to let one override
because of this? (we may even use this in the CI)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Responding to the off-topic comment:
I keep the occasion, in case Nix people are listening, to remind that OCAMLPATH is there to let one override the system config, not a place to store it. If they want to stay with env variables, they should add a nix specific one to findlib, eg NIX_OCAMLPATH, and have findlib honor both, giving OCAMLPATH precedence.
Nix is using this "trick" in many programming languages that have a PATH
environment variable, and has done so successfully for years. If Nix users had had to request changes to most of their programming tools to be able to work, it would have been less successful. The fact that Nix is becoming more and more important and has more and more users does not justify (IMHO) to introduce Nix-specific quirks in generic tools.
c87c455
to
85e0645
Compare
85e0645
to
ed8ce2b
Compare
changed: findlib sees |
Hum, this way OCAMLPATH cannot be used to override default_dirs, but just to extend them. Was there a problem with default_dirs being last? |
But I guess, this particular problem was actually resolved by #16428 (comment) |
Hum, so? |
@SkySkimmer adding a test wouldn't hurt, we can simulate a "global" install using the findlib variables, then we can test precedence properly. |
If you want to write a test feel free, I don't have quite enough understanding to do it myself. |
I'll open an issue, I don't have time to write the test now, but happy to sheperd. |
@@ -184,6 +184,9 @@ and ``coqtop``, unless stated otherwise: | |||
(``.cmo`` or ``.cmxs``). Subdirectories are not included. | |||
See the command :cmd:`Declare ML Module`. | |||
|
|||
Directories added with ``-I`` are searched after the current directory, | |||
in the order in which they were given on the command line |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is some missing punctuation, we might just as well be comprehensive.
in the order in which they were given on the command line | |
in the order in which they were given on the command line, | |
before OCaml's default directories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think neither comma is needed.
@coqbot: merge now |
Fix #16406