你能从编译的程序内获取编译器的命令行内容吗?



出于愚蠢的原因,我需要有一个字符串,其中包含编译器可执行文件嵌入我正在编译的程序中的选项。这可以通过构建系统或构建系统生成器来实现,尽管方式很丑陋;但我想知道我是否可以让编译器给我这些信息。

语言:C++

编译器:g++、clang++、icpc、MSVC

我尝试的是:我丢弃了$CXX -dM -E -x c++ - < /dev/null的所有定义,但没有发现与前3个编译器相关的内容。

注意:很明显,语言本身并没有提供这种情况,我询问的是编译器特定的功能。

这完全超出了C++标准的范围。除非编译器提供了明确的方法,否则由您自己实现。所有主要的C++编译器以相同的方式,或者至少以某种可以确定的方式,在逐个编译器的基础上(使用#ifdefs的嵌套发球(实现这一点的可能性微乎其微。

因此,这取决于你自己来实现。您需要使用任何用于编译和链接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框中,或者任何适合您特定应用程序的内容中。

最新更新