链接的可执行文件中静态库中缺少符号
我遇到链接可执行文件中缺少静态库符号的问题。 这是我的问题的描述:
我有从几个目标文件构建的静态库。这些目标文件提供了几组符号,与以下各项相关联:
- 一组 C 函数和结构(多个目标文件)。我们将相应的符号称为level1符号。
- 此 C 函数和结构的一组 C++ 包装类(另一个目标文件)。我们将相应的符号称为level2符号。
- 一组 C++ 包装类继承自 2 级类(另一个目标文件),具有扩展功能。我们将相应的符号称为 level3 符号。
地下 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/???:/家/beduin/???/build/deb/lib/???:/usr/local/ssl/lib64
I have a problem with static library symbols missed in linked executable.
Here is the description of my problem:
I have static library built from several object files. These object files provides sevaral groups of symbols, associated with:
- A set of C functions and structs (several object files). Let's call corresponding symbols level1 symbols.
- A set of C++ wrapper classes for this C functions and structs (another object file). Let's call corresponding symbols level2 symbols.
- A set of C++ wrapper classes inhereted from level 2 classes (another object file) with extended functionality. Let's call corresponding symbols level3 symbols.
Undeground C code uses several other project and external libs. Some of them are static, so currently this lib is static too.
Library is linked with executable file. This file used directly only level2 symbols from lib. But some dynamic libraries loaded by this executable during execution needs level3 symbols.
The problem is, that level3 symbols for some reason are missed into this executable(nm approved).
Library itself contains all groups of symbols. ALso there is another executable linked with this library and it also contains all groups of symbols. The main difference between these executables is that second executable (where all symbols are presented) uses leve3 symbols directly.
The whole project is built with CMake in debug configuration (this means "-g" option is presented in g++ commands). The underlying OS is GNU/Linux x86_64. g++ version is 4.4.
I've checked several similiar questions on StackOverflow but I haven't found any acceptable solution.
I've already tried several linking options to solve the problem (--export-dynamic, --whole_archive) but neither helps.
I'll be glad to see any ideas to solve this problem or, at least, possible reasons of this strange behaviour.
This is command line used to build executable. Command was generated by CMake. I only add --whole_archive option, then delete executable and rerun command. I also hope you will excuse me for replacing all project specific names with "???".
exec_name - name of executable we are talking about
lib_name - name of library we are talking about
/usr/bin/c++ - symlink to g++ v4.4 executable
/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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用
-rdynamic -Wl,-whole-archive; -Wl,-no-whole-archive
- 您的某个库不在--whole-archive
内Use
-rdynamic -Wl,-whole-archive <all your libs> -Wl,-no-whole-archive <boost, pthread and so on>
- one of your libs aren't within--whole-archive