build: add Mold linker compatibility

Mold handles several linker features differently from ld.bfd:

- --exclude-libs,ALL hides .symver-aliased symbols (e.g. rados_*)
  even when the version script lists them as global. Detect Mold
  (via USING_MOLD_LINKER) and disable --exclude-libs; version
  scripts already control symbol visibility.

- Duplicate symbols across static archives are treated as errors.
  Merge crimson-alien-common into crimson-alienstore as a single
  archive. For crimson-osd, link crimson-alienstore before
  crimson-common with --allow-multiple-definition so the alien
  thread's non-crimson definitions win (Mold picks first definition).

- Python/Cython extension builds (via Distutils.cmake) invoked the
  system default linker. Pass -fuse-ld= via MOLD_FUSE_LD_FLAG so
  extensions link with the configured linker.

- Add rados_* and _rados_* to librados.map global section for Mold
  compatibility with .symver aliases.

Co-authored-by: Mark Kogan <mkogan@redhat.com>
Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
This commit is contained in:
Ronen Friedman 2026-06-28 14:42:07 +00:00
parent 1605266614
commit e552441619
5 changed files with 66 additions and 20 deletions

View File

@ -202,3 +202,12 @@ try_compile(HAVE_LINK_EXCLUDE_LIBS
${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_LIST_DIR}/CephCheck_link.c
LINK_LIBRARIES "-Wl,--exclude-libs,ALL")
# Mold linker applies --exclude-libs after version script processing,
# which hides .symver-aliased symbols (e.g. rados_*) even when the
# version script lists them as global. Disable --exclude-libs for Mold;
# version scripts already control symbol visibility.
if(HAVE_LINK_EXCLUDE_LIBS AND USING_MOLD_LINKER)
message(STATUS "Mold linker -- disabling --exclude-libs (incompatible with .symver)")
set(HAVE_LINK_EXCLUDE_LIBS FALSE CACHE INTERNAL "" FORCE)
endif()

View File

@ -72,7 +72,11 @@ function(distutils_add_cython_module target name src)
list(APPEND PY_CPPFLAGS -D'__Pyx_check_single_interpreter\(ARG\)=ARG\#\#0')
set(PY_CC ${compiler_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1})
set(PY_CXX ${compiler_launcher} ${CMAKE_CXX_COMPILER} ${cxx_compiler_arg1})
set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared")
if(USING_MOLD_LINKER)
set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared" "${MOLD_FUSE_LD_FLAG}")
else()
set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared")
endif()
string(REPLACE " " ";" PY_LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
list(APPEND PY_LDFLAGS -L${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
@ -117,7 +121,11 @@ function(distutils_install_cython_module name)
get_property(compiler_launcher GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
get_property(link_launcher GLOBAL PROPERTY RULE_LAUNCH_LINK)
set(PY_CC "${compiler_launcher} ${CMAKE_C_COMPILER}")
set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared")
if(USING_MOLD_LINKER)
set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared ${MOLD_FUSE_LD_FLAG}")
else()
set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared")
endif()
set(PY_LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
cmake_parse_arguments(DU "DISABLE_VTA" "" "" ${ARGN})
if(DU_DISABLE_VTA AND HAS_VTA)

View File

@ -30,11 +30,6 @@ if(WITH_CEPH_DEBUG_MUTEX)
${PROJECT_SOURCE_DIR}/src/common/condition_variable_debug.cc
${PROJECT_SOURCE_DIR}/src/common/shared_mutex_debug.cc)
endif()
add_library(crimson-alien-common STATIC
${crimson_alien_common_srcs})
if(WITH_BREAKPAD)
target_link_libraries(crimson-alien-common Breakpad::client)
endif()
set(alien_store_srcs
alien_store.cc
@ -65,20 +60,32 @@ set(alien_store_srcs
${PROJECT_SOURCE_DIR}/src/os/bluestore/OnodeScan.cc
${PROJECT_SOURCE_DIR}/src/os/memstore/MemStore.cc)
# Merge alienstore + alien-common into a single archive. The common sources
# are compiled without WITH_CRIMSON and duplicate symbols in crimson-common.
# ld.bfd resolves these by archive order; Mold treats them as errors.
# After building, localize the duplicate symbols so they resolve internally
# within this archive (for the alien/bluestore thread) while crimson-osd's
# own references resolve from crimson-common (for seastar threads).
add_library(crimson-alienstore STATIC
${alien_store_srcs})
${alien_store_srcs}
${crimson_alien_common_srcs})
if(WITH_LTTNG)
add_dependencies(crimson-alienstore bluestore-tp)
endif()
if(WITH_BREAKPAD)
target_link_libraries(crimson-alienstore PRIVATE Breakpad::client)
endif()
# For crimson-alienstore WITH_CRIMSON is not defined
target_link_libraries(crimson-alienstore
PRIVATE
seastar
${FMT_LIB}
kv
heap_profiler
crimson-alien-common
${BLKID_LIBRARIES}
${UDEV_LIBRARIES}
blk)
# Mold duplicate-symbol handling is done at the crimson-osd link step
# (see src/crimson/osd/CMakeLists.txt) by ordering crimson-alienstore
# before crimson-common with --allow-multiple-definition.

View File

@ -70,16 +70,36 @@ if(HAS_VTA)
set_source_files_properties(main.cc
PROPERTIES COMPILE_FLAGS -fno-var-tracking-assignments)
endif()
target_link_libraries(crimson-osd
legacy-option-headers
crimson-admin
crimson-common
crimson-os
crimson
erasure_code
${FMT_LIB}
Boost::MPL
dmclock::dmclock)
if(USING_MOLD_LINKER AND WITH_BLUESTORE)
# With Mold, duplicate symbols between crimson-alienstore and crimson-common
# must be resolved in favor of crimson-alienstore (compiled without
# WITH_CRIMSON) so the alien thread uses the classic code paths.
# Link crimson-alienstore BEFORE crimson-common so its definitions win
# with --allow-multiple-definition (Mold picks first definition).
target_link_libraries(crimson-osd
legacy-option-headers
crimson-admin
crimson-alienstore
crimson-common
crimson-os
crimson
erasure_code
${FMT_LIB}
Boost::MPL
dmclock::dmclock)
target_link_options(crimson-osd PRIVATE -Wl,--allow-multiple-definition)
else()
target_link_libraries(crimson-osd
legacy-option-headers
crimson-admin
crimson-common
crimson-os
crimson
erasure_code
${FMT_LIB}
Boost::MPL
dmclock::dmclock)
endif()
set_target_properties(crimson-osd PROPERTIES
POSITION_INDEPENDENT_CODE ${EXE_LINKER_USE_PIE})
install(TARGETS crimson-osd DESTINATION bin)

View File

@ -1,5 +1,7 @@
LIBRADOS_PRIVATE {
global:
rados_*;
_rados_*;
extern "C++" {
"guard variable for boost::asio::detail::call_stack<boost::asio::detail::strand_executor_service::strand_impl, unsigned char>::top_";
"guard variable for boost::asio::detail::call_stack<boost::asio::detail::strand_service::strand_impl, unsigned char>::top_";