【问题标题】:Compile a Standalone Static Executable编译一个独立的静态可执行文件
【发布时间】:2011-03-18 00:23:35
【问题描述】:

我正在尝试编译不使用动态加载程序的可执行文件(ELF 文件)。我构建了一个交叉编译器,它从 linux 编译 mips,以在我制作的模拟器上使用。我在编译我的 hello.cpp 文件(hello world 程序)时声明了标志 -static-libgcc。显然这还不够。因为我的可执行文件中还有一个包含动态加载器的名称/路径的段。我使用哪些标志来生成包含需要运行的所有内容的可执行文件?我需要重建我的交叉编译器吗?

【问题讨论】:

    标签: c++ compiler-construction linker executable


    【解决方案1】:

    使用以下标志进行链接

    -static -static-libgcc -static-libstdc++
    

    使用这三个标志来链接所有依赖项的静态版本(假设 gcc)。请注意,在某些情况下,您不一定需要所有三个标志,但它们也不会“伤害”。因此,只需打开所有三个。

    检查它是否真的有效

    1. 确保确实没有动态链接

      ldd yourexecutable
      

      应该返回“不是动态可执行文件”或类似的东西。

    2. 确保没有剩余的未解析符号

      nm yourexecutable | grep " U "
      

      列表应该是空的或者应该只包含一些特殊的内核空间符号,比如

      U __tls_get_addr
      
    3. 最后,检查你是否可以真正执行你的可执行文件

    【讨论】:

      【解决方案2】:

      尝试使用-static 标志?

      【讨论】:

      • 是否有很好的资源来描述每个 gcc 标志的确切结果?我不是 100% 确定我是否真的禁用了动态加载。当我使用 -static 时,我仍然将动态加载器的名称放在 elf 文件的 .interp 部分中。
      • gcc.gnu.org/onlinedocs/gcc/Option-Index.html 我曾经写过一个加载elf可执行文件的操作系统,我可以确认-static标志有效,忽略ld相关的东西,直接跳转到可执行文件的入口点跨度>
      • 我读到了一些关于使用一些配置选项“-disable-shared”的内容。这不是编译独立可执行文件所必需的吗?
      • --disable-shared 是配置 GCC 时的一个选项(请参阅gcc.gnu.org/install/configure.html),但 GCC 将始终构建所有标准库的静态版本; --enable-shared 告诉它在静态版本之外构建它们的共享版本
      • 我明白了,所以一种或另一种 --disable-shared 不会影响我生成的可执行文件?如果使用静态(这样我可以确认我理解),那么我的可执行文件会相当大,因为运行二进制文件所需的所有内容都已经加载到 elf 文件中?然后我可以将我的程序计数器设置为入口位置,其他一切都应该解决吗?
      猜你喜欢
      • 2012-07-03
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 2014-08-30
      • 2017-03-29
      • 2018-04-19
      相关资源
      最近更新 更多