如何使OCaml字节码在Windows和Linux上工作

如何使OCaml字节码在Windows和Linux上工作,ocaml,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"; "--

我想编译一些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;;
如果我在Windows上编译并在Linux上运行,我会

Fatal error: unknown C primitive `win_waitpid'
如果我在Linux上编译并在Windows上运行,我会得到:

Fatal error: unknown C primitive `unix_waitpid'

如何使字节码在任何地方都能工作?

显然,原因是ocaml unix库的C存根名称因平台而异,这妨碍了字节码的可移植性。除了修补存根名称之外,我看不到出路。

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

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

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

$ cd /tmp
$ /usr/bin/myprog
将首先尝试从
/tmp
加载myprog的库(例如
unix.cma


应该在4.03中修复:

请显示编译命令。我正在使用ocamlbuild-我已经编辑了这个问题。我怎么做(补丁存根名称)?您必须在windows下安装(至少)mingw。您可以尝试通过在路径中添加mingw DLL来破解您的包,并启动字节码,然后看起来win_waitpid是一个OCaml函数,而不是mingw函数(我对此一无所知)。我将尝试转到win32unix源代码,并在.c文件的函数名和unix.ml中的“外部”声明中将win_u替换为unix_u。似乎win32unix中的一些函数有unix前缀,而一些win不知道为什么。我想消除这种差异将有利于unix库的字节码可移植性。显然,windows实现缺少很多原语(请看win32unix/unix.ml模块代码)。也许他们想允许在允许的平台(即安装了unix服务的windows)上包含这两个模块。我同意建议的在windows代码中重命名C原语的解决方案。
$ cd /tmp
$ /usr/bin/myprog