【问题标题】:Missing symbols from static library in linked executable链接可执行文件中的静态库中缺少符号
【发布时间】:2011-08-06 20:04:15
【问题描述】:

我遇到了链接可执行文件中缺少静态库符号的问题。 这是我的问题的描述:

我有从几个目标文件构建的静态库。这些目标文件提供了几组符号,与:

  1. 一组 C 函数和结构(几个目标文件)。我们把对应的符号称为level1符号。
  2. 为此 C 函数和结构(另一个目标文件)的一组 C++ 包装类。我们把对应的符号称为level2符号。
  3. 从具有扩展功能的 2 级类(另一个目标文件)继承而来的一组 C++ 包装类。我们把对应的符号称为level3符号。

Undeground C 代码使用其他几个项目和外部库。其中一些是静态的,所以目前这个库也是静态的。

库与可执行文件链接。此文件仅直接使用 lib 中的 level2 符号。但是这个可执行文件在执行过程中加载的一些动态库需要level3符号。

问题是,level3 符号由于某种原因被遗漏到这个可执行文件中(nm 批准)。

库本身包含所有符号组。此外,还有一个与该库链接的可执行文件,它还包含所有符号组。这些可执行文件之间的主要区别在于第二个可执行文件(所有符号都显示在其中)直接使用 leve3 符号。

整个项目是在调试配置中使用 CMake 构建的(这意味着“-g”选项出现在 g++ 命令中)。底层操作系统是 GNU/Linux x86_64。 g++ 版本是 4.4。

我在 StackOverflow 上检查了几个类似的问题,但没有找到任何可接受的解决方案。

我已经尝试了几个链接选项来解决问题(--export-dynamic、--whole_archive),但都没有帮助。

我很高兴看到解决这个问题的任何想法,或者至少是这种奇怪行为的可能原因。

这是用于构建可执行文件的命令行。命令由 CMake 生成。我只添加 --whole_archive 选项,然后删除可执行文件并重新运行命令。我也希望您能原谅我用“???”替换所有项目特定名称。

exec_name - 我们正在讨论的可执行文件的名称
lib_name - 我们正在讨论的库的名称

/usr/bin/c++ - g++ v4.4 可执行文件的符号链接

/usr/bin/c++ -Wextra -g -fPIC CMakeFiles/exec_dir.dir/main.cpp.o CMakeFiles/exec_dir.dir/options.cpp.o CMakeFiles/exec_dir.dir/runtime.cpp.o CMakeFiles/ exec_dir.dir/plugins.cpp.o CMakeFiles/exec_dir.dir/CServer.cpp.o -o exec_name -rdynamic ../lib/???/lib???.a --whole-archive ../.. /lib/???/???/lib_name.a ../lib/???/lib???.so ../../lib/???/???/lib???. a ../../???/???/lib???.a ../../lib/???/lib???.a -ldl -lboost_filesystem -lboost_signals -lboost_system -lboost_thread 。 ./../lib/???/lib???.so /usr/local/ssl/lib64/libcrypto.so -ldl -luuid -lodbc ../lib/log/lib???.so .. /lib/config/lib???a -lpthread ../../???/???/lib???.a -Wl,-rpath,/home/beduin/???/build/deb /???/lib/???:/home/beduin/???/build/deb/lib/???:/usr/local/ssl/lib64

【问题讨论】:

  • --whole-archive 和 -rdynamic is 解决这个问题的方法 - 你能显示生成可执行文件的命令行吗?
  • 我已将命令行添加到问题中。
  • 试试-rdynamic -Wl,-whole-archive <all your libs> -Wl,-no-whole-archive <boost, pthread and so on> - 看起来您的某个库不在 --whole-archive 中
  • 有效!谢谢您的帮助!我是 StackOverflow 的新手,有什么办法可以扩大您的声誉吗?以及如何通过再次修改我的帖子来标记正确答案?
  • @beduin:我会发布一个答案 - 然后你可以接受它

标签: c++ linker g++


【解决方案1】:

使用-rdynamic -Wl,-whole-archive <all your libs> -Wl,-no-whole-archive <boost, pthread and so on> - 您的其中一个库不在--whole-archive

【讨论】:

  • 一个建议:解释为什么-whole-archive 有帮助。类似于 Stackexchange 的网站不仅仅是为发布问题的人提供可用资源。一般来说,除了发布原始问题的个人之外,我没有看到很多对任何人都有帮助的单行答案。
  • -whole-archive 是否会转储标记为隐藏的符号?我的可执行文件大小增加了很多。
猜你喜欢
  • 2010-12-25
  • 2013-05-05
  • 2010-12-16
  • 1970-01-01
  • 2019-02-11
  • 2012-07-06
  • 2013-06-24
  • 2020-04-09
  • 2011-06-07
相关资源
最近更新 更多