【问题标题】:Can you get the compiler's command-line contents from within the compiled program?你能从编译后的程序中获取编译器的命令行内容吗?
【发布时间】:2022-01-02 13:42:40
【问题描述】:

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

语言:C++

编译器:g++、clang++、icpc、MSVC中的每一个

我尝试了什么:我使用 $CXX -dM -E -x c++ - < /dev/null 转储了所有定义,但前 3 个编译器没有看到相关内容。

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

【问题讨论】:

  • 一些具体细节可作为宏使用。您是否在寻求一些特定的选择?您会发现许多标志都有与之关联的相应宏,但您会单独获得每个标志。 (可以说是点菜。)例如:standard macros,或特定于MSVCgcc 的宏
  • @Wyck:不,我想要完整的字符串。或者更确切地说,我根本不想要它,但其他人认为他们想要它。

标签: c++ command-line compiler-options


【解决方案1】:

这完全超出了 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)

您需要弄清楚如何为您使用的任何构建框架实现类似的东西;在某个地方没有通用按钮可以按下每个编译器自动完成此操作。这需要明确实现。

【讨论】:

  • 如果我使用自动工具,这很有用,但它不能回答我的字面问题。我可以在没有编译器支持的情况下度过难关,如果可能的话,我宁愿避免麻烦。
  • 我相信我在第一段中回答了这个问题。
【解决方案2】:

我认为说您的问题的答案是并不太大胆,因为您无法获得用于编译某些任意的命令行参数em> 应用程序。所以我假设这是你自己构建的程序。

此外,,无法将 命令行 本身视为预处理器宏。

将元数据添加到您的可执行文件中

您可以安排您的构建系统将构建命令嵌入到您的可执行文件中。

首先,您需要一些机制来生成嵌入信息本身。这是一种方法:

make clean
make -n >buildinfo

然后,将 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 文件),您需要将构建信息嵌入为自定义 resource,并且您需要自己的自定义方式来提取它。该过程在this answer 中进行了描述。

备用路线

如果您希望程序本身可以使用构建信息,可以使用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这样的标志,它会在运行时将此字符串输出到标准输出,或者把它放在你的about框或者任何适合你的特定的应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 2010-10-25
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多