ocaml / opam

opam is a source-based package manager. It supports multiple simultaneous compiler installations, flexible package constraints, and a Git-friendly development workflow.
https://opam.ocaml.org
Other
1.21k stars 348 forks source link

Opam windows: ocaml vs ocaml.exe: "Cannot find file topfind" #5967

Open jacj-simcorp opened 1 month ago

jacj-simcorp commented 1 month ago

Hi, I am unsure if this is a bug or not.

I am testing opam 2.2 on Windows. I have a custom switch with a system-provided OCaml compiler.

Some packages fail to build with the error "Cannot find file topfind.".

If I source one of these packages, for example, topkg, I can build it using

ocaml pkg/pkg.ml build --pkg-name topkg --dev-pkg false

but

ocaml.exe pkg/pkg.ml build --pkg-name topkg --dev-pkg false

fails with the error mentioned above (note the .exe part of the last command).

The issue seems to be that ocaml and ocaml.exe are not the same:

$ which ocaml
/cygdrive/c/Users/JACJ/AppData/Local/opam/ocaml-system/bin/ocaml

$ which ocaml.exe
/cygdrive/c/dev/XXX/bin/ocaml.exe

The ocaml stub in opam-system will add the OCAML_TOPLEVEL_PATH path as an include directory, where topfind can be found. Calling ocaml.exe directly will not add this include dir.

I am using a pre-installed Cygwin and have set up opam using:

opam init --bare --no-setup --no-git-location --cygwin-local-install --cygwin-location='c:\cygwin'

Copying /cygdrive/c/Users/JACJ/AppData/Local/opam/ocaml-system/bin/ocaml to /cygdrive/c/Users/JACJ/AppData/Local/opam/ocaml-system/bin/ocaml.exe seems to solve the issue, but I am not sure that is a valid solution?

Any thoughts? Thanks!

opam config report

 opam-version         2.2.0~beta2 (7445007c04e949590ece05786f88a40d82c463b1)
 self-upgrade         no
 system               arch=x86_64 os=win32 os-distribution=cygwin os-version=10.0.19041
 solver               builtin-mccs+glpk
 install-criteria     -removed,-count[avoid-version,changed],-count[version-lag,request],-count[version-lag,changed],-count[missing-depexts,changed],-changed
 upgrade-criteria     -removed,-count[avoid-version,changed],-count[version-lag,solution],-count[missing-depexts,changed],-new
 jobs                 7
 repositories         1 (http), 1 (local) (default repo at 76de4586)
 pinned               0
 current-switch       ocaml-system
 invariant            ocaml-system
 compiler-packages    ocaml-system.4.14.1+XXXXX
 ocaml:native         true
 ocaml:native-tools   true
 ocaml:native-dynlink true
 ocaml:stubsdir       /cygdrive/c/dev/XXX/lib
 ocaml:preinstalled   true
 ocaml:compiler       system
 ocaml-system:path    C:\dev\XXX\bin
kit-ty-kate commented 1 month ago

The default opam-repository does not support Windows yet (very soon though), i'm surprised you managed to install anything. Could you try again with the setup described on on discuss or our blog post ?

jacj-simcorp commented 1 month ago

Oh wow! I did not notice that because most things just worked. I have managed to install 56 packages so far without any major issues..

The "fix" with making a stub named ocaml.exe does not work, perhaps as expected. At least I assume this is the reason why I now see

Error:
CreateProcess(): This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.

for other packages.

Anyways, of course using the right repo is mandatory.. I will switch and update on this.

jacj-simcorp commented 1 month ago

Ok, I have now switched to git+https://github.com/dra27/opam-repository.git#windows-initial.

However, the issue remains:

#=== ERROR while compiling topkg.1.0.7 ========================================#
# context     2.2.0~beta2 | win32/x86_64 | ocaml-system.4.14.1+XXXXX | git+https://github.com/dra27/opam-repository.git#windows-initial
# path        C:\Users\JACJ\AppData\Local\opam\ocaml-system\.opam-switch\build\topkg.1.0.7
# command     C:\dev\XXX\bin\ocaml.exe pkg/pkg.ml build --pkg-name topkg --dev-pkg false
# exit-code   125
# env-file    C:\Users\JACJ\AppData\Local\opam\log\topkg-2724-2815ec.env
# output-file C:\Users\JACJ\AppData\Local\opam\log\topkg-2724-2815ec.out
### output ###
# Cannot find file topfind.

The issue is the same:

$ which ocaml.exe && echo '#use "topfind";;' | ocaml.exe -stdin
/cygdrive/c/dev/XXX/bin/ocaml.exe
Cannot find file topfind.

$ which ocaml && echo '#use "topfind";;' | ocaml -stdin
/cygdrive/c/Users/JACJ/AppData/Local/opam/ocaml-system/bin/ocaml
dbuenzli commented 1 month ago

The ocaml stub in opam-system will add the OCAML_TOPLEVEL_PATH path as an include directory, where topfind can be found.

The problem is that this environment variable does nothing. See https://github.com/ocaml/opam-repository/issues/25819

jacj-simcorp commented 1 month ago

Aha! Thanks for the link. I can proceed by adding export OCAMLTOP_INCLUDE_PATH=$OCAML_TOPLEVEL_PATH after sourcing opam env.

dbuenzli commented 1 month ago

Just to make thing clear. I don't think this is what happens:

The ocaml stub in opam-system will add the OCAML_TOPLEVEL_PATH path as an include directory, where topfind can be found.

I guess this ocaml finds it simply because ocamlfind is installed in the switch and thus topfind is (also) installed in the ocaml library directory which this ocaml consults.

Calling ocaml.exe directly will not add this include dir.

That may be true, but if you want that to happen you need to adjust OCAMLTOP_INCLUDE_PATH.

jacj-simcorp commented 1 month ago

Just to make thing clear. I don't think this is what happens:

The ocaml stub in opam-system will add the OCAML_TOPLEVEL_PATH path as an include directory, where topfind can be found.

I guess this ocaml finds it simply because ocamlfind is installed in the switch and thus topfind is (also) installed in the ocaml library directory which this ocaml consults.

I think it is the addition of the include directory:

$ cat `which ocaml`
#!/bin/sh

BINDIR=$(dirname "$(command -v ocamlc)")
"$BINDIR/ocaml" -I "$OCAML_TOPLEVEL_PATH" "$@"

$ echo '#use "topfind";;' | ocaml.exe -I "$OCAML_TOPLEVEL_PATH" -stdin

At least it is sufficient to make ocaml.exe work.

I have manually set OCAMLTOP_INCLUDE_PATH and things are working fine now.

dbuenzli commented 1 month ago

Ah indeed, I though that this ocaml was a proper binary.