奇怪的错误,我无法在 Windows 上构建 OCaml 程序
Bizare errors and I'm unable to build OCaml programs on Windows
我最近一直在尝试让 OCaml 工作,并且解释器工作正常,我只是无法用它构建本机可执行文件。这是我的程序:
let () = print_endline "Hello, World!"
现在如果我 运行 ocaml program.ml
我得到预期的输出 Hello, World!
。但是,如果我 运行 ocamlbuild program.native
我得到:
mkdir 'C:\Users\User\_build'
'''C:\Program Files\OCaml\bin/ocamldep.opt' -modules program.ml > program.ml.depends
Exception Sys_error("program.ml.depends: No such file or directory").
然而,如果我查看目录 C:\Users\User\
,我可以看到 program.ml.depends
存在。 运行 我又得到了:
SANITIZE: a total of 1 file that should probably not be in your source tree
has been found. A script shell file "C:\Users\User\_build/sanitize.sh"
is being created. Check this script and run it to remove unwanted files or
use other options (such as defining hygiene exceptions or using the
-no-hygiene option).
IMPORTANT: I cannot work with leftover compiled files.
ERROR: Leftover dependency files:
File program.ml.depends in . has suffix .ml.depends
Exiting due to hygiene violations.
所以它确实存在!?!?!?!内容为my_prog.ml:
。旁注,_build
目录包含文件:_digests、_log、program.ml 和 sanatize.sh。下面是我 运行 使用 -verbose 10:
命令时的输出
mkdir 'C:\Users\User\_build'
Doing sanity checks
include directories are: [ "." ]
==> program.native
====> program.cmx
======> program.mlpack
======> program.ml
program.ml exists in source dir -> import it
======> program.ml.depends
========> program.ml
program.ml already built
start rule ocaml dependencies ml (%=program )
dyndeps: {. .}
mid rule ocaml dependencies ml (%=program ): cache miss: a product is not in build dir (program.ml.depends)
'''C:\Program Files\OCaml\bin/ocamldep.opt' -modules program.ml > program.ml.depends
resource_changed: program.ml.depends
end rule ocaml dependencies ml (%=program )
======> program.cmi
========> program.mli
==========> program.mly
========> program.mlpack
program.mlpack already failed
========> program.ml
program.ml already built
========> program.ml.depends
program.ml.depends already built
start rule ocaml: ml -> cmo & cmi (%=program )
Exception Sys_error("program.ml.depends: No such file or directory").
如果我强迫它:
include directories are: [ "." ]
==> program.native
====> program.cmx
======> program.mlpack
======> program.ml
program.ml exists and up to date
======> program.ml.depends
program.ml.depends exists in source dir -> import it
======> program.cmi
========> program.mli
==========> program.mly
========> program.mlpack
program.mlpack already failed
========> program.ml
program.ml already built
========> program.ml.depends
program.ml.depends already built
start rule ocaml: ml -> cmo & cmi (%=program )
dyndeps: {. .}
mid rule ocaml: ml -> cmo & cmi (%=program ): cache miss: a product is not in build dir (program.cmo)
'''C:\Program Files\OCaml\bin/ocamlc.opt' -c -o program.cmo program.ml
resource_changed: program.cmo
resource_changed: program.cmi
end rule ocaml: ml -> cmo & cmi (%=program )
start rule ocaml: ml & cmi -> cmx & o (%=program )
dyndeps: {. .}
mid rule ocaml: ml & cmi -> cmx & o (%=program ): cache miss: a product is not in build dir (program.cmx)
'''C:\Program Files\OCaml\bin/ocamlopt.opt' -c -o program.cmx program.ml
resource_changed: program.cmx
resource_changed: program.o
end rule ocaml: ml & cmi -> cmx & o (%=program )
====> program.o
program.o already built
start rule ocaml: cmx* & o* -> native (%=program )
prepare_libs: "program.native" -> [ ]
caml_transitive_closure ~caml_obj_ext:"cmx" ~pack_mode:false
~used_libraries:[ ] [ "program.cmx" ]
packages: {. .}
dependency_map: {::}
used_files: {. program.cmx .}
open_packages: [ ]
lib_index: {::}
dependencies: {::}
caml_transitive_closure: [ "program.cmx" ] -> [ ]
Failure: Link list cannot be empty.
我再次运行相同的命令:
include directories are: [ "." ]
==> program.native
====> program.cmx
program.cmx exists in source dir -> import it
====> program.o
program.o exists in source dir -> import it
start rule ocaml: cmx* & o* -> native (%=program )
prepare_libs: "program.native" -> [ ]
caml_transitive_closure ~caml_obj_ext:"cmx" ~pack_mode:false
~used_libraries:[ ] [ "program.cmx" ]
packages: {. .}
dependency_map: {::}
used_files: {. program.cmx .}
open_packages: [ ]
lib_index: {::}
dependencies: {::}
caml_transitive_closure: [ "program.cmx" ] -> [ "program.cmx" ]
link: [ "program.cmx" ] -o program.native
dyndeps: {. .}
mid rule ocaml: cmx* & o* -> native (%=program ): cache miss: a product is not in build dir (program.native)
'''C:\Program Files\OCaml\bin/ocamlopt.opt' program.cmx -o program.native
resource_changed: program.native
end rule ocaml: cmx* & o* -> native (%=program )
此时我确实得到了一个 program.native 文件,但是它不起作用,当我在文本编辑器中打开它时,它以 !<symlink>
开头。使用 readlink
后,它指向不存在的 _build/program.native
。在这一点上,我很困惑,不知道下一步该去哪里。令人遗憾的是,让这种编程语言发挥作用是如此困难。
我宁愿不必双重 boot/install 虚拟机来编译 OCaml。
最后一件事,我将如何安装 OPAM?
1) 不要将 OCaml 安装到包含白色 space 字符(如 'C:\Program Files...')、非 ascii 字符或其他特殊字符如 '~#?... ').您的构建路径也不应包含此类字符。它迟早会导致问题,因为所有常见的构建工具要么依赖于 cygwin(因此依赖 unix 约定),要么太愚蠢而无法正确引用。 (此外,您的构建路径看起来可疑。'C:\Users\User' 通常包含许多与您的项目无关的其他文件。将您的文件放在专用文件夹中。)
2) 如果要编译为本机代码,$PATH 中必须存在 C 工具链(mingw-w64 或 msvc)。
3) 您可以使用我为 cygwin 和 mingw-w64 编译器定制的 opam 和 OCaml 构建:https://github.com/fdopen/opam-repository-mingw。它工作得很好,如果满足要求(安装所有必要的 cygwin 包,在你的 username/build 路径中没有 white-spaces,在你的 $PATH 中没有替代的 OCaml 安装)
我最近一直在尝试让 OCaml 工作,并且解释器工作正常,我只是无法用它构建本机可执行文件。这是我的程序:
let () = print_endline "Hello, World!"
现在如果我 运行 ocaml program.ml
我得到预期的输出 Hello, World!
。但是,如果我 运行 ocamlbuild program.native
我得到:
mkdir 'C:\Users\User\_build'
'''C:\Program Files\OCaml\bin/ocamldep.opt' -modules program.ml > program.ml.depends
Exception Sys_error("program.ml.depends: No such file or directory").
然而,如果我查看目录 C:\Users\User\
,我可以看到 program.ml.depends
存在。 运行 我又得到了:
SANITIZE: a total of 1 file that should probably not be in your source tree
has been found. A script shell file "C:\Users\User\_build/sanitize.sh"
is being created. Check this script and run it to remove unwanted files or
use other options (such as defining hygiene exceptions or using the
-no-hygiene option).
IMPORTANT: I cannot work with leftover compiled files.
ERROR: Leftover dependency files:
File program.ml.depends in . has suffix .ml.depends
Exiting due to hygiene violations.
所以它确实存在!?!?!?!内容为my_prog.ml:
。旁注,_build
目录包含文件:_digests、_log、program.ml 和 sanatize.sh。下面是我 运行 使用 -verbose 10:
mkdir 'C:\Users\User\_build'
Doing sanity checks
include directories are: [ "." ]
==> program.native
====> program.cmx
======> program.mlpack
======> program.ml
program.ml exists in source dir -> import it
======> program.ml.depends
========> program.ml
program.ml already built
start rule ocaml dependencies ml (%=program )
dyndeps: {. .}
mid rule ocaml dependencies ml (%=program ): cache miss: a product is not in build dir (program.ml.depends)
'''C:\Program Files\OCaml\bin/ocamldep.opt' -modules program.ml > program.ml.depends
resource_changed: program.ml.depends
end rule ocaml dependencies ml (%=program )
======> program.cmi
========> program.mli
==========> program.mly
========> program.mlpack
program.mlpack already failed
========> program.ml
program.ml already built
========> program.ml.depends
program.ml.depends already built
start rule ocaml: ml -> cmo & cmi (%=program )
Exception Sys_error("program.ml.depends: No such file or directory").
如果我强迫它:
include directories are: [ "." ]
==> program.native
====> program.cmx
======> program.mlpack
======> program.ml
program.ml exists and up to date
======> program.ml.depends
program.ml.depends exists in source dir -> import it
======> program.cmi
========> program.mli
==========> program.mly
========> program.mlpack
program.mlpack already failed
========> program.ml
program.ml already built
========> program.ml.depends
program.ml.depends already built
start rule ocaml: ml -> cmo & cmi (%=program )
dyndeps: {. .}
mid rule ocaml: ml -> cmo & cmi (%=program ): cache miss: a product is not in build dir (program.cmo)
'''C:\Program Files\OCaml\bin/ocamlc.opt' -c -o program.cmo program.ml
resource_changed: program.cmo
resource_changed: program.cmi
end rule ocaml: ml -> cmo & cmi (%=program )
start rule ocaml: ml & cmi -> cmx & o (%=program )
dyndeps: {. .}
mid rule ocaml: ml & cmi -> cmx & o (%=program ): cache miss: a product is not in build dir (program.cmx)
'''C:\Program Files\OCaml\bin/ocamlopt.opt' -c -o program.cmx program.ml
resource_changed: program.cmx
resource_changed: program.o
end rule ocaml: ml & cmi -> cmx & o (%=program )
====> program.o
program.o already built
start rule ocaml: cmx* & o* -> native (%=program )
prepare_libs: "program.native" -> [ ]
caml_transitive_closure ~caml_obj_ext:"cmx" ~pack_mode:false
~used_libraries:[ ] [ "program.cmx" ]
packages: {. .}
dependency_map: {::}
used_files: {. program.cmx .}
open_packages: [ ]
lib_index: {::}
dependencies: {::}
caml_transitive_closure: [ "program.cmx" ] -> [ ]
Failure: Link list cannot be empty.
我再次运行相同的命令:
include directories are: [ "." ]
==> program.native
====> program.cmx
program.cmx exists in source dir -> import it
====> program.o
program.o exists in source dir -> import it
start rule ocaml: cmx* & o* -> native (%=program )
prepare_libs: "program.native" -> [ ]
caml_transitive_closure ~caml_obj_ext:"cmx" ~pack_mode:false
~used_libraries:[ ] [ "program.cmx" ]
packages: {. .}
dependency_map: {::}
used_files: {. program.cmx .}
open_packages: [ ]
lib_index: {::}
dependencies: {::}
caml_transitive_closure: [ "program.cmx" ] -> [ "program.cmx" ]
link: [ "program.cmx" ] -o program.native
dyndeps: {. .}
mid rule ocaml: cmx* & o* -> native (%=program ): cache miss: a product is not in build dir (program.native)
'''C:\Program Files\OCaml\bin/ocamlopt.opt' program.cmx -o program.native
resource_changed: program.native
end rule ocaml: cmx* & o* -> native (%=program )
此时我确实得到了一个 program.native 文件,但是它不起作用,当我在文本编辑器中打开它时,它以 !<symlink>
开头。使用 readlink
后,它指向不存在的 _build/program.native
。在这一点上,我很困惑,不知道下一步该去哪里。令人遗憾的是,让这种编程语言发挥作用是如此困难。
我宁愿不必双重 boot/install 虚拟机来编译 OCaml。
最后一件事,我将如何安装 OPAM?
1) 不要将 OCaml 安装到包含白色 space 字符(如 'C:\Program Files...')、非 ascii 字符或其他特殊字符如 '~#?... ').您的构建路径也不应包含此类字符。它迟早会导致问题,因为所有常见的构建工具要么依赖于 cygwin(因此依赖 unix 约定),要么太愚蠢而无法正确引用。 (此外,您的构建路径看起来可疑。'C:\Users\User' 通常包含许多与您的项目无关的其他文件。将您的文件放在专用文件夹中。)
2) 如果要编译为本机代码,$PATH 中必须存在 C 工具链(mingw-w64 或 msvc)。
3) 您可以使用我为 cygwin 和 mingw-w64 编译器定制的 opam 和 OCaml 构建:https://github.com/fdopen/opam-repository-mingw。它工作得很好,如果满足要求(安装所有必要的 cygwin 包,在你的 username/build 路径中没有 white-spaces,在你的 $PATH 中没有替代的 OCaml 安装)