如何自动创建具有最新编译时间的文件并将其包含到库中?
我有一个包含大约 100 个源文件的库。 如果任何其他文件已编译,我希望始终重建其中一个源,但我不希望每次运行 make/build 时都构建它。
基本上,我希望此文件内置有最后的构建日期/时间,以便链接到该库的任何应用程序都可以检查最后的构建时间/日期。 还有其他方法可以做到这一点吗?
I have a library consisting of approx 100 source files. I want one of the sources to be always rebuilt if any of the other files have been compiled but I don't want it built every time I run the make/build.
Basically I want this file to have the last build date/time built into it so any application linking to the library can check the last build time/date. Is there any other way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
让包含构建时间戳的对象文件依赖于所有其他对象文件:
Let the object file containing the build timestamp depend on all the other object files:
稍微扩展 JesperE 的解决方案。
让目标文件依赖于可执行文件所依赖的所有目标(不包括其自身)。
因此,如果所有可执行文件都依赖于对象,那么 JesperE 是完全正确的。
否则,在其他依赖项之一发生更改但目标文件没有发生更改的情况下,您可以重建可执行文件而不更新时间戳。 因此,问题中提到的两件事“具有最后的构建时间/日期”和“如果已编译任何源则重新构建”实际上并不是同一件事,所以这取决于您想要的。
示例可能包括您静态链接的库,或者一些用于进行链接的脚本,这些脚本发生了很大的变化,因此为了方便开发人员而将其作为依赖项。
如果您只是删除可执行文件并重建它,这仍然不会更新时间戳(可能是因为相关的某些内容发生了变化,但不是依赖项,例如因为您已经获取了链接器的最新版本或者您已经更改了环境中影响链接器和/或 makefile 的某些内容)。 因此,最好的办法可能是将对象编译为构建可执行文件的规则的一部分,如下所示:
或其他(如果您使用的是 make,则可能不是 .exe,但您永远不知道)。 实际上,错误处理有点狡猾,因为如果最后一行失败,则 version.o 将不会被删除。
我还要补充一点,如果您要向用户发布某些内容(我的意思是基本上距离您办公桌 10 英尺以上的任何人),无论如何从头开始构建可能是一个想法,而不是仅仅运行 make 来更新,并发货。 否则很容易搞砸 makefile,从而错过依赖项,意外构建“混合版本”,并且无法重现您发布的内容。
我之前曾对 makefile 进行过调整,因此如果版本号是由开发人员构建的,则版本号会被故意破坏(设置为“0.0 私有构建”) - 只有构建服务器设置用于启用正确版本号的选项。 对于该项目,在未通过标签从源代码控制中检出并从那里构建的东西上添加数字是没有意义的。
To expand slightly on JesperE's solution.
Let the object file depend on all targets which the executable depends on, (excluding itself).
So if all the executable depends on is objects, then JesperE is completely correct.
Otherwise, you could rebuild the executable without updating the timestamp, in the case where one of the other dependencies changes but none of your object files does. So the two things mentioned in the question, "has the last build time/date" and "rebuilt if any of the sources has been compiled", aren't actually the same thing, so it depends which you want.
Examples could include a library you statically link against, or some script which is used to do the linking and which changes a lot so has been made a dependency for the convenience of developers.
This still won't update the timestamp if you just delete the executable and rebuild it (perhaps because something has changed which is relevant, but not a dependency, such as because you've grabbed the latest version of the linker or you've changed something in the environment which affects the linker and/or the makefile). So the best thing to do might be to compile the object as part of the rule for building the executable, like this:
or whatever (probably not .exe if you're using make, but you never know). Actually the error-handling there is a bit dodgy, since version.o won't be deleted if the last line fails.
I'd also add that if you're going to release something to users (by which I mean basically anyone more than 10 feet from your desk), it might be an idea to build from scratch anyway rather than just run make to update, and ship it. It's pretty easy otherwise to screw up the makefile so that you miss a dependency, accidentally build a "mixed version", and have no way to reproduce what you shipped.
I've jiggered makefiles before so that the version number was deliberately sabotaged (set to "0.0 private build") if it was built by a developer - only the build server set the option used to enable the proper version number. For that project, it just wasn't meaningful to put a number on something that wasn't checked out of source control by tags, and built from there.