0

如何使用 ocamlbuild 工具编译需要cryptokit 包(使用配套 ocaml 成功编译)的 jocaml 源文件?

当我执行命令时,ocamlbuild -pkg cryptokit -use-jocaml a.native我收到此错误:

Warning: tag "package" does not expect a parameter, but is used with parameter "cryptokit"¬
+ jocamlopt -I /prefix/lib/ocaml -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/unix.cmxa /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native¬
File "_none_", line 1:¬ 
Error: Files /prefix/lib/ocaml/unix.cmxa¬
       and /prefix/lib/ocaml/unix.cmxa¬
              both define a module named Unix¬
              Command exited with code 2.¬ 
              Compilation unsuccessful after building 4 targets (3 cached) in 00:00:00.

本质上,ocaml Unix 模块与自己发生冲突。仅当我包含 Cryptokit (with -pkg cryptokit) 时才会出现此错误,这可能是因为 Cryptokit 需要 Unix。a.ml实际上可以是空的并且仍然会重现错误。

我尝试添加-use-ocamlfind标志,但由于它也使用 ocamlfind 来获取编译器,因此它选择 ocaml 编译器而不是 jocaml 编译器。

-verbose 1通过按顺序执行与 ocamlbuild 相同的命令(/.../unix.cmxa由当我在以下位置使用任何 jocaml 功能时,它会完全崩溃a.ml

jocamlopt -I /prefix/lib/ocaml -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native

但是,当我也删除该-I /prefix/lib/ocaml部分时,它会成功编译:

jocamlopt -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native

总而言之,我通过手动执行最后一个命令的修改来让它工作,但我想让 ocamlbuild 工作。

我认为这个错误与 Cryptokit 需要 Unix 模块这一事实有关:当我用 ocaml 而不是 jocaml 编译它时,在链接阶段它试图与 ocaml stdlib 链接(需要包含)而不是jocaml 标准库之一(作为标准库的一部分隐式包含)。

4

2 回答 2

1

我不知道有 ocamlbuild+JOcaml 组合的活跃用户!出于好奇,您能多谈谈您使用 JCaml+cryptokit 的目的吗?

我对 Cryptokit 或 JCaml 了解不多,但看起来您的主要问题与 ocamlbuild 无关。如果我理解正确,(1)Cryptokit 需要 Unix,(2)JOCaml 需要使用它自己的 Unix 变体。如果这是正确的,针对 ocaml 的 Unix 编译 Cryptokit 并期望它在与本身需要 JOCaml 的 Unix 的 JCaml 程序链接时工作,这必然会产生很多麻烦。如果这在您的情况下有效,那一定是因为您使用的 Cryptokit 部分实际上不需要 Unix,或者您正在测试的 JCaml 程序实际上不需要 JCaml 的 Unix。从长远来看,最好直接使用 JCaml 编译 Cryptokit(我不知道您对 OCaml 生态系统的总体感觉如何,但我个人会尝试构建一个 OPAM 开关,其中ocaml{c,opt}是它的别名jocaml{c,opt}并从中构建程序)。

关于 ocamlbuild 的特定部分,如果没有 tarball 能够重现您的设置并进行试验,很难给出任何准确的建议。但我会尝试以下两个选项之一:

  • 您可以使用-use-ocamlfind和教ocamlfind使用,jocaml而不是ocaml使用OCAMLFIND_COMMANDS环境变量(请参阅 参考资料man ocamlfind
  • 您可以完全避免-use-ocamlfind,而是ocamlfind作为命令行工具调用来获取 cryptokit 库 ( ocamlfind query cryptokit) 的位置。然后,您将使用-pkg cryptokit但自己传递路径(使用-lflags-cflags或通过修改myocamlbuild.ml配置文件)。
于 2015-10-29T14:48:54.547 回答
0

根据gasche的建议,我详细说明了这个-use-ocamlfind选项,我让它与一个小的讨厌的黑客一起工作:"unix"从包文件的requires字段中删除。它之所以有效,是因为 jocaml 将所有内容与默认情况下链接(真正的解决方案是禁用此行为,但似乎要困难得多)。所以工作编译命令是:METAcryptokitthreadsunix

ocamlbuild -use-ocamlfind -use-jocaml -pkg cryptokit a.ml

我认为可以将其推广到任何使用jocamlunixthreads在使用 jocaml 编译时使用的包。一个附属问题是是否可以使用_tagsormyocamlbuild.ml文件动态执行此操作(注意:如果需要移动此注释,请注释)。

于 2015-10-30T16:50:55.050 回答