Output compile time stamp in Visual C++ executable?

时间:2022-09-02 09:20:11

How can I insert compilation timestamp information into an executable I build with Visual C++ 2005? I want to be able to output something like this when I execute the program:

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

This build XXXX was compiled at dd-mm-yy, hh:mm.

这个版本XXXX编译为dd-mm-yy,hh:mm。

where date and time reflect the time when the project was built. They should not change with each successive call of the program, unless it's recompiled.

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

6 个解决方案

#1


18  

Though not your exact format, DATE will be of the format Mmm dd yyyy, while TIME will be of the format hh:mm:ss. You can create a string like this and use it in whatever print routine makes sense for you:

虽然不是您的确切格式,但DATE的格式为Mmm dd yyyy,而TIME的格式为hh:mm:ss。您可以创建一个这样的字符串,并在任何对您有意义的打印例程中使用它:

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

(Note on another answer: TIMESTAMP only spits out the modification date/time of the source file, not the build date/time.)

(注意另一个答案:TIMESTAMP只吐出源文件的修改日期/时间,而不是构建日期/时间。)

#2


7  

__DATE__ 
__TIME__

are predefined as part of the standards for C99 so should be available to you. They run once with the preprocessor.

被预定义为C99标准的一部分,因此应该可供您使用。它们与预处理器一起运行一次。

#3


5  

Well... for Visual C++, there's a built in symbol called __ImageBase. Specifically:

嗯...对于Visual C ++,有一个名为__ImageBase的内置符号。特别:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

You can inspect that at runtime to determine the timestamp in the PE header:

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

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

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

And use nt_header->FileHeader.TimeDateStamp to get the timestamp, which is seconds from 1/1/1970.

并使用nt_header-> FileHeader.TimeDateStamp来获取时间戳,即从1970年1月1日起的秒数。

#4


4  

__TIME__ and __DATE__ can work, however there are some complications.

__TIME__和__DATE__可以工作,但有一些并发症。

If you put these definitions in a .h file, and include the definitions from multiple .c/.cpp files, each file will have a different version of the date/time based on when it gets compiled. So if you're looking to use the date/time in two different places and they should always match, you're in trouble. If you're doing an incremental build, one of the files may be rebuilt while the other is not, which again results in time stamps that could be wildly different.

如果将这些定义放在.h文件中,并包含多个.c / .cpp文件中的定义,则每个文件将根据编译时的不同版本添加日期/时间。因此,如果您希望在两个不同的地方使用日期/时间并且它们应始终匹配,那么您就遇到了麻烦。如果您正在进行增量构建,则可能会重建其中一个文件而另一个文件不会重建,这会再次导致时间戳可能大不相同。

A slightly better approach is to make GetBuildTimeStamp() prototypes in a .h file, and put the __TIME__ and __DATE__ macros in the implementation(.c/.cpp) file. This way you can use the time stamps in multiple places in your code and they will always match. However you need to ensure that the .c/.cpp file is rebuilt every time a build is performed. If you're doing clean builds then this solution may work for you.

稍微好一点的方法是在.h文件中生成GetBuildTimeStamp()原型,并将__TIME__和__DATE__宏放在实现(.c / .cpp)文件中。这样,您可以在代码中的多个位置使用时间戳,它们将始终匹配。但是,您需要确保每次执行构建时都重建.c / .cpp文件。如果你正在做干净的构建,那么这个解决方案可能适合你。

If you're doing incremental builds, then you need to ensure the build stamp is updated on every build. In Visual C++ you can do this with PreBuild steps - however in this case I would recommend that instead of using __DATE__ and __TIME__ in a compiled .c/.cpp file, you use a text-based file that is read at run-time during your program's execution. This makes it fast for your build script to update the timestamp (no compiling or linking required) and doesn't require your PreBuild step to understand your compiler flags or options.

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

#5


1  

I think, the suggested solutions to use DATE, TIME or TIMESTAMP would be good enough. I do recommend to get a hold of a touch program to include in a pre-build step in order to touch the file that holds the use of the preprocessor variable. Touching a file makes sure, that its timestamp is newer than at the time it was last compiled. That way, the date/time in the compiled file is changed as well with each rebuild.

我认为,使用DATE,TIME或TIMESTAMP的建议解决方案就足够了。我建议保持触摸程序包含在预构建步骤中,以便触摸保存预处理器变量的文件。触摸文件可确保其时间戳比上次编译时更新。这样,编译文件中的日期/时间也会随着每次重建而更改。

#6


-1  

Visual C++ also supports __TIMESTAMP__ which is almost exactly what you need. That being said, the tough part about build timestamps is keeping them up to date, that means compiling the file in which __TIMESTAMP__ is used on every rebuild. Not sure if there's a way to set this up in Visual C++ though.

Visual C ++还支持__TIMESTAMP__,这几乎就是您所需要的。话虽如此,关于构建时间戳的困难部分是让它们保持最新,这意味着要编译在每次重建时使用__TIMESTAMP__的文件。不知道是否有办法在Visual C ++中设置它。

#1


18  

Though not your exact format, DATE will be of the format Mmm dd yyyy, while TIME will be of the format hh:mm:ss. You can create a string like this and use it in whatever print routine makes sense for you:

虽然不是您的确切格式,但DATE的格式为Mmm dd yyyy,而TIME的格式为hh:mm:ss。您可以创建一个这样的字符串,并在任何对您有意义的打印例程中使用它:

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

(Note on another answer: TIMESTAMP only spits out the modification date/time of the source file, not the build date/time.)

(注意另一个答案:TIMESTAMP只吐出源文件的修改日期/时间,而不是构建日期/时间。)

#2


7  

__DATE__ 
__TIME__

are predefined as part of the standards for C99 so should be available to you. They run once with the preprocessor.

被预定义为C99标准的一部分,因此应该可供您使用。它们与预处理器一起运行一次。

#3


5  

Well... for Visual C++, there's a built in symbol called __ImageBase. Specifically:

嗯...对于Visual C ++,有一个名为__ImageBase的内置符号。特别:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

You can inspect that at runtime to determine the timestamp in the PE header:

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

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

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

And use nt_header->FileHeader.TimeDateStamp to get the timestamp, which is seconds from 1/1/1970.

并使用nt_header-> FileHeader.TimeDateStamp来获取时间戳,即从1970年1月1日起的秒数。

#4


4  

__TIME__ and __DATE__ can work, however there are some complications.

__TIME__和__DATE__可以工作,但有一些并发症。

If you put these definitions in a .h file, and include the definitions from multiple .c/.cpp files, each file will have a different version of the date/time based on when it gets compiled. So if you're looking to use the date/time in two different places and they should always match, you're in trouble. If you're doing an incremental build, one of the files may be rebuilt while the other is not, which again results in time stamps that could be wildly different.

如果将这些定义放在.h文件中,并包含多个.c / .cpp文件中的定义,则每个文件将根据编译时的不同版本添加日期/时间。因此,如果您希望在两个不同的地方使用日期/时间并且它们应始终匹配,那么您就遇到了麻烦。如果您正在进行增量构建,则可能会重建其中一个文件而另一个文件不会重建,这会再次导致时间戳可能大不相同。

A slightly better approach is to make GetBuildTimeStamp() prototypes in a .h file, and put the __TIME__ and __DATE__ macros in the implementation(.c/.cpp) file. This way you can use the time stamps in multiple places in your code and they will always match. However you need to ensure that the .c/.cpp file is rebuilt every time a build is performed. If you're doing clean builds then this solution may work for you.

稍微好一点的方法是在.h文件中生成GetBuildTimeStamp()原型,并将__TIME__和__DATE__宏放在实现(.c / .cpp)文件中。这样,您可以在代码中的多个位置使用时间戳,它们将始终匹配。但是,您需要确保每次执行构建时都重建.c / .cpp文件。如果你正在做干净的构建,那么这个解决方案可能适合你。

If you're doing incremental builds, then you need to ensure the build stamp is updated on every build. In Visual C++ you can do this with PreBuild steps - however in this case I would recommend that instead of using __DATE__ and __TIME__ in a compiled .c/.cpp file, you use a text-based file that is read at run-time during your program's execution. This makes it fast for your build script to update the timestamp (no compiling or linking required) and doesn't require your PreBuild step to understand your compiler flags or options.

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

#5


1  

I think, the suggested solutions to use DATE, TIME or TIMESTAMP would be good enough. I do recommend to get a hold of a touch program to include in a pre-build step in order to touch the file that holds the use of the preprocessor variable. Touching a file makes sure, that its timestamp is newer than at the time it was last compiled. That way, the date/time in the compiled file is changed as well with each rebuild.

我认为,使用DATE,TIME或TIMESTAMP的建议解决方案就足够了。我建议保持触摸程序包含在预构建步骤中,以便触摸保存预处理器变量的文件。触摸文件可确保其时间戳比上次编译时更新。这样,编译文件中的日期/时间也会随着每次重建而更改。

#6


-1  

Visual C++ also supports __TIMESTAMP__ which is almost exactly what you need. That being said, the tough part about build timestamps is keeping them up to date, that means compiling the file in which __TIMESTAMP__ is used on every rebuild. Not sure if there's a way to set this up in Visual C++ though.

Visual C ++还支持__TIMESTAMP__,这几乎就是您所需要的。话虽如此,关于构建时间戳的困难部分是让它们保持最新,这意味着要编译在每次重建时使用__TIMESTAMP__的文件。不知道是否有办法在Visual C ++中设置它。