From: Ronen Friedman Date: Sun, 28 Jun 2026 14:42:07 +0000 (+0000) Subject: build: add Mold linker compatibility X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e55244161992640e2e4a487b1cbaa702f2cebf43;p=ceph.git 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 Signed-off-by: Ronen Friedman --- diff --git a/cmake/modules/CephChecks.cmake b/cmake/modules/CephChecks.cmake index 4da4dfad5bf..9506a4db220 100644 --- a/cmake/modules/CephChecks.cmake +++ b/cmake/modules/CephChecks.cmake @@ -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() diff --git a/cmake/modules/Distutils.cmake b/cmake/modules/Distutils.cmake index 37b2efa7457..9d5dd33fcef 100644 --- a/cmake/modules/Distutils.cmake +++ b/cmake/modules/Distutils.cmake @@ -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) diff --git a/src/crimson/os/alienstore/CMakeLists.txt b/src/crimson/os/alienstore/CMakeLists.txt index 6a227cfdb87..0c87e1505e5 100644 --- a/src/crimson/os/alienstore/CMakeLists.txt +++ b/src/crimson/os/alienstore/CMakeLists.txt @@ -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. diff --git a/src/crimson/osd/CMakeLists.txt b/src/crimson/osd/CMakeLists.txt index 7e06215a6eb..a15adf049cc 100644 --- a/src/crimson/osd/CMakeLists.txt +++ b/src/crimson/osd/CMakeLists.txt @@ -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) diff --git a/src/librados/librados.map b/src/librados/librados.map index 279a0ba0691..96dd5072d94 100644 --- a/src/librados/librados.map +++ b/src/librados/librados.map @@ -1,5 +1,7 @@ LIBRADOS_PRIVATE { global: + rados_*; + _rados_*; extern "C++" { "guard variable for boost::asio::detail::call_stack::top_"; "guard variable for boost::asio::detail::call_stack::top_";