如何制作适用于Windows和Linux的OCaml字节码

时间:2013-06-26 08:43:14

标签: ocaml

我想编译一些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'

如何让字节码在任何地方都能正常工作?

2 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分: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加载myprog的库(例如/tmp)。

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