OCaml Error: Required module `Core__Core_sys' is unavailable

OCaml Error: Required module `Core__Core_sys' is unavailable

我在链接一个非常简单的 OCaml 程序时遇到问题:

open Core

Format.printf "hello world %s\n"  "foobar";;
Format.printf "argv= %s\n" (Sys.get_argv()).(0) ;;

我用

编译
ocamlfind ocamlc -thread -package core visitor.ml

编译步骤总是产生错误:

Error: Required module `Core__Core_sys' is unavailable

我已固定版本 4.0.9,我可以看到文件:

$ ocamlfind query core
/home/ubuntu/.opam/4.09.0/lib/core

$ ls -la /home/ubuntu/.opam/4.09.0/lib/core显示

-rw-r--r--   1 ubuntu ubuntu    17891 Dec  3 20:14 core__Core_sys.cmi
-rw-r--r--   1 ubuntu ubuntu    93777 Dec  3 20:14 core__Core_sys.cmt
-rw-r--r--   1 ubuntu ubuntu    75659 Dec  3 20:14 core__Core_sys.cmti
-rw-r--r--   1 ubuntu ubuntu    16958 Dec  3 20:14 core__Core_sys.cmx

我已经尝试了所有我能想到的方法,但没有成功。顺便说一句,我注意到文档 https://ocaml.org/api/Sys.html 根本没有提到 get_argv 但如果我尝试简单 Sys.argv 我会收到警告:

# Sys.argv ;;
Alert deprecated: Core.Sys.argv
[since 2019-08] Use [Sys.get_argv] instead, which has the correct behavior when [caml_sys_modify_argv] is called.

所以我得出结论,在 ocaml.org 上发布的核心 OCaml 文档已经过时两年多了!如何获得最新的文档,最好是描述这些新手错误的文档?

几点。首先,看起来您使用的是相当旧的 OCaml 版本。除非出于某种原因需要继续使用 4.09,否则我强烈建议升级到最新版本 4.13.1。安装说明在这里:https://ocaml.org/learn/tutorials/up_and_running.html

如果您遇到任何问题,请尝试升级到最新版本的 opam(OCaml 包管理器)并执行 opam update 下载最新的包索引。

其次,您似乎正在尝试使用 Jane Street 的 Core library, which is a third-party package which is intended as a standard library replacement. As such, it has its own version of the OCaml standard library's Sys module, i.e. Core.Sys. Regarding the alert that you are getting, the Core.Sys.argv value is actually deprecated by Jane Street Core: https://ocaml.janestreet.com/ocaml-core/latest/doc/core/Core__/Core_sys/index.html#val-argv

A single result from get_argv (). This value is indefinitely deprecated. It is kept for compatibility...

这导致我们遇到最后一个问题,当您尝试编译时无法找到 core 包。这里有几个选择。首先,一个选项是 core 包和标准库替换实际上是可选的;您可能实际上不需要它们。如果您是 OCaml 初学者,您可以尝试只使用标准库(所以不要 open Core,不要尝试使用 core 包进行编译)。

如果您决定继续使用 core 包,另一种选择是 dune build system 而不是 ocamlfind。 Dune 是一个功能强大的现代 OCaml 构建系统,可以在构建过程中处理包 linking 的几乎所有方面,因此您无需担心发出单独的编译命令。

dune 文件如下所示:

(executable
  (name visitor)
  (libraries core))

并且 visitor.ml 文件将位于同一目录中:

let () =
  Printf.printf "hello world %s\n" "foobar";
  Printf.printf "argv= %s\n" Sys.argv.(0)

那么你会 运行:

dune exec ./visitor.exe

.exe 是沙丘约定,跨操作系统的可执行文件被赋予此扩展名。

最后,在源代码中您实际上不需要 ;;。更多相关信息:https://discuss.ocaml.org/t/terminate-a-line-with-or-or-in-or-nothing/8941/21?u=yawaramin

关于文档已过时的注意事项:如果您能指出我们从哪里获得导致您出现这种困惑的说明,将会有所帮助。人们付出了很多努力来清理安装说明和使文档现代化,但不幸的是,那里有很多过时的入门指南。我在此答案顶部提供的 'Up and Running' link 是最好的资源。

您需要通过添加 -linkpkg 标志来 link 包:

ocamlfind ocamlc -thread -package core -linkpkg visitor.ml