I've got a C++ project that happens to be stored in a Bazaar repo. This project also uses a #define
'd string to display its version number. Someone just asked if we could simply tie this displayed version number to the bzr repo revision number.
So, in pseudo-C, pseudo-bash, something like:
#define VERSION_STRING "revision $(bzr revno)"
//...
cout << "Starting " << VERSION_STRING;
Or so. How might you answer this question? Does the makefile run a script that inserts the output of that command into the appropriate source file? Is there a macro solution for this? Etc?
I'm open to any and all clever solutions, as I'm drawing an educated blank on this one. =D
The compiler will have a flag to define a macro value externally. For g++ and clang++ this is -D
:
g++ -DVERSION_STRING="revision $(bzr revno)" file.cpp -c -o file.o
To get that in the file as a string, you can either add extra quotes into the definition:
g++ -DVERSION_STRING="\"revision $(bzr revno)"\" file.cpp -c -o file.o
or you need to know how to stringify that value inside the file, which takes a little magic:
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
Then you could also have a default value. I'd recommend have a different variable set by the compiler to the one you use internally, it helps keep track:
#include <iostream>
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
#ifdef VERSION
#define VERSION_STRING STRINGIFY(VERSION)
#else
#define VERSION_STRING "0.0.0"
#endif
int main()
{
std::cout << VERSION_STRING << '\n';
}
results in:
$ g++ -DVERSION="1.0.0" SO.cpp
$ ./a.out
1.0.0
$ g++ SO.cpp
$ ./a.out
0.0.0
Note, $(bzr revno)
is the syntax to run bzr revno
and substitute its output in a shell (bash syntax, probably the same in most others). From within a makefile, as musasabi pointed out, the syntax is slightly different: $(shell bzr revno)
,