4

Is it possible to store and display the date of when my project was compiled?

I'd like to print this date when the program starts in order to know which version is used. Currently, I am doing this by hand, which is rather cumbersome.

I am using Visual Studio 2010.

Niall
  • 30,036
  • 10
  • 99
  • 142
Fabian
  • 4,001
  • 4
  • 28
  • 59
  • 3
    Would `__DATE__` and `__TIME__` work for you? – Niall Apr 01 '15 at 08:22
  • There are predefined macros which you can use as described here https://msdn.microsoft.com/en-us/library/b0084kay.aspx –  Apr 01 '15 at 08:22
  • 2
    The compilation date does not means much. You could clean your project and recompile it. What you should do is use some [version control](https://en.wikipedia.org/wiki/Revision_control) system like [git](http://git-scm.com/) and use the unique commit id – Basile Starynkevitch Apr 01 '15 at 08:27

5 Answers5

8

C++ specifies that there's a special preprocessor macro called __DATE__ that is a string literal of when the compilation happened. There's also a corresponding __TIME__ macro.

You can use at such:

const std::string compilation_date = __DATE__;
const std::string compilation_time = __TIME__;

...

std::cout << "This source file was compiled on date " << compilation_date
          << " and at the time " << compilation_time << '\n';
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    Better use const char compilation[] so that you can locate the string in the binary via symbol lookup without even having to run the program. You can also avoid relinking the binary and edit the string directly using binutils and dd. – Johan Boulé Dec 18 '20 at 17:54
5

You can use the __DATE__ and __TIME__ macros - see "Predefined macros" here.

As a sample, something like this:

#include <iostream>
int main()
{
    using namespace std;
    cout << "Compiled on: " << __DATE__ << endl;
    cout << "Compiled at: " << __TIME__ << endl;
}

You would modify the messages and use according to your needs.

You could even look to building it up into a larger macro or named variable.

#include <iostream>
const char* const COMPILED = __DATE__ " @ " __TIME__;
int main()
{
    using namespace std;
    cout << "Compiled: " << COMPILED << endl;
}

If the "version" information is tied to a source control location or data (such as a commit number), it may also be an idea to include that data in the build via a build step or command line define of some sort. You should also consider the effect of incremental builds on the date and time. I'm assuming the "release" builds are not incremental based, or if so, there is "touch" on the file containing the date and time data.

Niall
  • 30,036
  • 10
  • 99
  • 142
4

There are TWO parts to this. The first one (already mentioned in the answers) is to use __DATE__. Unfortunately, this will just tell you the date of compilation for that Translation Unit. If you want the date of the last Visual Studio Build, you need to force a rebuild of the Translation Unit containing __DATE__

One simple solution to this is to always update the file time of that Translation Unit. Say you want Joachim's solution, then you create a separate builddate.cpp file with

const std::string compilation_date = __DATE__;
const std::string compilation_time = __TIME__;

In the post build step, call copy /b builddate.cpp+,,. This means that after every build, the builddate.cpp file becomes newer than the executable and will be recompiled on the next build.

On Linux you'd use touch for this.

Community
  • 1
  • 1
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Better use const char compilation[] so that you can locate the string in the binary via symbol lookup without even having to run the program. You can also avoid relinking the binary and edit the string directly using binutils and dd. – Johan Boulé Dec 18 '20 at 17:56
1

Your question shows that you are not using version control system. You should, there are no excuses like "my project too small I'll do it later when will work on something bigger" or "it is too complex". VCS is must use for every developer, when you start to use it you will not imagine how you lived before without it. So when you start to use VCS your question will be "how to put comit or tag version into source?" For example on svn you can use:

const char *version = "$Id:$";

and svn will change it to current commit version. For other VCS systems solution could be different but close, as this problem is very common.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • Do you know how the same is possible in git? – Fabian Apr 09 '15 at 09:27
  • @Fabian http://stackoverflow.com/questions/11534655/git-keyword-substitution-like-those-in-subversion – Slava Apr 09 '15 at 20:20
  • Be aware that you need to set the svn property svn:keywords on the project tree root dir. Another approach is to patch the binaries after they are built to directly edit the constant string global variable symbol, using binutils and dd for example. The advantage is your don't have do to any costly relinking. – Johan Boulé Dec 18 '20 at 18:05
0

There is a macro called

__DATE__

which resolves to something like "Apr 1 2015". One can just use that. It is a standard predefined macro.

__ DATE __ : This macro expands to a string constant that describes the date on which the preprocessor is being run. The string constant contains eleven characters and looks like "Feb 12 1996". If the day of the month is less than 10, it is padded with a space on the left. If GCC cannot determine the current date, it will emit a warning message (once per compilation) and DATE will expand to "??? ?? ????". https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html

However, this solution lacks formatting. Of course, you can parse it, but maybe there is an easier, more C++ like solution.

Fabian
  • 4,001
  • 4
  • 28
  • 59