lundi 11 avril 2022

Undefined Symbol at Runtime

We compile and link our code using CMake 3.18 on Ubuntu 18.04. The structure of the program is this:

There's an application with a main function, which loads a shared library at runtime, say lib_a.so. At runtime, this library loads two other libraries, lib_b.so and lib_c.so and uses symbols from them. lib_b.so uses symbols from lib_c.so as well.

lib_b.so and lib_c.so are compiled from submodules B and C of A.

On some systems the code runs fine. On some systems, however, we get undefined symbol error, which looks like this when the symbol that can't be found is demangled using c++filt:

Unable to load lib_a.so : lib_b.so: undefined symbol: D::E::Get(std::initializer_list<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >)

Namespace D and class D::E are under a submodule of C. This submodule doesn't contain a CMakeLists.txt, and no shared or static library is produced from it. Its a directory, which contains source and header files only.

When we look at the defined symbols of lib_c.so using nm --defined-only lib_c.so, we see that there's this symbol:

D::E::Get(std::initializer_list<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)

Our G++ version is 7.5.0, and CMake version is 3.18.0.

From this, we gather this is a CXX11 ABI issue. So, these are the things that we tried, separately:

  • Adding add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=1), before defining the target, to the CMakeLists.txt that compiles and links lib_b.so.

  • Adding set (CMAKE_CXX_STANDARD 11), before defining the target, to the CMakeLists.txt that compiles and links lib_a.so. As this is the top module, we thought this would set c++ standard to 11 for all of its submodules.

  • Adding target_compile_features(target PUBLIC cxx_std_11), before defining the target, to the CMakeLists.txt that compiles and links lib_b.so.

None of solved the problem. Also, there's no change. lib_b.so looks for the same symbol, again.

However, when we write a Makefile that compiles the sources and links the shared libraries as told, the problem disappears.

Aucun commentaire:

Enregistrer un commentaire