From f0239936532d40be05e75384c37fb8d6c1bb4ff6 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Wed, 21 May 2025 16:07:01 +0300 Subject: [PATCH] CMake: With symbol versioning, try to pass --undefined-version to linker Fixes: https://github.com/tukaani-project/xz/issues/180 Fixes: https://bugs.gentoo.org/956119 --- CMakeLists.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c115034..4e1499f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ include(CheckSymbolExists) include(CheckStructHasMember) include(CheckCSourceCompiles) include(CheckCCompilerFlag) +include(CheckLinkerFlag) include(cmake/tuklib_large_file_support.cmake) include(cmake/tuklib_integer.cmake) include(cmake/tuklib_cpucores.cmake) @@ -556,6 +557,21 @@ symbol versioning (${SUPPORTED_SYMBOL_VERSIONING_VARIANTS})") set(SYMBOL_VERSIONING "generic") endif() endif() + + if(NOT SYMBOL_VERSIONING STREQUAL "no") + # If features are disabled in liblzma, some symbols may be missing. + # LLVM's lld defaults to --no-undefined-version and the build breaks + # if not all symbols in the version script exist. That is good for + # catching errors like typos, but in our case the downside is too big. + # Avoid the problem by using --undefined-version if the linker + # supports it. + # + # GNU ld has had --no-undefined-version for a long time but it's not + # the default. The opposite option --undefined-version was only added + # in 2022, thus we must use --undefined-version conditionally. + check_linker_flag(C "-Wl,--undefined-version" + HAVE_LINKER_FLAG_UNDEFINED_VERSION) + endif() endif() set(LIBLZMA_API_HEADERS @@ -1480,6 +1496,9 @@ elseif(BUILD_SHARED_LIBS AND SYMBOL_VERSIONING STREQUAL "linux") # NOTE: Set it explicitly to 1 to make it clear that versioning is # done unconditionally in the C files. target_compile_definitions(liblzma PRIVATE HAVE_SYMBOL_VERSIONS_LINUX=1) + if(HAVE_LINKER_FLAG_UNDEFINED_VERSION) + target_link_options(liblzma PRIVATE "-Wl,--undefined-version") + endif() target_link_options(liblzma PRIVATE "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_linux.map" ) @@ -1487,6 +1506,9 @@ elseif(BUILD_SHARED_LIBS AND SYMBOL_VERSIONING STREQUAL "linux") LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_linux.map" ) elseif(BUILD_SHARED_LIBS AND SYMBOL_VERSIONING STREQUAL "generic") + if(HAVE_LINKER_FLAG_UNDEFINED_VERSION) + target_link_options(liblzma PRIVATE "-Wl,--undefined-version") + endif() target_link_options(liblzma PRIVATE "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_generic.map" )