为什么 OCaml 代码会出现这个编译错误?

问题描述

我目前正在测试 Facebook 的 Infer(开源)v0.17.0 并尝试通过命令使用 bash 文件从源代码构建它

$> ./build-infer.sh 铿锵

但是,我在编译它时遇到错误错误是这样发生的。

[23:35:46][ 98156] Building clang plugin...
[      0s][ 98156] SUCCESS Building clang plugin
[23:35:46][ 98165] Building clang plugin OCaml interface...
[      0s][ 98165] SUCCESS Building clang plugin OCaml interface
[23:35:47][ 98205] Generating source dependencies...
[      0s][ 98205] SUCCESS Generating source dependencies
[23:35:47][ 98298] Building native(opt) Infer...
[*ERROR**][98298] *** ERROR 'Building native(opt) Infer'
[*ERROR**][98298] *** command: ' make INteraCTIVE=1 -C /home/roksui/Dev/dbtest/infer/src infer'
[*ERROR**][98298] *** CWD: '/home/roksui/Dev/dbtest'
[*ERROR**][98298] *** stdout:
[*ERROR**][98298] make[1]: Entering directory '/home/roksui/Dev/dbtest/infer/src'
[*ERROR**][98298] Makefile:122: recipe for target '/home/roksui/Dev/dbtest/infer/bin/infer.exe' Failed
[*ERROR**][98298] make[1]: Leaving directory '/home/roksui/Dev/dbtest/infer/src'
[*ERROR**][98298] *** stderr:
[*ERROR**][98298] Entering directory '/home/roksui/Dev/dbtest/infer'
[*ERROR**][98298] File "src/base/Utils.ml",line 322,characters 4-13:
[*ERROR**][98298] 322 |     Unix.dup2 ~src ~dst:Unix.stderr () ;
[*ERROR**][98298]           ^^^^^^^^^
[*ERROR**][98298] Error: This function has type
[*ERROR**][98298]          src:IStdlib.IStd.Unix.File_descr.t ->
[*ERROR**][98298]          dst:IStdlib.IStd.Unix.File_descr.t -> unit
[*ERROR**][98298]        It is applied to too many arguments; maybe you forgot a `;'.
[*ERROR**][98298] make[1]: *** [/home/roksui/Dev/dbtest/infer/bin/infer.exe] Error 1

函数 Unix.dup2 的参数太多似乎有问题,所以我搜索了 ml 文件,下面是发生错误代码片段。

let suppress_stderr2 f2 x1 x2 =
  let restore_stderr src =
    Unix.dup2 ~src ~dst:Unix.stderr () ;
    Unix.close src
  in
  let orig_stderr = Unix.dup Unix.stderr in
  Unix.dup2 ~src:(Lazy.force devnull) ~dst:Unix.stderr () ;
  let f () = f2 x1 x2 in
  let finally () = restore_stderr orig_stderr in
  protect ~f ~finally

据我所知,Unix.dup2 函数接受两个参数 src 和 dst。但是额外的单元参数 () 在这里发生了什么?

这个错误是否是因为我使用了错误版本的 ocaml 编译器?为什么会出现这个错误?任何见解将不胜感激。谢谢。

解决方法

Facebook Infer 使用具有 v0.14.xcore 标准库替代品 a terminating unit argument。最新版本已经不行了。所以问题似乎是你安装了错误的版本。

编辑:实际上,我查看了 wrong docs,尽管它托管在 jane street 并在 URL 中多次提到 core,但它似乎实际上是 OCaml std 的文档LIB Unix的模块。 Core 中的 latest version of Unix.dup2 仍然具有可选的和终止的 unit 参数。这可能意味着您根本没有安装 Core。但无论哪种方式,您都需要返回并查看我认为的构建和先决条件说明。

当您有一个带有可选参数的函数时,通常会使用终止 unit 参数,否则只有标记参数。由于标记参数可以以任何顺序应用,因此编译器无法知道是否应考虑部分或完全应用没有可选参数的函数应用程序。它将假设部分应用,因此在这种情况下可选参数实际上不是可选的。为了解决这个问题,通常使用一个未标记的 unit 参数来告诉编译器该函数应该被认为是完全应用的。

出于某种原因,从 dup2 中删除了可选参数以及终止的 unit 参数,因为它不再需要。