如何在字节码可执行文件和ocamlrun之间嵌入和分离二进制文件?

如何在字节码可执行文件和ocamlrun之间嵌入和分离二进制文件?,ocaml,Ocaml,所谓二进制,我指的是字节码和本机代码 我构建了一个仅依赖于标准库的程序,使用带有最少标志集的ocamlbuild: ocamlbuild -I … -use-ocamlfind -libs str program.byte 它运行正常。仅供参考,我使用OCaml 4.02.1,Mac OS X Mountain Lion 通过ocamlobjinfo program.byte我可以大致了解其内容: … Imported units: 9c1885d2c36e2eb94f56f2

所谓二进制,我指的是字节码和本机代码

我构建了一个仅依赖于标准库的程序,使用带有最少标志集的
ocamlbuild

ocamlbuild -I … -use-ocamlfind -libs str program.byte
它运行正常。仅供参考,我使用OCaml 4.02.1,Mac OS X Mountain Lion

通过
ocamlobjinfo program.byte
我可以大致了解其内容:

…
Imported units:
        9c1885d2c36e2eb94f56f21da9040d87 UnixLabels
        30a4cc8e5f4f902ea609c91caec48af7 Unix
        0ce699458ce4430954d7e6a78874647c Sys
…
        8988208489274193e4e3f69dc6ec2f75 MyModule1
        4164567363e873f17809de38a8c5f09e MyModule2
…
Used DLLs:
        dllcamlstr
        dllunix
Primitives used:
        re_string_match
        re_partial_match
…
1) 我的理解是,
program.byte
嵌入了我的整个字节码。我猜它嵌入了我使用的标准库模块的整个字节码,但它真的嵌入了吗

我假设
ocamlrun
在运行时加载2个动态加载的库,这样就能够找到原语;它们是标准库所必需的

我认为字节码可执行文件不能在没有
ocamlrun
的情况下运行,因此我不明白为什么OCaml会在我的程序中嵌入部分标准库,而不是用
ocamlrun
来包装它们

尤其是因为字节码在OCaml版本之间似乎不兼容。我的意思是,我不能先用v4.01构建,然后用v4.02运行,反之亦然

从技术角度来看,我很好奇,但只要字节码可以跨Unices移植,我就可以接受。不过,从法律角度来看,这让我担心字节码可执行文件的分发,该文件嵌入了根据LGPL许可的部分。这可能就是为什么要对OCaml库应用额外的异常

2) 我问题的第二部分是,在运行时,
ocamlrun
的二进制依赖关系是什么?虽然字节码可移植性对于分发来说是非常好的,但是版本之间的不兼容性却无法达到目的。在OCaml升级之后,您将如何继续运行各种OCaml版本的字节码程序

我试图以一种简单的方式保存一份
ocamlrun
的副本,它的版本与构建字节码可执行文件的
ocamlc
相同。然后在安装了较旧的OCaml实现的计算机上,使用此
ocamlrun
运行此可执行文件。不出所料,这一计划惨遭失败

附加问题)我没有Windows构建机器。我的程序执行Windows中不存在的系统调用;它是在Mac上构建的,但在Linux上仍然可以正常工作。假设没有32位/64位的问题,那么它实际上可能会在Cygwin上运行吗

我无法通过谷歌搜索所有这些信息,所以我很感激哪怕是一个指向最新描述的指针

干杯

编辑:我正在尝试找出是否可以避免源代码重新编译。用例:

  • 我提供字节码可执行文件
    B
  • 我可以告诉用户:“那么您在六个月/几年后就不会再使用OCaml版本x.y.z了?好吧,别担心,保留x.y.z发行版中的
    那些二进制文件的副本,并且按照
    这些步骤
    ,您仍然可以运行
    B
    ,而不会破坏其他一切
我有
B
,但我对
那些二进制文件和
这些步骤一无所知。我尽可能不去使用框架,让它对用户来说更简单

我已经知道了,但由于Cygwin在提供POSIX抽象层方面做得很好,我想知道是否有人成功地运行了一个字节码可执行文件,该文件利用了Unix、Sys等模块的POSIX特定系统功能(例如信号;否则,对于Windows,只模拟sigkill)我说的不是MinGW等的交叉编译,而是使用Cygwin控制台与Cygwin DLL动态链接。

1)是的,
cmo
s使用的模块与字节码程序链接

是的,原语的C库是动态链接的

字节码对于同一版本的任何
ocamlrun
都应该是可移植的:因此,OCaml的初始引导编译器
boot/ocamlc
作为字节码分发

您可以使用
-custom
选项将
ocamlrun
与字节码显式链接,但
ocamlrun
约为半mb,将其附加到每个字节码可执行文件是浪费

我认为您对OCaml的LGPL链接异常的猜测是正确的

2) 正如我所说的,字节码的可移植性只有在相同版本的运行时才能得到保证。如果我们升级OCaml版本,我们只需重新编译所有内容。在一些小的升级中,旧的字节码可能在新的
ocamlrun
中工作,因为字节码在升级中没有更改…但这只是运气好,你永远不应该依赖它。顺便说一句,OPAM允许您拥有多个OCaml系统,如果您想保留较旧的字节码程序,您可能需要使用它


附加问题)这取决于。例如,
boot/ocamlc
,OCaml的初始引导编译器,可以在所有系统上运行。但是如果您的字节码依赖于特定于操作系统的外部原语,那么它就不能在其他系统上运行。例如,
Unix
在Unix和Windows中有不同的C原语集,因此字节码程序使用
Unix
的链接在Unix和Windows上都不能正常工作。

感谢您确认我的问题:p我已经编辑了我的问题。我不知道在添加
-lflag-custom
后字节码可执行文件是否仍然是可移植的,但在我这方面仍然缺少一些东西:程序没有在其他地方运行。