延迟或重复 GNU make 中的先决条件
我正在尝试将我的 Subversion 修订版号嵌入到 C++ 项目中,但在设置 GNU make 时遇到问题。 我的 makefile 目前看起来像这样:
check-svnversion:
../shared/update-svnversion-h.pl
../shared/svnversion.h: check-svnversion
shared/svnversion.o: ../shared/svnversion.h
.PHONY: check-svnversion
svnversion.o
依赖于 svnversion.cpp
(通过模式规则)和 svnversion.h
(明确列出因为依赖性检查由于某种原因没有检测到它)。 svnversion.h
由 update-svnversion-h.pl
脚本创建和维护(该脚本基本上只是运行 svnversion
并将输出合并到C++ 文件)。
目前,我必须运行 make
两次才能使文件更新。 第一次,make
运行 update-svnversion-h.pl
(因为它被列为先决条件),但不检查 svnversion.h
的时间戳code> 之后查看它被 update-svnversion-h.pl
更改,因此它不会重新制作 svnversion.o
。 第二次,它会检查时间戳,无论如何都会运行 update-svnversion-h.pl
(这次不会执行任何操作,因为 svnversion.h
已达到date),然后重新编译 svnversion.cpp
生成 svnversion.o
。
有没有办法告诉 GNU make 对单个先决条件进行两次评估,或者延迟检查先决条件的时间戳,直到该先决条件的命令完成之后?
或者,是否有更好的方法在我的源代码中嵌入修订号? (为了速度,我试图避免需要在每个构建上重新编译的解决方案。)
I'm trying to embed my Subversion revision number in a C++ project and am having problems setting up GNU make to do so. My makefile currently looks something like this:
check-svnversion:
../shared/update-svnversion-h.pl
../shared/svnversion.h: check-svnversion
shared/svnversion.o: ../shared/svnversion.h
.PHONY: check-svnversion
svnversion.o
depends on svnversion.cpp
(via a pattern rule) and svnversion.h
(listed explicitly because dependency checking isn't picking it up for some reason). svnversion.h
is created and maintained by the update-svnversion-h.pl
script (which basically just runs svnversion
and munges the output into a C++ file).
Currently, I have to run make
twice to get the file up to date. The first time, make
runs update-svnversion-h.pl
(since it's listed as a prerequisite) but does not check the timestamp of svnversion.h
afterwards to see that it was changed by update-svnversion-h.pl
, so it does not remake svnversion.o
. The second time, it does check the timestamp, runs update-svnversion-h.pl
anyway (which doesn't do anything this time, since svnversion.h
is up to date), then recompiles svnversion.cpp
to make svnversion.o
.
Is there a way to tell GNU make to evaluate a single prerequisite twice or to delay checking the timestamp on a prerequisite until after that prerequisite's commands are finished?
Alternatively, is there a better way to embed a revision number in my source code? (For the sake of speed, I'm trying to avoid solutions that would require recompilation on every build.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这看起来类似于 autotools 对其 config.h 标头所做的事情。
快速浏览一下 automake 的
remake-hdr.am
即可了解它是如何实现这一点的:并且
config.status
创建标记文件。此 automake 示例与您的示例之间的主要区别似乎是 automake 涉及标记文件,而在您的示例中它甚至不是真正的文件。
This seems similar to what autotools does for its config.h header.
A quick look at automake's
remake-hdr.am
shows how it does the trick:And
config.status
creates the stamp file.The main difference between this automake example and your example seems to be that automake touches the stamp file, while in your example it is not even a real file.
这是我放入 make 文件中的目标。 它创建了几个函数,以字符串形式返回各种构建遥测数据。 好处是遥测数据代表最后一次链接的时间,而不是构建对象的时间。
请务必用“svn_version.c”替换最终目标中对目标文件的依赖关系。 前任。
Here is a target I put in my make files. It creates a couple of functions that return various build telemetreis as strings. The nice thing being that the telemetries represent the last time linked, not when an object is built.
Be sure to replace the dependancy on the your object files in your final target with simply 'svn_version.c'. Ex.
您可以使用 Subversion 的关键字替换将版本号放入代码中。
[在书中]有详细说明,但简而言之,您必须设置文件的
svn:keywords
属性以包含Rev
,然后放入$Rev$
代码中的某处。 SVN 会自动将其替换为$Rev: #$
,其中#
是修订号。 您必须解析结果字符串才能获取实际数字,但这应该是一个简单的解析(只需删除前六个字符和最后一个字符)。请注意,这是该文件的最后更改版本,而不是存储库的最后更改版本。 书页上的内容稍微复杂和详细。
You can use Subversion's keyword substitution to put the version number into your code.
It's detailed [in the book], but in short you will have to set the
svn:keywords
property for the file to includeRev
and then put$Rev$
somewhere in your code. SVN will automatically replace this with$Rev: #$
, where#
is the revision number. You mat have to parse the resulting string to get your actual number, but it should be an easy parse (just drop the first six characters and the last character).Note that this is the last changed revision of that file, not the repo's last changed revision. That is slightly more complex and detailed on the book page.
我通过让 check-svnversion 规则删除 svnversion.o 来强制它在需要时重新编译来解决这个问题。 这不太优雅,但很有效; 它看起来类似于 CesarB 的回答。
I solved this by having my check-svnversion rule delete svnversion.o to force it to be recompiled if needed. This isn't exactly elegant, but it works; it looks similar to the autotools solution described in CesarB's answer.