]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cmake: link librados applications against ceph-common 47029/head
authorKefu Chai <tchaikov@gmail.com>
Sat, 9 Jul 2022 11:32:03 +0000 (07:32 -0400)
committerKefu Chai <tchaikov@gmail.com>
Sat, 9 Jul 2022 13:02:04 +0000 (21:02 +0800)
to address link failures like:

[100%] Linking CXX executable ../../../bin/unittest_global_doublefree
/opt/rh/gcc-toolset-12/root/usr/bin/ld: /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/libstdc++_nonshared.a(sstream-inst80.o): undefined reference to symbol '_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21'
/opt/rh/gcc-toolset-12/root/usr/bin/ld: /usr/lib64/libstdc++.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

this happens when using gcc-toolset to build the tree.

because neither librados.so nor libcephfs exposes libstdc++ symbols
to executable linking against it. while CMake uses "c++" to link
C++ executables. the "c++" executable comes from GTS links the C++
executables agaist
/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/libstdc++.so,
which in turn is a ld script:

```
$ cat /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/libstdc++.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
INPUT ( /usr/lib64/libstdc++.so.6 -lstdc++_nonshared )
```

but the thing is, stdc++_nonshared references some symbols
provided by libstdc++.so.6, and it is listed before it. that's
why "ld" is not able to resolve the referenced symbols used by
the executable, despite that they are provided by libstdc++ in
this case.

in this change, ceph-common is added to the linkage of executables
linked against librados and/or libcephfs, even the executables
in question does not reference ceph-common symbols. unlike librados,
libcephfs and librgw, ceph-common is an internal library, which does
not hide *any* symbols from its consumer, it is also able to provide
symbols from C++ standard library linked by it. so, in our case,
we can link the C++ executables against ceph-common for accessing
the C++ standard library. the reason why we don't link aginst libstdc++
explictly is that, we should leave this to the C++ compiler instead of
referencing a specific C++ standard library explictly by its name.
what if user wants to link against libc++ instead of libstdc++?
another fix could be to remove '-Wl,--as-needed' linker options
from the command line linking the librados applications, so the linker
does not ignore the symbols from libstdc++ when resolving the ones
referenced by stdc++_nonshared, but that would be complicated.

please note, linking against ceph-common does not change the linkage
of

* Ceph executables compiled using non-gcc-toolset toolchain, because we
  always pass '-Wl,--as-needed' to "c++" when linking executables,
  so "ld" should be able to drop ceph-common even we instruct it
  to link against ceph-common. so it would be a no-op in this case.
* 3rd party librados executables compiled using non-gcc-toolset toolchain,
  but linked against librados compiled using gcc-toolset toolchain.
  because they still link against the /usr/lib64/libstdc++.so.6, when
  these executables are compiled and linked. and librados is always
  able to access libceph-common. so librados is safe.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
src/test/CMakeLists.txt
src/test/common/CMakeLists.txt

index 54c49970ebc6772929ae29feb51bed9a3661fafd..d61ee22dfd640dcb9d7993f0a5a7f7181c04413d 100644 (file)
@@ -134,7 +134,7 @@ endif(WITH_RADOSGW)
 if(WITH_LIBCEPHFS)
   # From src/test/Makefile-client.am: I dont get this one... testing the osdc build but link in libcephfs?
   add_executable(test_build_libcephfs buildtest_skeleton.cc)
-  target_link_libraries(test_build_libcephfs cephfs pthread ${CRYPTO_LIBS} ${EXTRALIBS})
+  target_link_libraries(test_build_libcephfs cephfs pthread ceph-common ${CRYPTO_LIBS} ${EXTRALIBS})
 endif(WITH_LIBCEPHFS)
 
 add_executable(test_build_librados buildtest_skeleton.cc)
index dba313ac396ed28e9e816d243a1f03f215d76428..28738c090853822cbaa121379179afd5169c087d 100644 (file)
@@ -300,7 +300,7 @@ if(WITH_CEPHFS)
     test_global_doublefree.cc
     )
   add_ceph_unittest(unittest_global_doublefree)
-  target_link_libraries(unittest_global_doublefree cephfs librados)
+  target_link_libraries(unittest_global_doublefree cephfs librados ceph-common)
 endif(WITH_CEPHFS)
 
 if(NOT WIN32)