9

我想编译一些 OCaml 字节码并让它在 Windows 和 Unix 类型的系统上运行。如果我在每个平台上重新编译它,我的源代码可以正常工作,但字节码不可移植。

示例代码:

open Unix

let on_windows = Filename.dir_sep <> "/";;
Printf.printf "On windows: %b\n" on_windows;;

let child = create_process "gpg" (Array.of_list ["gpg"; "--version"]) stdin stdout stderr;;
Printf.printf "Child %d\n" child;;

构建命令:

ocamlbuild -use-ocamlfind -pkg unix test.byte

如果我在 Windows 上编译并在 Linux 上运行,我会得到

Fatal error: unknown C primitive `win_waitpid'

如果我在 Linux 上编译并在 Windows 上运行,我会得到:

Fatal error: unknown C primitive `unix_waitpid'

我怎样才能让字节码在任何地方都能工作?

4

2 回答 2

8

显然,原因是 ocaml unix 库根据平台对 C 存根有不同的名称,这阻碍了字节码的可移植性。除了修补存根名称之外,我没有看到出路..

于 2013-06-26T09:47:49.410 回答
2

仅仅重命名 C 符号是行不通的,因为 unix.ml 模块有两个完全不同的版本(尽管具有相同的接口)。如果你静态链接你的代码,你会得到一个用于构建平台的,它不会在另一个平台上工作。

解决方案是创建和分发 .cma 存档(未链接 Unix 模块)而不是可执行文件。然后ocaml在目标平台上使用动态链接:

http://roscidus.com/blog/blog/2013/07/07/ocaml-binary-compatibility/#windows--linux-compatibility

更新:这不安全。当您这样做时ocaml /path/to/script.ml,它会将当前目录(不是包含脚本的目录)添加到搜索路径的开头。因此:

$ cd /tmp
$ /usr/bin/myprog

将首先尝试unix.cma/tmp.

应该在 4.03 中修复:http ://caml.inria.fr/mantis/view.php?id=6081

于 2013-07-11T15:57:02.677 回答