opam icon indicating copy to clipboard operation
opam copied to clipboard

Opam fails to install in directory with spaces in the name.

Open ddickstein opened this issue 2 years ago • 13 comments

[ERROR] The installation of ocaml-base-compiler failed at "make install".
-> installed ocaml-options-vanilla.1

#=== ERROR while installing ocaml-base-compiler.4.14.1 ========================#
# context     2.0.5 | linux/x86_64 |  | [https://opam.ocaml.org#f473da85](https://opam.ocaml.org/#f473da85)
# path        ~/directory with spaces/project-name/_opam/.opam-switch/build/ocaml-base-compiler.4.14.1
# command     ~/.opam/opam-init/hooks/sandbox.sh install make install
# exit-code   2
# env-file    ~/.opam/log/ocaml-base-compiler-957096-d2d111.env
# output-file ~/.opam/log/ocaml-base-compiler-957096-d2d111.out
### output ###
# [...]
# fi
# /usr/bin/install -c -p -m 644 \
#   eventlog_metadata \
#   "/path/to/directory with spaces/project-name/_opam/lib/ocaml"
# make[1]: Leaving directory '/path/to/directory with spaces/project-name/_opam/.opam-switch/build/ocaml-base-compiler.4.14.1/tools'
# make -C man install
# make[1]: Entering directory '/path/to/directory with spaces/project-name/_opam/.opam-switch/build/ocaml-base-compiler.4.14.1/man'
# mkdir -p /path/to/directory with spaces/project-name/_opam/man/man1
# mkdir: cannot create directory '/path/to/directory': Read-only file system
# make[1]: *** [Makefile:25: install] Error 1
# make[1]: Leaving directory '/path/to/directory with spaces/project-name/_opam/.opam-switch/build/ocaml-base-compiler.4.14.1/man'
# make: *** [Makefile:401: install] Error 2



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+- The following actions failed
| - install ocaml-base-compiler 4.14.1
+-
+- The following changes have been performed (the rest was aborted)
| - install base-bigarray         base
| - install base-threads          base
| - install base-unix             base
| - install ocaml-options-vanilla 1
+-

The error "cannot create directory '/path/to/directory': Read-only file system" makes no sense - the file system is not read-only, and "directory" is not the name of this directory (it should be "directory with spaces"). I can confirm that instead using directory-with-hyphens makes this succeed.

ddickstein avatar Sep 19 '23 14:09 ddickstein

Could you try with the latest version of opam (2.1.5)? And if it doesn't work could you try with the latest alpha for opam 2.2?

To install opam 2.1.5:

bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"

to install opam 2.2.0~alpha2:

bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) --dev"

opam 2.0.5 is fairly old (4 years old) and based on a 5 years old branch so bugs that have been fixed since is to be expected.

kit-ty-kate avatar Sep 19 '23 15:09 kit-ty-kate

note from & for opam dev team: it is at least working in opam 2.2~alpha, as a reftest succeed switch creation and installing a package in a path with spaces.

rjbou avatar Sep 19 '23 16:09 rjbou

On Linux, even with opam 2.2~alpha2, I get an error

/tmp/dir with spaces% opam switch create toto --packages ocaml.4.14.1 --jobs=1

<><> Installing new switch packages <><><><><><><><><><><><><><><><><><><><><><>
Switch invariant: ["ocaml" {= "4.14.1"}]

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base
∗ installed ocaml-options-vanilla.1
⬇ retrieved ocaml-base-compiler.4.14.1  (https://opam.ocaml.org/cache)
[ERROR] The installation of ocaml-base-compiler failed at "make install".

#=== ERROR while installing ocaml-base-compiler.4.14.1 ========================#
# context     2.2.0~alpha2 | linux/x86_64 |  | https://opam.ocaml.org#f921ce76
# path        /tmp/dir with spaces/opam/toto/.opam-switch/build/ocaml-base-compiler.4.14.1
# command     /tmp/dir with spaces/opam/opam-init/hooks/sandbox.sh install make install
# exit-code   2
# env-file    /tmp/dir with spaces/opam/log/ocaml-base-compiler-71689-b28f1b.env
# output-file /tmp/dir with spaces/opam/log/ocaml-base-compiler-71689-b28f1b.out
### output ###
# [...]
# fi
# /usr/bin/install -c -p -m 644 \
#   eventlog_metadata \
#   "/tmp/dir with spaces/opam/toto/lib/ocaml"
# make[1] : on quitte le répertoire « /tmp/dir with spaces/opam/toto/.opam-switch/build/ocaml-base-compiler.4.14.1/tools »
# make -C man install
# make[1] : on entre dans le répertoire « /tmp/dir with spaces/opam/toto/.opam-switch/build/ocaml-base-compiler.4.14.1/man »
# mkdir -p /tmp/dir with spaces/opam/toto/man/man1
# mkdir: impossible de créer le répertoire « /tmp/dir »: Système de fichiers accessible en lecture seulement
# make[1]: *** [Makefile:25 : install] Erreur 1
# make[1] : on quitte le répertoire « /tmp/dir with spaces/opam/toto/.opam-switch/build/ocaml-base-compiler.4.14.1/man »
# make: *** [Makefile:401 : install] Erreur 2



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
┌─ The following actions failed
│ ∗ install ocaml-base-compiler 4.14.1
└─ 
┌─ The following changes have been performed (the rest was aborted)
│ ∗ install base-bigarray         base
│ ∗ install base-threads          base
│ ∗ install base-unix             base
│ ∗ install ocaml-options-vanilla 1
└─ 
Switch initialisation failed: clean up? ('n' will leave the switch partially installed) [y/n]

with echo $OPAMROOT showing /tmp/dir with spaces/opam

eponier avatar Oct 06 '23 20:10 eponier

Sorry I’m not sure why I didn’t remember this on my first read of the issue, but this is happening because OCaml doesn’t support spaces in the prefix.

This was fixed in 5.1.0 and was backported in the 4.14 and 5.0 branches so it should be fixed once 4.14.2 and 5.0.1 are released. See https://github.com/ocaml/ocaml/pull/11590 cc @octachron

Closing since it is not an issue in opam, sorry I hadn’t realized sooner.

kit-ty-kate avatar Oct 09 '23 16:10 kit-ty-kate

I'm facing the same kind of error with opam 2.2.0~alpha2 and ocaml 5.1.0. The message is different. So I wonder if the problem is opam or ocaml?

with bwrap

/tmp/my folder with spaces$ opam sw create . 5.1.0

<><> Installing new switch packages <><><><><><><><><><><><><><><><><><><><><><>
Switch invariant: ["ocaml-base-compiler" {= "5.1.0"} | "ocaml-system" {= "5.1.0"}]

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base
∗ installed ocaml-options-vanilla.1
⬇ retrieved ocaml-base-compiler.5.1.0  (cached)
∗ installed ocaml-base-compiler.5.1.0
∗ installed ocaml-config.3
[ERROR] The compilation of ocaml.5.1.0 failed at "ocaml /tmp/my folder with spaces/_opam/share/ocaml-config/gen_ocaml_config.ml 5.1.0 ocaml".

#=== ERROR while compiling ocaml.5.1.0 ========================================#
# context     2.2.0~alpha2 | linux/x86_64 | ocaml-base-compiler.5.1.0 | https://opam.ocaml.org#ad6e2e17
# path        /tmp/my folder with spaces/_opam/.opam-switch/build/ocaml.5.1.0
# command     ~/.opam/opam-init/hooks/sandbox.sh build ocaml /tmp/my folder with spaces/_opam/share/ocaml-config/gen_ocaml_config.ml 5.1.0 ocaml
# exit-code   1
# env-file    ~/.opam/log/ocaml-2141670-5e79cc.env
# output-file ~/.opam/log/ocaml-2141670-5e79cc.out
### output ###
# bwrap: execvp ocaml: No such file or directory



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
┌─ The following actions failed
│ λ build ocaml 5.1.0
└─ 
┌─ The following changes have been performed (the rest was aborted)
│ ∗ install base-bigarray         base
│ ∗ install base-threads          base
│ ∗ install base-unix             base
│ ∗ install ocaml-base-compiler   5.1.0
│ ∗ install ocaml-config          3
│ ∗ install ocaml-options-vanilla 1
└─ 
Switch initialisation failed: clean up? ('n' will leave the switch partially installed) [y/n] y

Without bwrap

/tmp/my folder with spaces$ opam sw create . 5.1.0

<><> Installing new switch packages <><><><><><><><><><><><><><><><><><><><><><>
Switch invariant: ["ocaml-base-compiler" {= "5.1.0"} | "ocaml-system" {= "5.1.0"}]

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base
∗ installed ocaml-options-vanilla.1
⬇ retrieved ocaml-base-compiler.5.1.0  (cached)
∗ installed ocaml-base-compiler.5.1.0
∗ installed ocaml-config.3
[ERROR] Actions cancelled because of a system error:
/home/me/bin/opam-2.2.0-alpha2-x86_64-linux: "create_process" failed on /tmp/my folder with spaces/_opam/bin/ocaml: No such file or directory
Switch initialisation failed: clean up? ('n' will leave the switch partially installed) [y/n] y
Fatal error:
/home/me/bin/opam-2.2.0-alpha2-x86_64-linux: "create_process" failed on /tmp/my folder with spaces/_opam/bin/ocaml: No such file or directory

Khady avatar Oct 31 '23 08:10 Khady

@Khady if you don’t clean up the switch and look into what’s in /tmp/my folder with spaces/_opam/bin/, what do you have? (if possible using ls -l to see if the executables are correctly flagged)

kit-ty-kate avatar Oct 31 '23 14:10 kit-ty-kate

nevermind I was able to reproduce locally. I’ll reopen this

kit-ty-kate avatar Oct 31 '23 14:10 kit-ty-kate

for the record

/tmp/my folder with spaces$ ls -l "/tmp/my folder with spaces/_opam/bin/" 
total 149316
-rwxr-xr-x 1 me me 21870417 Oct 31 14:47 ocaml
lrwxrwxrwx 1 me me       10 Oct 31 14:48 ocamlc -> ocamlc.opt
-rwxr-xr-x 1 me me  3058815 Oct 31 14:48 ocamlc.byte
-rwxr-xr-x 1 me me 16336944 Oct 31 14:48 ocamlc.opt
-rwxr-xr-x 1 me me  2965864 Oct 31 14:47 ocamlcmt
-rwxr-xr-x 1 me me   625502 Oct 31 14:47 ocamlcp
-rwxr-xr-x 1 me me  3696517 Oct 31 14:48 ocamldebug
lrwxrwxrwx 1 me me       12 Oct 31 14:48 ocamldep -> ocamldep.opt
-rwxr-xr-x 1 me me  2960307 Oct 31 14:47 ocamldep.byte
-rwxr-xr-x 1 me me 15938352 Oct 31 14:48 ocamldep.opt
-rwxr-xr-x 1 me me  4196184 Oct 31 14:48 ocamldoc
-rwxr-xr-x 1 me me 22827232 Oct 31 14:48 ocamldoc.opt
lrwxrwxrwx 1 me me       12 Oct 31 14:48 ocamllex -> ocamllex.opt
-rwxr-xr-x 1 me me   394072 Oct 31 14:47 ocamllex.byte
-rwxr-xr-x 1 me me  3804704 Oct 31 14:48 ocamllex.opt
-rwxr-xr-x 1 me me   376608 Oct 31 14:47 ocamlmklib
-rwxr-xr-x 1 me me   426302 Oct 31 14:47 ocamlmktop
lrwxrwxrwx 1 me me       16 Oct 31 14:48 ocamlobjinfo -> ocamlobjinfo.opt
-rwxr-xr-x 1 me me  3160235 Oct 31 14:47 ocamlobjinfo.byte
-rwxr-xr-x 1 me me 17116480 Oct 31 14:48 ocamlobjinfo.opt
lrwxrwxrwx 1 me me       12 Oct 31 14:48 ocamlopt -> ocamlopt.opt
-rwxr-xr-x 1 me me  4003041 Oct 31 14:48 ocamlopt.byte
-rwxr-xr-x 1 me me 20982296 Oct 31 14:48 ocamlopt.opt
-rwxr-xr-x 1 me me   626658 Oct 31 14:47 ocamloptp
-rwxr-xr-x 1 me me  1053426 Oct 31 14:47 ocamlprof
-rwxr-xr-x 1 me me  1973984 Oct 31 14:47 ocamlrun
-rwxr-xr-x 1 me me  2197584 Oct 31 14:47 ocamlrund
-rwxr-xr-x 1 me me  1973696 Oct 31 14:47 ocamlruni
-rwxr-xr-x 1 me me   287288 Oct 31 14:47 ocamlyacc

I couldn't find where the full logs are, but # command ~/.opam/opam-init/hooks/sandbox.sh build ocaml /tmp/my folder with spaces/_opam/share/ocaml-config/gen_ocaml_config.ml 5.1.0 ocaml is a bit fishy, as if it was missing some quoting

Khady avatar Oct 31 '23 14:10 Khady

Mmmh, this seems to be a fondamental issue with the way executables are read in Unix systems...

The directory shows ocaml well installed and everything but trying to start the interpreter leads to the following error:

./_opam/bin/ocaml
zsh: ./_opam/bin/ocaml: bad interpreter: /private/tmp/my: no such file or directory

The first line of the ocaml executable is the following:

#!/private/tmp/my folder with spaces/_opam/bin/ocamlrun

However according to https://lists.gnu.org/archive/html/bug-bash/2008-05/msg00052.html it is not possible to have a path with spaces in it :/

kit-ty-kate avatar Oct 31 '23 14:10 kit-ty-kate

Right, so I suppose that opam is innocent and this issue should be reported to ocaml/ocaml. Thanks for your help!

Khady avatar Oct 31 '23 15:10 Khady

I’m hearing in my earpiece that the relocatable compiler work might fix this issue whenever it lends in the compiler. But it’s definitely worth opening a new issue in ocaml/ocaml to track this.

I’ll keep this issue opened until the proper fix lends.

kit-ty-kate avatar Oct 31 '23 15:10 kit-ty-kate

ok, investigating this a little bit more before to open an issue on ocaml/ocaml, I realized the problem could/should be fixed in https://github.com/ocaml/opam-repository/blob/7b4cedddee88c79d6bdb00eccf7b36a7b617b211/packages/ocaml/ocaml.5.1.0/opam#L20, and opam show ocaml points to https://github.com/ocaml/opam-repository, but I wonder if it's better to talk there or here.

It is possible to launch the ocaml binary with ocamlrun instead of relying on the shebang:

sg:/tmp/my folder with spaces$ _opam/bin/ocamlrun _opam/bin/ocaml _opam/.opam-switch/build/ocaml-config.3/gen_ocaml_config.ml 5.1.0 ocaml
sg:/tmp/my folder with spaces$ ls
_opam  ocaml.config  where
sg:/tmp/my folder with spaces$ cat ocaml.config 
opam-version: "2.0"
variables {
  native: true
  native-tools: true
  native-dynlink: true
  stubsdir: "/tmp/my folder with spaces/_opam/lib/ocaml/stublibs:/tmp/my folder with spaces/_opam/lib/ocaml"
  preinstalled: false
  compiler: "5.1.0"
}
sg:/tmp/my folder with spaces$ cat where
/tmp/my folder with spaces/_opam/lib/ocaml

So I wonder if the build instruction of ocaml should be changed from

build: ["ocaml" "%{ocaml-config:share}%/gen_ocaml_config.ml" _:version _:name]

To something like

build: ["ocamlrun" "%{bin}/ocaml" "%{ocaml-config:share}%/gen_ocaml_config.ml" _:version _:name]

Khady avatar Nov 01 '23 04:11 Khady

It’s indeed possible but the problem is that the ocaml package is not the only place where a bytecode binary is called. For example on platforms that do not have native backend support, all ocaml programs have this issue. So you would be able to install the compiler but any other packages would still have to be patched and that’s simply too much work. Especially for an issue that is going to be fixed hopefully soon-ish ^^

kit-ty-kate avatar Nov 01 '23 12:11 kit-ty-kate

I can confirm that opam itself works fine with spaces and that ocaml will support spaces as part of Relocatable OCaml:

$ cd /tmp
$ mkdir "dir with spaces"
$ cd "dir with spaces"
$ opam switch create --empty --repos=reloc,default .
$ opam install ocaml-base-compiler
[...]
$ ocamlc -where
/tmp/dir with spaces/_opam/lib/ocaml
$ which ocaml
/tmp/dir with spaces/_opam/bin/ocaml
$ ocaml test.ml
Hello World

kit-ty-kate avatar Sep 15 '25 14:09 kit-ty-kate