在使用普通旧make
的相对较大的项目中,甚至在没有任何改变的情况下构建项目需要几十秒。特别是许多make -C
的执行,它们有新的流程开销。
这个问题的显而易见的解决方案是基于inotify
的构建工具 - 就像操作系统的功能一样。它会在某个文件发生变化时查看,并根据该列表单独编译该文件。
那里有这样的机器吗?开源项目的奖励积分。
答案 0 :(得分:14)
你的意思是Tup:
从主页:
" Tup是一个基于文件的构建系统 - 它输入文件更改列表和有向非循环图(DAG),然后处理DAG以执行更新相关文件所需的相应命令。 DAG存储在SQLite数据库中。默认情况下,通过扫描文件系统生成文件更改列表。或者,可以通过运行包含的文件监视器守护程序预先提供列表。"
答案 1 :(得分:4)
我只是想知道stat()
文件花了这么长时间。要在此处检查这是一个很小的systemtap脚本,我用它来衡量stat()
个文件所需的时间:
# call-counts.stp
global calls, times
probe kernel.function(@1) {
times[probefunc()] = gettimeofday_ns()
}
probe kernel.function(@1).return {
now = gettimeofday_ns()
delta = now - times[probefunc()]
calls[probefunc()] <<< delta
}
然后像这样使用它:
$ stap -c "make -rC ~/src/prj -j8 -k" ~/tmp/count-calls.stp sys_newstat
make: Entering directory `/home/user/src/prj'
make: Nothing to be done for `all'.
make: Leaving directory `/home/user/src/prj'
calls["sys_newstat"] @count=8318 @min=684 @max=910667 @sum=26952500 @avg=3240
我运行它的项目有4593个源文件,需要~27毫秒(26952500nsec以上)才能生成所有文件以及相应的.d文件。我虽然使用非递归make。
答案 2 :(得分:2)
如果您正在使用OSX,则可以使用fswatch
https://github.com/alandipert/fswatch
以下是如何使用fswatch更改文件,然后在检测到任何内容时运行make
fswatch -o anyFile | xargs -n1 -I{} make
您可以在makefile中运行fswatch,如下所示:
watch: $(FILE)
fswatch -o $^ | xargs -n1 -I{} make
(当然,$(FILE)是在makefile中定义的。) make现在可以监视文件中的更改,如下所示:
> make watch
你可以看到这样的另一个文件:
> make watch anotherFile
答案 3 :(得分:1)
安装inotify-tools并写几行bash
以在更新某些目录时调用make
。
作为旁注,递归使得规模严重并且容易出错。首选non-recursive make。
答案 4 :(得分:0)
您描述的更改依赖项已经是Make的一部分,但Make足够灵活,可以以低效的方式使用。如果缓慢真的是由递归(make -C
命令)引起的 - 它可能是 - 那么你应该减少递归。 (您可以尝试使用自己的条件逻辑来决定是否执行make -C
,但这将是一个非常不优雅的解决方案。)
粗略地说,如果你的makefile看起来像这样
# main makefile
foo:
make -C bar baz
和这个
# makefile in bar/
baz: quartz
do something
您可以将其更改为:
# main makefile
foo: bar/quartz
cd bar && do something
有许多细节要求正确,但现在如果bar/quartz
未更改,则foo
规则将无法运行。