如何用ocamlbuild编译一个jocaml文件并包含一个包?

时间:2015-10-21 12:36:27

标签: ocaml ocamlbuild

如何使用ocamlbuild工具编译需要cryptokit package(使用伴随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(带-pkg cryptokit)时可能会因为Cryptokit需要Unix而弹出此错误。 a.ml实际上可能是空的,但仍会重现错误。

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

通过顺序执行与ocamlbuild相同的命令(由-verbose 1显示),我得到了当我执行最后一个没有/.../unix.cmxa的命令时,没有更多的冲突,但加载了错误的Unix模块:它是来自ocaml而不是来自jocaml的那个,所以当我在a.ml中使用任何jocaml功能时它会完全崩溃:

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 stdlib(隐式包含在stdlib中)。

2 个答案:

答案 0 :(得分:1)

我不知道有ocamlbuild + JOcaml组合的活跃用户!好奇心,你会更多地谈谈你使用JOCaml + cryptokit的内容吗?

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

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

  • 您可以使用jocaml{c,opt}并教-use-ocamlfind使用ocamlfind而不是jocaml使用ocaml环境变量(请参阅OCAMLFIND_COMMANDS
  • 您可以完全避免使用man ocamlfind,而是将-use-ocamlfind作为命令行工具来获取cryptokit库的位置(ocamlfind)。然后你使用ocamlfind query cryptokit但是自己传递路径(使用-pkg cryptokit-lflags或修改-cflags配置文件)。

答案 1 :(得分:0)

按照gasche的建议阐述-use-ocamlfind选项,我得到了一个小的讨厌的黑客:从{{1}的"unix"字段中移除requires META包的文件。它的工作原理是因为默认情况下jocaml会将所有内容与cryptokitthreads联系起来(真正的解决办法就是禁用此行为,但这似乎要困难得多)。所以工作编译命令是:

unix

我认为可以将此概括为使用jocaml编译时使用ocamlbuild -use-ocamlfind -use-jocaml -pkg cryptokit a.mlunix的任何包。一个辅助问题是,是否可以使用threads_tags文件动态执行此操作(注意:如果需要移动此注释,请注释)。