出于愚蠢的原因,我需要有一个字符串,其中包含编译器可执行文件嵌入我正在编译的程序中的选项。这可以通过构建系统或构建系统生成器来实现,尽管方式很丑陋;但我想知道我是否可以让编译器给我这些信息。
语言:C++
编译器:g++、clang++、icpc、MSVC
我尝试的是:我丢弃了$CXX -dM -E -x c++ - < /dev/null
的所有定义,但没有发现与前3个编译器相关的内容。
注意:很明显,语言本身并没有提供这种情况,我询问的是编译器特定的功能。
这完全超出了C++标准的范围。除非编译器提供了明确的方法,否则由您自己实现。所有主要的C++编译器以相同的方式,或者至少以某种可以确定的方式,在逐个编译器的基础上(使用#ifdef
s的嵌套发球(实现这一点的可能性微乎其微。
因此,这取决于你自己来实现。您需要使用任何用于编译和链接C++代码的构建框架——无论是生成文件、脚本还是用于它的任何工具——并进行适当的更改,以捕获传递给编译器的所有选项,并将它们提供给您的应用程序。
例如,在一个自动生成处理的Makefile.am
中,我会做这样的事情:
BUILT_SOURCES += compilation_options.H
compilation_options.H:
echo "#define compilation_options "$(CXXFLAGS)"" >compilation_options.H
这应该足够好了,除非CXXFLAGS
有一些引号或特定的标点符号,在这种情况下,这将需要更多的工作。也许加入$(CPPFLAGS)
和$(LDFLAGS)
,作为一个好的衡量标准。
你需要弄清楚如何为你正在使用的任何构建框架实现类似的东西;在某个地方,没有一个通用的按钮可以被按下,让每个编译器自动完成这项工作。这需要明确实施。
我认为说你的问题的答案是no并不太大胆,因为你无法获得用于编译某些任意应用程序的命令行参数。所以我假设这是一个你自己构建的程序。
此外,no,无法将命令行本身视为预处理器宏。
将元数据添加到可执行文件
您可以安排构建系统将构建命令嵌入到可执行文件中。
首先,您需要一些机制来生成嵌入信息本身。有一种方法:
make clean
make -n >buildinfo
然后,将构建信息嵌入ELF可执行文件的文本部分:
objcopy --add-section .build_info=buildinfo path_to_your_executable
您可以使用再次提取此信息
readelf -p .build_info path_to_your_executable
或
objdump -s --section .build_info path_to_your_executable
对于Windows
对于Windows可执行文件(PE文件(,您需要将构建信息嵌入为自定义资源,并且您需要自己的自定义方式来提取它。该过程在本答案中进行了描述。
备用路线
如果您希望程序本身可以使用内部版本信息,则可以使用xxd
。
例如:
xxd -i buildinfo >buildinfo.c
buildinfo的虚构内容用于说明目的:
Hello, world!
buildinfo.c的结果内容:
unsigned char buildinfo[] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x21, 0x0a
};
unsigned int buildinfo_len = 14;
只需编译此文件并将其与程序中的其他文件链接即可。然后,您可以手动编写命令行处理处理,以包含像--show-build-info
这样的标志,该标志将在运行时将此字符串输出到stdout,或者将其放在about框中,或者任何适合您特定应用程序的内容中。