在Visual C++可执行文件中输出编译时间戳?

20

我如何在使用Visual C++ 2005构建的可执行文件中插入编译时间戳信息? 我希望能够在执行程序时输出以下内容:

此版本 XXXX 是在 dd-mm-yy,hh:mm 编译的。

其中日期和时间反映了项目构建的时间。 它们不应该随着每次调用程序而更改,除非重新编译。


请参考以下问题的答案:在Visual Studio C++构建中打印日期和时间 - User
6个回答

26

尽管不是您精确的格式,日期将采用Mmm dd yyyy格式,而时间将采用hh:mm:ss格式。 您可以创建这样一个字符串,并在适合您的任何打印例程中使用它:

const char *buildString = "This build XXXX was compiled at " __DATE__ ", " __TIME__ ".";

(关于另一个答案的说明:TIMESTAMP仅显示源文件的修改日期/时间,而不是生成日期/时间。)


11
__DATE__ 
__TIME__

这些在 C99 标准中预定义,因此应该对您可用。它们在预处理器中运行一次。


1
请注意,像我这样希望在VERSIONINFO结构中添加日期的人无法使用这些定义与资源编译器一起使用。 - Skywalker13

8

对于Visual C++,有一个内置的符号称为__ImageBase。具体来说:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

您可以在运行时检查它以确定PE头中的时间戳:

const IMAGE_NT_HEADERS *nt_header= (const IMAGE_NT_HEADERS *)((char *)&__ImageBase + __ImageBase.e_lfanew);

使用nt_header->FileHeader.TimeDateStamp获取时间戳,它是从1970年1月1日起计算的秒数。


6

__TIME____DATE__可以使用,但是存在一些复杂性。

如果将这些定义放在.h文件中,并从多个.c/.cpp文件中包含这些定义,则每个文件将根据编译时间具有不同版本的日期/时间。因此,如果您想在两个不同的地方使用日期/时间,并且它们应始终匹配,则会遇到问题。如果进行增量构建,则其中一个文件可能会重新构建,而另一个文件则没有,这将导致时间戳可能非常不同。

稍微好一点的方法是在.h文件中制作GetBuildTimeStamp()原型,并在实现(.c/.cpp)文件中放置__TIME____DATE__宏。这样,您可以在代码中的多个位置使用时间戳,并且它们将始终匹配。但是,您需要确保每次执行构建时都重新构建.c/.cpp文件。如果您正在执行清理构建,则此解决方案可能适用于您。

如果您正在进行增量构建,则需要确保在每次构建时更新构建标记。在Visual C++中,您可以使用PreBuild步骤来完成此操作-但在这种情况下,我建议您不要在已编译的.c/.cpp文件中使用__DATE____TIME__,而是使用文本文件,在程序执行期间运行时读取。这使得您的构建脚本可以快速更新时间戳(无需编译或链接),并且不需要您的PreBuild步骤了解您的编译器标志或选项。


另一种方法是拥有一个特殊的单个文件,其中包含时间戳,并确保用于构建的 makefile 在每次重新构建程序时重新构建该特定文件。这是我在较大软件项目中看到的最常见的解决方案。 - jakobengblom2
在我预构建的 cpp 文件中创建一个时间戳函数,它按照我的期望为增量构建工作。只是在头文件中有一个宏并不能在每次需要更新时间戳时更新我的应用程序中的时间戳。 - thomthom

1

我认为,使用DATETIMETIMESTAMP来建议解决方案已经足够好了。我建议在预构建步骤中获取一个touch程序并将其包含在内,以触摸包含预处理器变量的文件。触摸文件可以确保其时间戳比上次编译时更新。这样,在每次重新构建时,编译文件中的日期/时间也会随之改变。


0

Visual C++ 还支持 __TIMESTAMP__,几乎完全符合您的需求。 话虽如此,生成时间戳的难点在于保持它们的最新状态,这意味着在每次重新构建中编译使用了 __TIMESTAMP__ 的文件。不确定是否有方法在 Visual C++ 中设置此项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接