可以“制作”检查依赖项的 mtime 在运行之间是否“不同”,而不仅仅是它是否比目标新?
如果 foo_user.cpp 依赖于 foo.h,则构建了 foo_user.cpp,然后将 foo.h 的修改时间设置为更早的时间,make 将不会重建 foo_user.cpp(因为 foo.cpp 是“较新的”)。我更希望 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 规则)。
If foo_user.cpp depends on foo.h, then foo_user.cpp is built, and then foo.h's modification time is set to further in the past, make will not rebuild foo_user.cpp (because foo.cpp is 'newer'). I'd prefer it if make recorded the modification times of dependencies, and if they changed at all (newer or older), to consider targets of that dependency to be out of date. Can GNU make do this? If not, is there an easy alternative?
In case you're curious how this situation arises: foo.h resides in a symlinked folder. The symlink may point to the foolib-1.0 folder, the foolib-2.0 folder, etc. When the symlink points at a different version of the library, even an older version, foo_user.cpp should be rebuilt. If I simply specifiy symlinkfolder/foo.h as a dependency of foo_user.cpp, make only pays attention to the timestamp of foo.h, not the timestamp of the symlink'd directory through which foo.h is accessed. I can't add the symlink itself as a dependency, because the make rule is generated by the compiler (GCC has a special flag that when given causes it to output a make rule for all the headers a source file depends on).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我试图理解为什么你不能只添加符号链接作为依赖项。我想你的自动依赖关系在一行上,但你可以有任意多的依赖关系。
但话虽如此,
make
似乎会统计符号链接的目标,而不是符号链接本身,因此可能不是 DTRT。我想每当您创建符号链接时您都可以触摸某个文件,但我也想您已经想到了...您可以有一个运行 ls -id link/ 的规则。 > test,会将链接目标目录的inode号放入
test
中。然后,您可以cmp test save
,其中save
来自上次运行。然后你可以让 make 规则执行make clean &&如果它们不同,则创建目标
。I'm trying to understand why you can't just add the symlink as a dependency. I imagine your automatic dependencies are on one line, but you can have as many as you want.
But having said that, it seems likely that
make
will stat the symlink's target, and not the symlink itself, so that may not DTRT. I suppose you could just touch a file somewhere whenever you make the symlink, but I also suppose you've already thought of that...You could have a rule that runs
ls -id link/. > test
, which will put the inode number of the link target directory intest
. You could thencmp test save
, wheresave
is from the last run. You could then have that make rule domake clean && make target
if they are different.不,Make 不支持这一点。您可能希望考虑使用其他构建系统,例如 SCons,它不仅仅依赖于时间戳,而且实际上计算 MD5源文件的哈希值并根据哈希值做出决策。
来自“什么让 SCons 变得更好?”在其网站上:
No, Make does not support this. You may wish to consider using another build system such as SCons, which does not rely solely on the timestamp but actually computes the MD5 hash of source files and bases its decisions on the hashes.
From "What makes SCons better?" on its web site:
虽然
make
不支持开箱即用,但您可以对其进行编程。这里包含 makefile
more_deps
,其中有时将包含对符号链接触发器的依赖。触发器是一种特殊的中间体,所有有意义的信息都是它的时间戳。当符号链接更改时,触发器的时间戳会更新为当前时间(请参阅touch
),从而使 foo_user 过时并重新构建。计算上述依赖关系后,需要
include
和MAKE_RESTARTS
来重新启动 make。如果包含的 makefile 本身就是目标,则认为该目标已重建,重建后 make 重新启动并重新读取 makefile。但是当它第二次读取 makefile 时,它不会将more_deps
视为目标,因为MAKE_RESTARTS
变量扩展为非空字符串。事实上,if 语句听起来像这样:
While
make
doesn't support it out of the box, you can program it.Here you include makefile
more_deps
which sometimes will include the dependency on the symlink's trigger. Trigger is a special intermediate flie, all the meaningful informaion in which is its timestamp. When the symlink changes, the timestamp of the trigger is updated to current time (seetouch
), thus making foo_user outdated and it is the rebuilt.include
andMAKE_RESTARTS
are needed to restart make after calculating the dependency described above. If the makefile being included is a target itself, the target is considered to be rebuilt, is rebuilt and then make restarts and re-reads makefile. But when it reads makefile for the second time, it doesn't seemore_deps
as a target, becauseMAKE_RESTARTS
variable expands to non-empty string.In fact, the line with if can sound like this:
您通过哪个过程更改符号链接?您可以将
make clean
类型的操作添加到更改符号链接的脚本中。您还可以在其中设置一个“标头工作文件夹”,让 make 复制您的头文件,其中复制的头文件依赖于其原始文件和符号链接。 GCC 生成的依赖项仅考虑工作标头,不会与 Makefile 的
将标头复制到工作文件夹
部分发生冲突。Through which process do you change the symlink? You could add a
make clean
type of action to the script that changes the symlink.You could also set up a "header working folder" in with you let make copy your header files, where the copied header files are dependent on their original and the symlink. The dependencies generated by GCC only take the working headers into account and won't clash with your
copy headers into the working folder
part of your Makefile.