对接口做出不一致的假设
Make inconsistent assumptions over interface
我想优化 makefile
的编译时间。浪费我时间的一个问题是,修改一个文件后,例如 make
returns,
File "frontend/parser_e.ml", line 1:
Error: The files expression/rc.cmi and frontend/gen/lexer_ref.cmi
make inconsistent assumptions over interface Utility
make: *** [frontend/parser_e.cmx] Error 2
rm frontend/parser_name.ml
请注意,有问题的文件可能会更改,但这种情况经常发生。我要做的是 make clean
然后 make
,因此它不是增量构建并且需要时间。
所以有人知道我应该在 makefile
中检查什么以减少出现此类错误的可能性吗?
编辑 1:
其实我所有的ml相关文件都是深度1
,除了frontend/gen/*
,深度是2。根据@camlspotter的回答,我稍微修改了ocamldep
我的一部分 makefile
。现在看起来像这样:
DIRS= -I frontend -I frontend/gen -I lib ...
depend: $(AUTOGEN)
# ocamldep -native $(DIRS) */*.ml */*.mli > depend # this is what was written before, I don't hink it is correct
ocamldep -native $(DIRS) *.ml *.mli > depend
因此,make
跟随另一个 make
会立即给出不一致错误。
一个问题是我没有AUTOGEN
,这正常吗?
还有一个问题是make depend
生成了一个depend
,有0个字符,正常吗?
编辑 2:
我按照 OCaml 源代码的 Makefile
修改了 depend:
:
beforedepend:: */*.ml
depend: beforedepend
(for d in \
frontend frontend/gen lib ... ; \
do ocamldep $(DIRS) $$d/*.mli $$d/*.ml; \
done) > depend
我实际上有大约20个文件夹,每个文件夹有1-5毫升的文件。这一次,make
响过了for d in ...
,不想停下来。但是如果我删除 3-4 个文件夹,它会在几秒钟后成功创建 depend
。
您的 Makefile 没有涵盖模块之间所有必要的依赖关系。
的含义
File "frontend/parser_e.ml", line 1:
Error: The files expression/rc.cmi and frontend/gen/lexer_ref.cmi
make inconsistent assumptions over interface Utility
是:
frontend/parser_e.ml
取决于 expression/rc.ml
和 frontend/gen/lexer_ref.ml
expression/rc.ml
和 frontend/gen/lexer_ref.ml
都使用名为 Utility
的模块
expression/rc.ml
和frontend/gen/lexer_ref.ml
必须与Utility
的类型(接口)一致,但没有。
我想到造成这种状态的两种可能:
- 可能有两个不同的
utility.ml
,例如dir_a/utility.ml
和dir_b/utility.ml
。 OCaml 不允许链接具有相同名称的模块。您可以使用打包模块解决此问题(请参阅 -pack
编译器选项)。你的情况不是这样。
- 这两个模块使用相同的
utility.ml
,但您的 Makefile 可能并不完全了解依赖关系。这就是你的情况。
第二种情况的一种可能情况是:
- 您已修改
utility.ml
或 utility.mli
并且其界面(.cmi
文件)已更改。
expression/rc.ml
和 frontend/gen/lexer_ref.ml
中的一个针对 Utility
的这个新接口重新编译,但另一个不是,因为依赖性未知。
- 编译器发现两个模块在
frontend/parser_e.ml
中一起使用时存在不一致问题。
为了修复,您必须 运行 ocamldep
捕获所有必要的模块依赖项并将其通知给 make
。注意:
- 给出正确的选项和参数。由于您使用嵌套目录,因此需要多次
-I
选项。
- 确保自动生成的
.ml
和 .mli
文件确实在 ocamldep
运行 之前生成。由于您似乎有 .mly
和 .mll
文件并且您遇到了有关它们的问题,我怀疑您在这里遗漏了一些东西。
在 OCaml 编译器源代码本身中可以找到 OCaml 模块依赖性分析的一个很好的例子。最好用 beforedepend
、depend
和 include .depend
.
检查它的行
一般提示:
- 将
include .depend
添加到您的 Makefile 并将所有模块依赖项捕获到此 .depend
文件中,使用 ocamldep
- 请注意,您项目的所有
.ml
和 .mli
文件都必须由 ocamldep
扫描。不要忘记正确添加 -I
选项,否则它会遗漏一些依赖项。
- 在 运行 宁
ocamldep
之前,确保自动生成 .ml
和 .mli
文件,例如 .mly
和 [=40= 的输出] 生成。或者它遗漏了一些依赖项。
典型的 Makefile 如下所示:
beforedepend:: x.ml
x.ml: x.mly
ocamlyacc x.mly
beforedepend:: y.ml
y.ml: y.mll
ocamllex y.mll
depend: beforedepend
ocamldep -I <dir1> -I <dir2> <all the ml and mli paths> > .depend
include .depend
我想优化 makefile
的编译时间。浪费我时间的一个问题是,修改一个文件后,例如 make
returns,
File "frontend/parser_e.ml", line 1:
Error: The files expression/rc.cmi and frontend/gen/lexer_ref.cmi
make inconsistent assumptions over interface Utility
make: *** [frontend/parser_e.cmx] Error 2
rm frontend/parser_name.ml
请注意,有问题的文件可能会更改,但这种情况经常发生。我要做的是 make clean
然后 make
,因此它不是增量构建并且需要时间。
所以有人知道我应该在 makefile
中检查什么以减少出现此类错误的可能性吗?
编辑 1:
其实我所有的ml相关文件都是深度1
,除了frontend/gen/*
,深度是2。根据@camlspotter的回答,我稍微修改了ocamldep
我的一部分 makefile
。现在看起来像这样:
DIRS= -I frontend -I frontend/gen -I lib ...
depend: $(AUTOGEN)
# ocamldep -native $(DIRS) */*.ml */*.mli > depend # this is what was written before, I don't hink it is correct
ocamldep -native $(DIRS) *.ml *.mli > depend
因此,make
跟随另一个 make
会立即给出不一致错误。
一个问题是我没有AUTOGEN
,这正常吗?
还有一个问题是make depend
生成了一个depend
,有0个字符,正常吗?
编辑 2:
我按照 OCaml 源代码的 Makefile
修改了 depend:
:
beforedepend:: */*.ml
depend: beforedepend
(for d in \
frontend frontend/gen lib ... ; \
do ocamldep $(DIRS) $$d/*.mli $$d/*.ml; \
done) > depend
我实际上有大约20个文件夹,每个文件夹有1-5毫升的文件。这一次,make
响过了for d in ...
,不想停下来。但是如果我删除 3-4 个文件夹,它会在几秒钟后成功创建 depend
。
您的 Makefile 没有涵盖模块之间所有必要的依赖关系。
的含义File "frontend/parser_e.ml", line 1:
Error: The files expression/rc.cmi and frontend/gen/lexer_ref.cmi
make inconsistent assumptions over interface Utility
是:
frontend/parser_e.ml
取决于expression/rc.ml
和frontend/gen/lexer_ref.ml
expression/rc.ml
和frontend/gen/lexer_ref.ml
都使用名为Utility
的模块
expression/rc.ml
和frontend/gen/lexer_ref.ml
必须与Utility
的类型(接口)一致,但没有。
我想到造成这种状态的两种可能:
- 可能有两个不同的
utility.ml
,例如dir_a/utility.ml
和dir_b/utility.ml
。 OCaml 不允许链接具有相同名称的模块。您可以使用打包模块解决此问题(请参阅-pack
编译器选项)。你的情况不是这样。 - 这两个模块使用相同的
utility.ml
,但您的 Makefile 可能并不完全了解依赖关系。这就是你的情况。
第二种情况的一种可能情况是:
- 您已修改
utility.ml
或utility.mli
并且其界面(.cmi
文件)已更改。 expression/rc.ml
和frontend/gen/lexer_ref.ml
中的一个针对Utility
的这个新接口重新编译,但另一个不是,因为依赖性未知。- 编译器发现两个模块在
frontend/parser_e.ml
中一起使用时存在不一致问题。
为了修复,您必须 运行 ocamldep
捕获所有必要的模块依赖项并将其通知给 make
。注意:
- 给出正确的选项和参数。由于您使用嵌套目录,因此需要多次
-I
选项。 - 确保自动生成的
.ml
和.mli
文件确实在ocamldep
运行 之前生成。由于您似乎有.mly
和.mll
文件并且您遇到了有关它们的问题,我怀疑您在这里遗漏了一些东西。
在 OCaml 编译器源代码本身中可以找到 OCaml 模块依赖性分析的一个很好的例子。最好用 beforedepend
、depend
和 include .depend
.
一般提示:
- 将
include .depend
添加到您的 Makefile 并将所有模块依赖项捕获到此.depend
文件中,使用ocamldep
- 请注意,您项目的所有
.ml
和.mli
文件都必须由ocamldep
扫描。不要忘记正确添加-I
选项,否则它会遗漏一些依赖项。 - 在 运行 宁
ocamldep
之前,确保自动生成.ml
和.mli
文件,例如.mly
和 [=40= 的输出] 生成。或者它遗漏了一些依赖项。
典型的 Makefile 如下所示:
beforedepend:: x.ml
x.ml: x.mly
ocamlyacc x.mly
beforedepend:: y.ml
y.ml: y.mll
ocamllex y.mll
depend: beforedepend
ocamldep -I <dir1> -I <dir2> <all the ml and mli paths> > .depend
include .depend