【问题标题】:Static library symbols missing in linked executable链接的可执行文件中缺少静态库符号
【发布时间】:2010-12-25 06:41:58
【问题描述】:

我正在尝试将静态创建的 .a 库与另一段 C 代码链接。

但是,在最终的可执行文件中,使用nm 命令查看时会发现缺少几个符号(函数名称)。这是因为链接器(被调用的gcc)正在剥离与库链接的另一段C 代码中未引用的符号。我尝试使用nm 命令查找的函数符号在.a 库中可见。

如何使链接器不以这种方式去除省略的符号?

【问题讨论】:

    标签: static-linking


    【解决方案1】:

    通常您需要在应用程序中调用一些注册函数来生成这样的引用。当然如果你无法访问第一个库的代码,你只能使用 tommieb75 描述的 -g 选项。

    【讨论】:

      【解决方案2】:

      一般来说,链接器会去掉其他符号——主要是为了

      • 减小可执行文件的最终大小
      • 加快程序的执行速度

      这里有两种思路:

      • 当您将选项 -O 用作 gcc 命令行的一部分时,即优化代码,因此所有调试信息都会被剥离,因此链接器将自动执行相同操作。
      • 当您使用选项 -g 作为 gcc 命令行的一部分时,该选项包括所有调试信息,以便可执行文件可以在调试器下加载且符号完整。

      从本质上讲,这两者是相互排斥的——你不能将两者结合起来。

      因此,这取决于您使用了哪些开关来实现这一点。通常,-g 开关用于在公开发布之前进行内部调试和测试。相反的是-O2 这样的东西,它使编译器足够聪明,可以生成一个可执行文件,该可执行文件被认为是优化的,例如删除死变量、展开循环等等。

      希望这对您有所帮助并给您提示

      【讨论】:

      • 事实上,如果我没记错的话,使用 Borland 的编译器(认为它是 3.1 和 5.5),它抱怨使用(是吗?)printf 并与浮点链接,因为代码中没有微调强制链接工作,解决方法是包含一个引用浮点数的虚拟函数..有人可以支持我吗?
      • 你确定吗?我通常使用 -g 和 -O2 以便在发布模块中也有调试符号。这会导致发布模块得到优化,但甚至具有使“核心文件”可读且对深度调试有用的符号。我的意思是:我不认为它们是相互排斥的(我多年来一直使用这个标志......)但我同意如果不需要,这可能是浪费。
      【解决方案3】:

      使用 -dynamic 在 gcc 中编译以强制编译器包含所有符号。但请确保这是您真正想要的,因为这很浪费。

      可能对某些静态工厂模式有用。

      【讨论】:

        猜你喜欢
        • 2011-08-06
        • 2013-05-05
        • 2019-02-11
        • 2012-07-06
        • 2013-06-24
        • 2010-12-16
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        相关资源
        最近更新 更多