I'm not aware of any way to do what you're seeking to do directly via a flag using one of the commonly used linkers. In general, if you want to link the definition of such an object into your program, you'll have to provide an object file containing a suitable symbol definition.
The probably simplest way to get there would be to just invoke the compiler to compile the definition of your variable with the content being fed from a macro defined via the command line like already suggested in the other answers. If you want to avoid creating temporary source files, gcc can also receive input straight from stdin:
echo "const char git_commit[] = GIT_COMMIT;" | gcc -DGIT_COMMIT=\"asdf\" -c -o git_commit.obj -xc++ -
And in your code your just declare it as
extern const char git_commit[];
Note: I'm using const char git_commit[]
rather than const char* git_commit
. That way, git_commit
will directly be an array of suitable size initialized to hold the contents of the commit hash. const char* git_commit
, on the other hand, will create a global pointer object initialized to hold the address of a separate string literal object, which means you introduce an unnecessary indirection. Not that it will really matter here, but it also doesn't really cost you anything to skip the inefficiency, however tiny it might be…
There would also be the objcopy
utility which can be used to wrap arbitrary binary content in an object file, see, e.g., here How do I embed the contents of a binary file in an executable on Mac OS X? It may even be possible to pass input to objcopy straight via stdin as well. Finally, you could also just write your own tool that directly writes an object file containing a suitable symbol definition. Consider, however, that, at the end of the day, you're seeking to generate an object file that can be linked with the other object files making up your program. Simply using the same compiler you use to compile the rest of the code is probably the most robust way of going about doing that. With other solutions, you'll always have to manually make sure that the object files are compatible in terms of target architecture, memory layout, …