For silly reasons, I am required to have a string with the options the compiler executable got embedded in the program I'm compiling. This can be achieved by the build system or build-system-generator, albeit in an ugly way; but I was wondering if I can get my compiler to give me that information.
Language: C
Compiler: Each of g , clang , icpc, MSVC
What I tried: I dumped all of the defines with $CXX -dM -E -x c - < /dev/null
, and didn't see something relevant, for the first 3 compilers.
Note: Obviously the language itself does not provide for this to happen, I'm asking about compiler-specific features.
CodePudding user response:
This is completely out of the scope of the C standard. Unless your compiler provides an explicit means of doing so, it is up to you to implement it yourself. And the chances of all major C compilers implementing this in an identical way, or at least in some way that can be determined, on individual compiler-by-compiler basis (with a nested hairball of #ifdef
s), are slim to none.
Therefore it is up to you to implement this yourself. You will need to take whatever build framework you are using to compile and link your C code -- be it a makefile, a script, or whatever tool gets used for it -- and make the appropriate changes to capture all options that get passed to the compiler, and provide them to your applications.
In an automake-processed Makefile.am
, for example, I would do something like this:
BUILT_SOURCES = compilation_options.H
compilation_options.H:
echo "#define compilation_options \"$(CXXFLAGS)\"" >compilation_options.H
That should be good enough unless CXXFLAGS
has some quotes or specific punctuation, in which case this will require a little bit more work. Perhaps toss in $(CPPFLAGS)
and $(LDFLAGS)
, for a good measure.
You will need to figure out how to implement something similar for whatever build framework you're using; there is no universal button, somewhere, that can be pushed to have this done automatically with every compiler. This needs to be implemented explicitly.
CodePudding user response:
I don't think it's too bold to say that the answer to your question is no, in that you cannot get the command line arguments that were used to compile some arbitrary application. So I'm going to assume this is a program that you're building yourself.
Furthermore, no, there's no way to see the command line itself as a preprocessor macro.
Adding metadata to your executable
You can arrange for your build system to embed the build commands into your executable.
Firstly, you will want some mechanism for producing the embedded information itself. Here's one way:
make clean
make -n >buildinfo
Then, to embed the buildinfo in a text section of your ELF executable:
objcopy --add-section .build_info=buildinfo path_to_your_executable
You can extract this info again with:
readelf -p .build_info path_to_your_executable
or
objdump -s --section .build_info path_to_your_executable
For Windows
For Windows executables (PE files), you'll want to embed your build info as a custom resource, and you'll need your own custom way to extract it. The procedure is described in this answer.
Alternate route
If you want the build info available to the program itself, you can use xxd
.
For example:
xxd -i buildinfo >buildinfo.c
Fictional contents of buildinfo for illustration purposes:
Hello, world!
Resulting contents of buildinfo.c:
unsigned char buildinfo[] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x21, 0x0a
};
unsigned int buildinfo_len = 14;
Just compile and link this file along with others in your program. Then you could manually write your command-line processing handling to include a flag like --show-build-info
that would output this string to stdout at run-time or put it in your about box or whatever is appropriate for your particular application.