OCaml 指定 ppx 可执行文件的路径

OCaml specify path to ppx executable

我正在尝试弄清楚如何将可执行文件的位置传递给 运行 作为 OCaml 编译器的 ppx 过滤器 ocamlc/ocamlopt.

我的问题基本上是

例如,这是一个简单的 OCaml 程序。

(* foo.ml *)
let hi = ();;

Printf.printf "hi there\n"

使用一个非常简单的过滤器 cat,我们可以看到过滤器应该处理什么样的输入。

$ ocamlopt -ppx cat foo.ml | cat -v
Caml1999M019M-^DM-^U??^@^@^@^G^@^@^@^A^@^@^@^C^@^@^@^B&foo.m
...
File "foo.ml", line 1:
Error: External preprocessor does not produce a valid file

它看起来像某种二进制格式,也许是 AST 表示?

cppo,没有配置选项,在使用显式文件调用时处理文本 OCaml 源文件。我有点困惑为什么它在以这种方式调用时发出 #line 指令......我相信这些指令对 C 编译器有意义,但对 OCaml 编译器没有意义。

例如:

$ cppo foo.ml
# 1 "foo.ml"
let hi = ();;

Printf.printf "hi there\n"

它在作为过滤器调用时工作,为行指令提供 <stdin> 的文件名。

$ cat foo.ml | cppo
# 1 "<stdin>"
let hi = ();;

Printf.printf "hi there\n"

阅读 --help for cppo,没有提到输入和输出格式或像 -ppx 这样的参数,这有点令人失望。

你应该怎么做才能将所有片段拼接在一起?

事实证明,我混淆了涵盖扩展点的 ppx 参数和 camlp4(或者可能 camlp5,那里的命名很奇怪,我不知道完全看不懂)。

在编译器前面放置 camlp4 过滤器的正确方法似乎是带有 -pp 标志

以下命令都产生a.out

$ ocamlc foo.ml
$ ocamlc -pp cat foo.ml
$ ocamlc -pp cppo foo.ml

有点令人惊讶的是,即使输出为空,这也有效。

$ ocamlc -pp /usr/bin/true foo.ml

以下命令都不会发出有效的 OCaml 并且什么也不会产生

$ ocamlc -pp /usr/bin/false foo.ml
File "foo.ml", line 1:
Error: Error while running external preprocessor
$ ocamlc -pp /usr/bin/rev foo.ml
File "/var/.../ocamlpp27e608", line 1, characters 2-3:
Error: Syntax error

Ocaml 编译器支持两个不同的预处理器系列:使用 -pp 选项调用的文本预处理器和使用 -ppx 选项调用的(二进制)AST 预处理器。

文本预处理器应将文本源文件的名称作为输入,并在标准输出上输出 OCaml 源文件或 OCaml 二进制 AST。对于那些, cat 确实实现了恒等映射: ocamlc -pp catocamlc 。这些预处理器的一个重要限制是它们不能链接在一起。

相反,-ppx AST 预处理器将输入 AST 二进制文件的名称和输出二进制 AST 文件的名称作为输入。换句话说,在这种情况下恒等映射可以用 cp 来实现: ocamlc -ppx cpocamlc。由于这些预处理器的输入和输出都是二进制 AST,因此可以将多个 ppx 预处理器链接在一起。

cppo预处理器属于第一类,需要用-pp

调用