]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
CMake: With symbol versioning, try to pass --undefined-version to linker
authorLasse Collin <lasse.collin@tukaani.org>
Wed, 21 May 2025 13:07:01 +0000 (16:07 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 21 May 2025 13:07:01 +0000 (16:07 +0300)
Fixes: https://github.com/tukaani-project/xz/issues/180
Fixes: https://bugs.gentoo.org/956119
CMakeLists.txt

index 5c11503465a593f327a32685b674a277d7b7d436..4e1499f7e4d70131dac57f1c1a506376bfd55744 100644 (file)
@@ -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"
     )