如果foo_user.cpp依赖于foo.h,则构建foo_user.cpp,然后将foo.h的修改时间设置为过去,make将不会重建foo_user.cpp(因为foo.cpp是'newer “)。我更喜欢它,如果make记录了依赖项的修改时间,并且如果它们完全改变(更新或更旧),则认为该依赖项的目标已过时。 GNU可以做到这一点吗?如果没有,是否有一个简单的替代方案?
如果您对这种情况的出现感到好奇:foo.h驻留在符号链接文件夹中。符号链接可能指向foolib-1.0文件夹,foolib-2.0文件夹等。当符号链接指向库的不同版本时,即使是旧版本,也应该重建foo_user.cpp。如果我只是将symlinkfolder / foo.h指定为foo_user.cpp的依赖项,那么make只关注foo.h的时间戳,而不是注意访问foo.h的符号链接目录的时间戳。我不能将符号链接本身添加为依赖项,因为make规则是由编译器生成的(GCC有一个特殊的标志,当给定它时会导致它为源文件所依赖的所有标题输出一个make规则)。 p>
答案 0 :(得分:3)
我试图理解为什么你不能只将符号链接添加为依赖项。我想你的自动依赖是在一条线上,但你可以拥有你想要的任意数量。
x.o: a.h b.h
x.o: c.h
x.o: d.h
但话虽如此,似乎make
将统计符号链接的目标,而不是符号链接本身,因此可能不是DTRT。我想你只要在制作符号链接时就可以触摸一个文件,但我也想你已经想到了......
您可以使用运行ls -id link/. > test
的规则,该规则会将链接目标目录的inode编号放在test
中。然后,您可以cmp test save
,其中save
来自上次运行。然后,如果它们不同,您可以使该规则执行make clean && make target
。
targetwrapper:
ls -id link/. > test
cmp test save || make clean
make realtarget
cp test save
clean:
echo cleaned
realtarget:
echo made
答案 1 :(得分:2)
不,Make不支持此功能。您可能希望考虑使用另一个构建系统,例如SCons,它不仅仅依赖于时间戳,而是实际计算源文件的MD5哈希并将其决策基于哈希值。
来自“是什么让SCons变得更好?”在其网站上:
- 使用MD5签名可靠地检测构建更改;可选的,可配置的传统时间戳支持。
答案 2 :(得分:1)
虽然make
不支持开箱即用,但您可以对其进行编程。
include more_deps
ifneq ($(MAKE_RESTARTS),)
more_deps:
if (foolink.old differs from what foolink points to) ; then \
readlink foolink > foolink.old ; \
echo "foo_user: foolink_trigger" > more_deps ; \
touch foolink_trigger ; \
else \
echo "" > more_deps ;\
fi
endif
foo_user: foo_user.cpp
g++ $^ -o $@
这里包含makefile more_deps
,其中有时将包含对符号链接触发器的依赖。 Trigger是一个特殊的中间版本,所有有意义的信息都是它的时间戳。当符号链接发生更改时,触发器的时间戳会更新为当前时间(请参阅touch
),从而使foo_user过时并且重建时间。
include
和MAKE_RESTARTS
重启make。如果包含的makefile是目标本身,则认为目标是重建的,重建目标然后重新启动并重新读取makefile。但是当它第二次读取makefile时,它不会将more_deps
视为目标,因为MAKE_RESTARTS
变量会扩展为非空字符串。
事实上,if的行听起来像这样:
more_deps:
if (any condition you want with $(VARIABLES) possible!) ; then \
update a file that holds the previous state ;\
...
答案 3 :(得分:0)
您通过哪个流程更改符号链接?您可以向更改符号链接的脚本添加make clean
类型的操作。
你也可以设置一个“标题工作文件夹”,让你复制你的头文件,其中复制的头文件依赖于它们的原始和符号链接。 GCC生成的依赖项仅考虑工作头,并且不会与Makefile的copy headers into the working folder
部分冲突。