并行安装不同的ocaml版本
我正在尝试编译 adder xml-rpc-light ocaml 包的示例。在包含(我怀疑所有)必要的库后,我在编译时收到此错误:
File "_none_", line 1, characters 0-1:
Error: Files /[...]/godi/lib/ocaml/site-lib/xmlrpc-light/xmlrpc-light.cma(XmlRpcBase64)
and /[...]/godi/lib/ocaml/std-lib/stdlib.cma(Buffer)
make inconsistent assumptions over interface Buffer
Command exited with code 2.
我明白它的含义。基本上,不知何故,xmlrpc-light.cma 和 stdlib.cma 不假定相同的 Buffer 接口,这会在编译时出现类型错误。但是如何在不更改这些库的代码的情况下协调它们呢?
在 Ygrek 和 Gasche 的答案后进行编辑
从这两个答案中,我想我知道现在的问题是什么,但我不太确定如何处理它。我使用 GODI,所有内容通常都在那里编译(3.11.2 版本)。最近,我独立安装了 OCaml 3.12 只是为了玩玩它。现在,如果我进入新的命令行并编写 ocaml
,启动的就是这个新的 3.12。目前,在 GODI 中,一切仍然照常工作(或几乎 - 见下文),但如果我想安装一些非 GODI 库(如 xmlrpc-light),我必须使用命令行。如果我尝试使用 make
编译 xmlrpc-light,我得到:
ocamlfind ocamlc -package xml-light,netclient,nethttpd-for-netcgi2 -c XmlRpc.mli
File "XmlRpc.mli", line 1, characters 0-1:
Error: /[...]/godi/lib/ocaml/pkg-lib/xml-light/xml.cmi
is not a compiled interface
make[1]: *** [XmlRpc.cmi] Error 2
make: *** [native-code-library] Error 2
尽管事实上命令行中可用的 ocaml 是非 GODI 3.12,但它在这里查找 GODI 库的原因是ocamlfind
实际上调用了 /[...]/godi/bin/ocamlfind
。我可以理解为什么 3.12 ocaml 抱怨 xml.cmi 不是编译接口(它是用 GODI - 3.11.2 编译的)。
所以,总而言之,我的系统目前一团糟。我不知道如何保留两个 ocaml 环境(GODI 和 3.12)并每次选择我想使用哪一个。但如果 3.12 能解决我所有的问题,我很乐意删除它。
GODI 的问题
只是为了提供更多信息,我最近尝试添加 godi-ocaml-xml-rpc
库(因为它是一个替代的 xml-rpc 库并且在 GODI 中可用),但是我
> ocamlfind ocamlopt -a -o xmlrpc.cmxa \
> -predicates "" xmlRPCTypes.cmx xmlRPCDtd.cmx xmlRPCNet.cmx xmlRPCClient.cmx xmlRPCServer.cmx cgiSource.cmx
> ocamlfind ocamlopt -o oxridl.opt -package "pcre annexlib" -linkpkg oxridl.ml
> cd /[...]/godi/build/godi/godi-ocaml-xml-rpc/work/ocaml-xml-rpc-0.2.6/httpd && make && make opt
> ocamlfind ocamlc -c -I .. httpdSource.mli -package "http annexlib"
> File "httpdSource.mli", line 1, characters 0-1:
> Error: ../xmlRPCServer.cmi
> is not a compiled interface
> make[7]: *** [httpdSource.cmi] Error 2
> Error: Exec error: File /[...]/godi/build/godi/godi-ocaml-xml-rpc/./makefile, line 38: Command returned with non-zero exit code
> Error: Exec error: File /[...]/godi/build/godi/godi-ocaml-xml-rpc/./../../mk/bsd.pkg.mk, line 1378: Command returned with non-zero exit code
### Error: Command fails with code 1: godi_console
怀疑这可能与同样的问题有关。奇怪的是,它抱怨 xmlRPCServer.cmi
不是已编译的接口,而我认为它正是应该编译以安装 godi-ocaml-xml-rpc 的文件之一。
I'm attempting to compile the adder example of the xml-rpc-light ocaml package. After including (I suspect all) the necessary libraries I get this error at compilation:
File "_none_", line 1, characters 0-1:
Error: Files /[...]/godi/lib/ocaml/site-lib/xmlrpc-light/xmlrpc-light.cma(XmlRpcBase64)
and /[...]/godi/lib/ocaml/std-lib/stdlib.cma(Buffer)
make inconsistent assumptions over interface Buffer
Command exited with code 2.
I understand what it means. Basically, somehow, xmlrpc-light.cma and stdlib.cma don't assume the same Buffer interface and this gives a type error at compilation time. But how can I reconcile them without changing the code of these libraries?
Edit after Ygrek's and Gasche's answers
From both answers I think I know what the problem is now but I'm not really sure how to deal with it. I use GODI and everything usually compiles there (3.11.2 version). More recently, I installed OCaml 3.12 independently just to play with it. Now, if I go to a new command line and write ocaml
, it is this new 3.12 which starts up. Presently, within GODI everything still works as usual (or almost -- see below) but if I want to install some non-GODI library (like xmlrpc-light) I have to use the command line. If I try to compile xmlrpc-light using make
, I get:
ocamlfind ocamlc -package xml-light,netclient,nethttpd-for-netcgi2 -c XmlRpc.mli
File "XmlRpc.mli", line 1, characters 0-1:
Error: /[...]/godi/lib/ocaml/pkg-lib/xml-light/xml.cmi
is not a compiled interface
make[1]: *** [XmlRpc.cmi] Error 2
make: *** [native-code-library] Error 2
The reason why it is looking into GODI libraries here, despite the fact that the ocaml available at command line is the non-GODI 3.12, is that ocamlfind
actually calls /[...]/godi/bin/ocamlfind
. I can understand why 3.12 ocaml complaints about xml.cmi not being a compiled interface (it was compiled with GODI -- 3.11.2).
So, to sum up, my system is currently a mess. And I don't know how to keep the two ocaml environments (GODI and 3.12) and select each time which one I want to use. But I'm happy to remove 3.12 if it solves all my problems.
Problem with GODI
Just to give some more information, I've recently tried to add the godi-ocaml-xml-rpc
library (because it's an alternative xml-rpc library and it's available in GODI), but I get
> ocamlfind ocamlopt -a -o xmlrpc.cmxa \
> -predicates "" xmlRPCTypes.cmx xmlRPCDtd.cmx xmlRPCNet.cmx xmlRPCClient.cmx xmlRPCServer.cmx cgiSource.cmx
> ocamlfind ocamlopt -o oxridl.opt -package "pcre annexlib" -linkpkg oxridl.ml
> cd /[...]/godi/build/godi/godi-ocaml-xml-rpc/work/ocaml-xml-rpc-0.2.6/httpd && make && make opt
> ocamlfind ocamlc -c -I .. httpdSource.mli -package "http annexlib"
> File "httpdSource.mli", line 1, characters 0-1:
> Error: ../xmlRPCServer.cmi
> is not a compiled interface
> make[7]: *** [httpdSource.cmi] Error 2
> Error: Exec error: File /[...]/godi/build/godi/godi-ocaml-xml-rpc/./makefile, line 38: Command returned with non-zero exit code
> Error: Exec error: File /[...]/godi/build/godi/godi-ocaml-xml-rpc/./../../mk/bsd.pkg.mk, line 1378: Command returned with non-zero exit code
### Error: Command fails with code 1: godi_console
which I suspect could have to do with the same problem. The weird thing is that it's complaining about xmlRPCServer.cmi
not being a compiled interface when, I think, it is precisely one of the files it should be compiling to install godi-ocaml-xml-rpc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
确保您使用的是单一版本的 ocaml 编译器并重建 xmlrpc。
更新
简单的经验法则 - 为每个 ocaml 安装提供单独的 ocamlfind ,并确保在任何时间点 PATH 中都只有一个 ocaml + ocamlfind 。即,将 ocaml-3.12 安装到
/opt/ocaml-3.12
中,并将新的 ocamlfind 安装到/opt/ocaml-3.12/bin
中。然后,当您想使用 ocaml 3.12 时,只需使用 PATH=/opt/ocaml-3.12/bin:$PATH ,它就会选择 ocamlfind 和匹配的 ocaml,并且所有 ocamlfind 安装都将从系统 ocaml 中分离出来。旧的 ocaml 安装根本不会受到影响。(可以使用单个 ocamlfind 和许多 ocaml 安装,但这更复杂,我不会推荐它 - 无论如何 ocamlfind 构建得很快)。
Make sure that you are using the single version of ocaml compiler and rebuild xmlrpc.
UPDATE
Easy rule of thumb - have separate ocamlfind for each ocaml installation and make sure that only one ocaml + ocamlfind are in PATH at any point of time. i.e. install ocaml-3.12 into
/opt/ocaml-3.12
and install fresh ocamlfind into/opt/ocaml-3.12/bin
too. Then when you want to use ocaml 3.12 just usePATH=/opt/ocaml-3.12/bin:$PATH
and it will pick up ocamlfind and matching ocaml and all ocamlfind installations will be separated from system ocaml. The old ocaml install will not be affected at all.(One can go with single ocamlfind and many ocaml installs but that's more complicated and I wouldn't recommend it - ocamlfind builds quickly anyway).
要扩展一下 ygrek 答案:这可能意味着 xmlrpc-light 是针对不同版本的标准库(.. 与您系统上可用的版本)进行编译的。如果您在安装 xmlrpc-light 后重新安装了新的标准库,或者使用为不同系统编译的二进制 xmlrpc-light 包,则可能会出现这种情况。解决方案可能是根据当前的标准库重建 xmlrpc。
这些接口版本控制问题很微妙,因为它们与 C/C++ 接口决策中的惯例不符;在这些语言中,当包接口更改时,默认情况下假定与以前的接口兼容。在 OCaml 中,它们被假定为不兼容(它们比较整个模块接口的哈希值),并且必须重新编译。
大多数打包工具(例如 GNU/Linux 发行版)都采用默认兼容行为,并且没有适当的工具来确保接口更改时重新编译。 GODI 是专门为 OCaml 设计的,可以进行依赖性跟踪(如果您在 GODI 中升级软件包,它将重新编译所有依赖的软件包),并且 Debian 打包团队已经制定了一个方案,可以通过其打包系统实现相同的行为(有关此内容的更多详细信息,请参阅文章 使用包间强制类型安全链接关系)。其他一些工具对此很谨慎,但不幸的是这不是常态,并且仅使用发行版的包管理器仍然可能会出现此类错误。
To expand a bit on ygrek answer : that probably means that xmlrpc-light has been compiled against a different version of the standard library (.. than the one available on your system). This is possible if you reinstalled a new standard library since you installed xmlrpc-light, or if you use a binary xmlrpc-light package that was compiled for a different system. The solution is probably to rebuild xmlrpc against your current standard library.
Those interface versioning issues are delicate because they don't correspond to what is the custom in C/C++ interface decisions; in those languages, when a package interface change, it is assumed by default to be compatible with the previous interface. In OCaml, they are assumed to be incompatible (they compare a hash of the whole module interface), and recompilation is mandatory.
Most packaging tools, e.g. for GNU/Linux distributions, assume the compatible-by-default behavior, and don't have the tooling in place to ensure recompilation when an interface changes. GODI, which was designed specifically for OCaml, does that dependency tracking (if you upgrade a package in GODI, it will recompile all dependent packages), and the Debian packaging team has a scheme in place to achieve the same behaviour with their packaging system (for more details about this, see the article Enforcing Type-Safe Linking using Inter-Package Relationships). Some other tools are careful about this, but unfortunately this is not the norm, and you may still have such errors using only the package manager of your distribution.