When building internal libraries statically with `-DENABLE_SHARED=no`,
linking `librados.a` always fails because the
`LIBRADOS_C_API_DEFAULT_F` macro inserts an underscore prefix to all
exported symbols. It does this so a versioned symbol with the real
name can be created. Symbol versions however only work with shared
libraries, and the linker fails to find the prefix-less symbols:
FAILED: bin/ceph_radosacl
: && /usr/bin/c++ -O0 -fPIC -fuse-ld=mold -Og -g -rdynamic src/tools/CMakeFiles/ceph_radosacl.dir/radosacl.cc.o -o bin/ceph_radosacl -Wl,-rpath,::::::::::::::::::::::::::::::: lib/liblibrados.a lib/libglobal.a lib/liblibrados_impl.a lib/libosdc.a lib/libcls_lock_client.a lib/libceph-common.a /usr/lib/aarch64-linux-gnu/libblkid.so /usr/lib/aarch64-linux-gnu/libcrypto.so lib/libjson_spirit.a lib/libcommon_utf8.a lib/libextblkdev.a -lcap boost/lib/libboost_thread.a boost/lib/libboost_chrono.a boost/lib/libboost_atomic.a boost/lib/libboost_system.a boost/lib/libboost_random.a boost/lib/libboost_program_options.a boost/lib/libboost_date_time.a boost/lib/libboost_iostreams.a boost/lib/libboost_regex.a lib/libfmtd.a lib/liberasure_code.a /usr/lib/aarch64-linux-gnu/libudev.so /usr/lib/aarch64-linux-gnu/libz.so -ldl /usr/lib/aarch64-linux-gnu/librt.a -lresolv -Wl,--as-needed -latomic && :
mold: error: undefined symbol: rados_conf_parse_env
>>> referenced by librados_cxx.cc
>>> lib/liblibrados.a(librados_cxx.cc.o):(librados::v14_2_0::Rados::conf_parse_env(char const*) const)
mold: error: undefined symbol: rados_nobjects_list_seek
>>> referenced by librados_cxx.cc
>>> lib/liblibrados.a(librados_cxx.cc.o):(librados::NObjectIteratorImpl::seek(unsigned int))
mold: error: undefined symbol: rados_conf_parse_argv_remainder
>>> referenced by librados_cxx.cc
>>> lib/liblibrados.a(librados_cxx.cc.o):(librados::v14_2_0::Rados::conf_parse_argv_remainder(int, char const**, char const**) const)
mold: error: undefined symbol: rados_version
>>> referenced by librados_cxx.cc
>>> lib/liblibrados.a(librados_cxx.cc.o):(librados::v14_2_0::Rados::version(int*, int*, int*))
mold: error: undefined symbol: rados_nobjects_list_next2
>>> referenced by librados_c.cc
>>> lib/liblibrados.a(librados_c.cc.o):(_rados_nobjects_list_next)
>>> referenced by librados_cxx.cc
>>> lib/liblibrados.a(librados_cxx.cc.o):(librados::NObjectIteratorImpl::get_next())
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
set_property(TARGET librados APPEND_STRING PROPERTY
LINK_FLAGS " -static-libstdc++ -static-libgcc")
endif()
+ target_compile_definitions(librados PRIVATE -DLIBRADOS_SHARED=1)
endif()
target_link_libraries(librados PRIVATE
librados_impl osdc ceph-common cls_lock_client
#define tracepoint(...)
#endif
-#if defined(HAVE_ASM_SYMVER) || defined(HAVE_ATTR_SYMVER)
+#if defined(LIBRADOS_SHARED) && (defined(HAVE_ASM_SYMVER) || defined(HAVE_ATTR_SYMVER))
// prefer __attribute__() over global asm(".symver"). because the latter
// is not parsed by the compiler and is partitioned away by GCC if
// lto-partitions is enabled, in other words, these asm() statements