使ocaml、camlp4、ppx、node、js_of_ocaml和ocamlbuild兼容

4
安装了 npmnode 后,使用 js_of_ocaml 编译 OCaml 文件时出现错误,因此我执行了 opam switch reinstall system 命令:
:testweb $ opam switch reinstall system
Your system compiler has been changed. Do you want to upgrade your OPAM installation ? [Y/n] y

=-=- Upgrading system -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=   
[WARNING] base-ocamlbuild.base is not available because it requires OCaml >= 3.10 & < 4.03. Skipping.
[WARNING] camlp4.4.02+system is not available because your system doesn't comply with preinstalled &
      ocaml-version >= "4.02" & ocaml-version < "4.03". Skipping.
[WARNING] ppx_tools.4.02.3 is not available because your system doesn't comply with ocaml-version >=
      "4.02.0" & ocaml-version < "4.03.0". Skipping.
The following dependencies couldn't be met:
  - deriving -> camlp4
Your request can't be satisfied:
  - camlp4 is not available because your system doesn't comply with ocaml-version >= "4.04".

No solution found, exiting
The former package state can be restored with opam switch import "/Users/softtimur/.opam/backup/state-20160418124642.export" --switch system

然后,我意识到 ocamlfind 不再起作用:

:testweb $ ocamlfind ocamlc -package js_of_ocaml.ppx -linkpkg cubes.ml -o T
-bash: /Users/softtimur/.opam/system/bin/ocamlfind: No such file or directory

PS: node --version的版本号为v6.1.0; npm --version的版本号为3.8.6; ocaml -version的版本号为The OCaml toplevel, version 4.03.0js_of_ocaml --version的版本号是2.7,但在执行opam swtich reinstall system之后,它显示为-bash: /Users/softtimur/.opam/system/bin/js_of_ocaml: No such file or directory

有人知道如何让所有这些软件包兼容吗?


早先: 在安装npmnode之后,在执行opam switch reinstall system之前,以下是编译错误:

:testweb $ ocamlfind ocamlc -package js_of_ocaml.ppx -linkpkg cubes.ml -o T
Failure("Ast_mapper: OCaml version mismatch or malformed input")
File "cubes.ml", line 1:
Error: Error while running external preprocessor
Command line: /Users/softtimur/.opam/system/lib/js_of_ocaml/./ppx_js '/var/folders/fn/0rmvqqbs4k76lg5g6b7kll100000gn/T/camlppxffe989' '/var/folders/fn/0rmvqqbs4k76lg5g6b7kll100000gn/T/camlppx02e06a'

另一种方法也出现了错误:

:testweb $ ocamlfind ocamlc -package js_of_ocaml -syntax camlp4o -package js_of_ocaml.syntax -linkpkg -o cubes.byte cubes.ml
Fatal error: unknown C primitive `caml_is_printable'
File "cubes.ml", line 1:
Error: Error while running external preprocessor
Command line: camlp4 '-I' '/usr/local/lib/ocaml/camlp4' '-I' '/Users/softtimur/.opam/system/lib/js_of_ocaml' '-parser' 'o' '-parser' 'op' '-printer' 'p' 'pa_js.cmo'  'cubes.ml' > /var/folders/fn/0rmvqqbs4k76lg5g6b7kll100000gn/T/ocamlpp8b28e8

起初: 我的最初目标是编写和编译cubes.ml,使其能够包装一个OCaml函数以创建一个可以在Web中调用的JS函数,并且可以在Linux命令行下测试OCaml函数和字节码。

cubes.ml如下:

let () =
  let oneArgument (a: int) = a + 100 in
  Js.Unsafe.global##.jsOneArgument := Js.wrap_callback oneArgument;
  print_string "hello\n";
  exit 0

然后,ocamlfind ocamlc -package js_of_ocaml.ppx -linkpkg cubes.ml -o T应该生成T,使得./T返回hello。并且js_of_ocaml T -o cubes.js应该生成cubes.js,以便可以通过其他JS或HTML文件调用cubes.jsjsOneArgument函数。
在我搞乱包之前,./T返回未实现的Javascript原始caml_pure_js_expr!,这就是为什么我安装了npmnode等的原因。

“$ node cubes.js” 这么写不就可以了吗? - zakki
你是指在命令行中运行 node cubes.js 吗?能否请您详细说明一下? - SoftTimur
是的。在Linux命令行下,node.js输出“hello”。 - zakki
我明白你的意思...请看我的更新... - SoftTimur
安装 Node 时,可能会更新系统编译器。此时可能需要运行 opam switch reinstall system - zakki
我刚刚执行了 opam switch reinstall system 命令,看起来有点让人担心... - SoftTimur
1个回答

0

我回到了OCaml 4.02.3:

opam switch 4.02.3

那么,

eval `opam config env`

那么,

opam install ppx_tools js_of_ocaml

作为结果,ocamlfind ocamlc -package js_of_ocaml.ppx -linkpkg cubes.ml -o T 生成 T,而 js_of_ocaml T -o cubes.js 生成 cubes.jsnode cubes.js 确实返回 hello
然而,./T 仍然返回 Unimplemented Javascript primitive caml_pure_js_expr!,我将开另一个帖子讨论这个问题...

请注意,应该是 eval `opam config env` (反引号)或 eval $(opam config env)(备用 bash 语法),简单的引号不起作用。 - gasche
eval $(opam env) 也能完成这项工作。 - Hartmut Pfarr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接