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.
CodePudding user response:
Turns out this was a third-party library issue.
As @Someprogrammerdude suggested, running CMake with VERBOSE=1 revealed that lib_b.so is linked with -D_GLIBCXX_USE_CXX11_ABI=0.
I changed it manually in B/CMakeFiles/B.dir/flags.cmake to -D_GLIBCXX_USE_CXX11_ABI=1. This time the previous error is gone.
This, however, gave another undefined symbol error with cxx11_abi regarding one of the third-party libraries that we use.
Updating the library to a version that's compiled with CXX11 ABI resolved the issue.