OCaml 错误:所需模块“Core__Core_sys”不可用

Posted

技术标签:

【中文标题】OCaml 错误:所需模块“Core__Core_sys”不可用【英文标题】:OCaml Error: Required module `Core__Core_sys' is unavailable 【发布时间】:2022-01-10 19:23:15 【问题描述】:

我在链接一个非常简单的 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 文档已经过时两年多了!如何获得最新的文档,最好是描述这类新手错误的文档?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

谢谢!接下来,在运行时,我得到了Failed to load plugin ... no implementation available for ...,我通过在构建命令中添加-linkall 解决了这个问题。 确实,如果您使用的插件依赖于所有已经加载的库模块,您需要添加-linkall【参考方案2】:

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

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

其次,您似乎正在尝试使用 Jane Street 的 Core 库,这是一个第三方包,旨在作为标准库的替代品。因此,它有自己的 OCaml 标准库的 Sys 模块版本,即 Core.Sys。关于您收到的警报,Core.Sys.argv 值实际上已被 Jane Street Core 弃用:https://ocaml.janestreet.com/ocaml-core/latest/doc/core/Core__/Core_sys/index.html#val-argv

get_argv() 的单个结果。此值已无限期弃用。保留它是为了兼容性...

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

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

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

关于文档已过期的注意事项:如果您能指出我们从哪里获得导致您出现这种混淆的说明,这将有所帮助。清理安装说明和更新文档需要付出很多努力,但不幸的是,那里有很多过时的入门指南。我在此答案顶部提供的“启动并运行”链接是最佳资源。

【讨论】:

叹息。我正在做一个推荐 4.09 的项目,我无法将它移植到更新的东西上。该项目似乎也非常大量地使用 Core,或者至少是 Core_kernel。最后,dune 不是一个选项:1/2 代码是 c++,1/3 是方案,1/6 是 python;我也无法将那里使用的构建系统移植到沙丘上。 我也花了一段时间才意识到 BaseCore 模块不是该语言的基本核心部分,而是第三方附加组件。这是一个非常不幸的命名决定,但是……就这样。哦,好吧。 @Linas 确实如此,特别是因为 OCaml 有一个名为“核心库”的内置库:ocaml.org/releases/4.13/htmlman/core.html。简街核心命名非常混乱。

以上是关于OCaml 错误:所需模块“Core__Core_sys”不可用的主要内容,如果未能解决你的问题,请参考以下文章

OCaml 图形错误未绑定模块 mac OSX

编译包含“打开 Findlib”的 Ocaml 文件时出现未绑定模块 Findlib 错误

ocaml,能够在值更改时触发编译错误

Ocaml 值与模块和签名中的参数化类型不匹配

为啥 OCaml 中的模块类型注释会导致此代码无法编译?

如何在 utop 中重新加载 OCaml 模块