如何使用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中)。
答案 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会将所有内容与cryptokit
和threads
联系起来(真正的解决办法就是禁用此行为,但这似乎要困难得多)。所以工作编译命令是:
unix
我认为可以将此概括为使用jocaml编译时使用ocamlbuild -use-ocamlfind -use-jocaml -pkg cryptokit a.ml
或unix
的任何包。一个辅助问题是,是否可以使用threads
或_tags
文件动态执行此操作(注意:如果需要移动此注释,请注释)。