Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing symbols from static library in linked executable

Tags:

c++

g++

linker

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:

  1. A set of C functions and structs (several object files). Let's call corresponding symbols level1 symbols.
  2. A set of C++ wrapper classes for this C functions and structs (another object file). Let's call corresponding symbols level2 symbols.
  3. 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

like image 296
beduin Avatar asked Oct 12 '22 06:10

beduin


1 Answers

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

like image 170
Erik Avatar answered Oct 21 '22 05:10

Erik