如何将编译时间戳信息插入到使用 Visual C++ 2005 构建的可执行文件中?当我执行程序时,我希望能够输出这样的东西:
此版本 XXXX 在 dd-mm-yy, hh:mm 编译。
其中日期和时间反映了项目的构建时间。它们不应该随着程序的每次连续调用而改变,除非它被重新编译。
如何将编译时间戳信息插入到使用 Visual C++ 2005 构建的可执行文件中?当我执行程序时,我希望能够输出这样的东西:
此版本 XXXX 在 dd-mm-yy, hh:mm 编译。
其中日期和时间反映了项目的构建时间。它们不应该随着程序的每次连续调用而改变,除非它被重新编译。
虽然不是您的确切格式,但DATE的格式为 Mmm dd yyyy,而TIME的格式为 hh:mm:ss。您可以创建一个这样的字符串,并在任何对您有意义的打印例程中使用它:
const char *buildString = "This build XXXX was compiled at " __DATE__ ", " __TIME__ ".";
(注意另一个答案:TIMESTAMP只吐出源文件的修改日期/时间,而不是构建日期/时间。)
__DATE__
__TIME__
预定义为 C99 标准的一部分,因此您应该可以使用。它们与预处理器一起运行一次。
嗯...对于 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 日开始的秒数。
__TIME__
并且__DATE__
可以工作,但是有一些并发症。
如果您将这些定义放在一个 .h 文件中,并包含来自多个 .c/.cpp 文件的定义,则每个文件将根据其编译时间具有不同版本的日期/时间。因此,如果您希望在两个不同的地方使用日期/时间并且它们应该始终匹配,那么您就有麻烦了。如果您正在进行增量构建,则其中一个文件可能会被重建,而另一个则不会,这再次导致时间戳可能大不相同。
更好的方法是在 .h 文件中制作 GetBuildTimeStamp() 原型,并将__TIME__
和__DATE__
宏放入 implementation(.c/.cpp) 文件中。这样,您可以在代码中的多个位置使用时间戳,并且它们将始终匹配。但是,您需要确保每次执行构建时都重新构建 .c/.cpp 文件。如果您正在进行干净的构建,那么此解决方案可能对您有用。
如果您正在进行增量构建,那么您需要确保每次构建都更新构建标记。在 Visual C++ 中,您可以使用 PreBuild 步骤来执行此操作 - 但是在这种情况下,我建议您不要在编译的 .c/.cpp 文件中使用__DATE__
和,而是使用__TIME__
在程序运行期间在运行时读取的基于文本的文件执行。这使您的构建脚本可以快速更新时间戳(无需编译或链接),并且不需要您的 PreBuild 步骤来了解您的编译器标志或选项。
我认为,使用DATE、TIME或TIMESTAMP的建议解决方案就足够了。我确实建议获取一个包含在预构建步骤中的触摸程序,以便触摸包含预处理器变量使用的文件。触摸文件可确保其时间戳比上次编译时更新。这样,编译文件中的日期/时间也会随着每次重建而改变。
Visual C++ 也支持__TIMESTAMP__
几乎正是您所需要的。话虽如此,关于构建时间戳的难点在于让它们保持最新,这意味着编译__TIMESTAMP__
每次重建时使用的文件。不确定是否有办法在 Visual C++ 中进行设置。