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;我也无法将那里使用的构建系统移植到沙丘上。 我也花了一段时间才意识到Base
和 Core
模块不是该语言的基本核心部分,而是第三方附加组件。这是一个非常不幸的命名决定,但是……就这样。哦,好吧。
@Linas 确实如此,特别是因为 OCaml 有一个名为“核心库”的内置库:ocaml.org/releases/4.13/htmlman/core.html。简街核心命名非常混乱。以上是关于OCaml 错误:所需模块“Core__Core_sys”不可用的主要内容,如果未能解决你的问题,请参考以下文章