CMake: Refactor XZ_SYMBOL_VERSIONING to match configure.ac

Make the available options and their behavior match
--enable-symbol-versions in configure.ac.

Don't enable symbol versions on Linux if not using glibc. Previously
the generic variant was selected on Microblaze or if using NVHPC
without checking that libc is glibc.

Leave the cache variable to "auto" or "yes" if that was specified
instead of setting it to the autodetected value by default. A downside
is that one cannot easily see which variant the autodetection code
has selected. The same applies to XZ_SANDBOX and XZ_THREADS though.
This commit is contained in:
Lasse Collin 2024-06-20 21:53:03 +03:00
parent cc52ef8ed3
commit 188143a50a
1 changed files with 73 additions and 48 deletions

View File

@ -416,35 +416,42 @@ endif()
option(BUILD_SHARED_LIBS "Build liblzma as a shared library instead of static") option(BUILD_SHARED_LIBS "Build liblzma as a shared library instead of static")
# Symbol versioning is supported ELF shared libraries on certain OSes.
# First assume that symbol versioning isn't supported.
set(SYMBOL_VERSIONING "no")
if(NOT WIN32) if(NOT WIN32)
# Symbol versioning only affects ELF shared libraries. The option is # The XZ_SYMBOL_VERSIONING option is ignored for static libraries but
# ignored for static libraries. # we keep the option visible still in case the project is reconfigured
# to build a shared library.
# #
# Determine the default value so that it's always set with # auto Autodetect between no, generic, and linux
# shared libraries in mind which helps if the build dir is reconfigured # yes Force on by autodetecting between linux and generic
# from static to shared libs without resetting the cache variables. # no Disable symbol versioning
set(SYMBOL_VERSIONING_DEFAULT OFF) # generic FreeBSD, most Linux/glibc systems, and GNU/Hurd
# linux Linux/glibc with extra symbol versions for compatibility
# with binaries that have been linked against a liblzma version
# that has been patched with "xz-5.2.2-compat-libs.patch" from
# RHEL/CentOS 7.
set(SUPPORTED_SYMBOL_VERSIONING_VARIANTS auto yes no generic linux)
set(XZ_SYMBOL_VERSIONING "auto" CACHE STRING "Enable ELF shared library \
symbol versioning (${SUPPORTED_SYMBOL_VERSIONING_VARIANTS})")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND # Show a dropdown menu in CMake GUI:
(CMAKE_SYSTEM_PROCESSOR MATCHES "[Mm]icro[Bb]laze" OR set_property(CACHE XZ_SYMBOL_VERSIONING
CMAKE_C_COMPILER_ID STREQUAL "NVHPC")) PROPERTY STRINGS "${SUPPORTED_SYMBOL_VERSIONING_VARIANTS}")
# As a special case, GNU/Linux on MicroBlaze gets the generic
# symbol versioning because GCC 12 doesn't support the __symver__
# attribute on MicroBlaze. On Linux, CMAKE_SYSTEM_PROCESSOR comes
# from "uname -m" for native builds (should be "microblaze") or from
# the CMake toolchain file (not perfectly standardized but it very
# likely has "microblaze" in lower case or mixed case somewhere in
# the string).
#
# NVIDIA HPC Compiler doesn't support symbol versioning but
# it uses the linked from the system so the linker script
# can still be used to get the generic symbol versioning.
set(SYMBOL_VERSIONING_DEFAULT "generic")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") if(NOT XZ_SYMBOL_VERSIONING IN_LIST SUPPORTED_SYMBOL_VERSIONING_VARIANTS)
# GNU/Linux-specific symbol versioning for shared liblzma. message(FATAL_ERROR "'${XZ_SYMBOL_VERSIONING}' is not a supported "
# This includes a few extra compatibility symbols for RHEL/CentOS 7 "symbol versioning variant")
# which are pointless on non-glibc non-Linux systems. endif()
if(NOT XZ_SYMBOL_VERSIONING STREQUAL "auto" AND
NOT XZ_SYMBOL_VERSIONING STREQUAL "yes")
# Autodetection was disabled. Use the user-specified value as is.
set(SYMBOL_VERSIONING "${XZ_SYMBOL_VERSIONING}")
else()
# Autodetect the symbol versioning variant.
# #
# Avoid symvers on Linux with non-glibc like musl and uClibc. # Avoid symvers on Linux with non-glibc like musl and uClibc.
# In Autoconf it's enough to check that $host_os equals linux-gnu # In Autoconf it's enough to check that $host_os equals linux-gnu
@ -453,6 +460,7 @@ if(NOT WIN32)
# #
# This check is here for now since it's not strictly required # This check is here for now since it's not strictly required
# by anything else. # by anything else.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
check_c_source_compiles( check_c_source_compiles(
"#include <features.h> "#include <features.h>
#if defined(__GLIBC__) && !defined(__UCLIBC__) #if defined(__GLIBC__) && !defined(__UCLIBC__)
@ -462,21 +470,38 @@ if(NOT WIN32)
#endif #endif
" "
IS_LINUX_WITH_GLIBC) IS_LINUX_WITH_GLIBC)
else()
if(IS_LINUX_WITH_GLIBC) set(IS_LINUX_WITH_GLIBC OFF)
set(SYMBOL_VERSIONING_DEFAULT "linux")
endif() endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") if(IS_LINUX_WITH_GLIBC AND
set(SYMBOL_VERSIONING_DEFAULT "generic") (CMAKE_SYSTEM_PROCESSOR MATCHES "[Mm]icro[Bb]laze" OR
CMAKE_C_COMPILER_ID STREQUAL "NVHPC"))
# As a special case, GNU/Linux on MicroBlaze gets the generic
# symbol versioning because GCC 12 doesn't support the __symver__
# attribute on MicroBlaze. On Linux, CMAKE_SYSTEM_PROCESSOR comes
# from "uname -m" for native builds (should be "microblaze") or
# from the CMake toolchain file (not perfectly standardized but
# it very likely has "microblaze" in lower case or mixed case
# somewhere in the string).
#
# NVIDIA HPC Compiler doesn't support symbol versioning but
# it uses the linked from the system so the linker script
# can still be used to get the generic symbol versioning.
set(SYMBOL_VERSIONING "generic")
elseif(IS_LINUX_WITH_GLIBC)
# GNU/Linux-specific symbol versioning for shared liblzma. This
# includes a few extra compatibility symbols for RHEL/CentOS 7
# which are pointless on non-glibc non-Linux systems.
set(SYMBOL_VERSIONING "linux")
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "GNU" OR
XZ_SYMBOL_VERSIONING STREQUAL "yes")
set(SYMBOL_VERSIONING "generic")
endif()
endif() endif()
set(XZ_SYMBOL_VERSIONING "${SYMBOL_VERSIONING_DEFAULT}" CACHE STRING
"Enable ELF shared library symbol versioning (OFF, generic, linux)")
# Show a dropdown menu in CMake GUI:
set_property(CACHE XZ_SYMBOL_VERSIONING
PROPERTY STRINGS "OFF;generic;linux")
endif() endif()
set(LIBLZMA_API_HEADERS set(LIBLZMA_API_HEADERS
@ -1362,7 +1387,7 @@ if(WIN32)
# Disable __declspec(dllimport) when linking against static liblzma. # Disable __declspec(dllimport) when linking against static liblzma.
target_compile_definitions(liblzma INTERFACE LZMA_API_STATIC) target_compile_definitions(liblzma INTERFACE LZMA_API_STATIC)
endif() endif()
elseif(BUILD_SHARED_LIBS AND XZ_SYMBOL_VERSIONING STREQUAL "linux") elseif(BUILD_SHARED_LIBS AND SYMBOL_VERSIONING STREQUAL "linux")
# Note that adding link options doesn't affect static builds # Note that adding link options doesn't affect static builds
# but HAVE_SYMBOL_VERSIONS_LINUX must not be used with static builds # but HAVE_SYMBOL_VERSIONS_LINUX must not be used with static builds
# because it would put symbol versions into the static library which # because it would put symbol versions into the static library which
@ -1378,7 +1403,7 @@ elseif(BUILD_SHARED_LIBS AND XZ_SYMBOL_VERSIONING STREQUAL "linux")
set_target_properties(liblzma PROPERTIES set_target_properties(liblzma PROPERTIES
LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_linux.map" LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_linux.map"
) )
elseif(BUILD_SHARED_LIBS AND XZ_SYMBOL_VERSIONING STREQUAL "generic") elseif(BUILD_SHARED_LIBS AND SYMBOL_VERSIONING STREQUAL "generic")
target_link_options(liblzma PRIVATE target_link_options(liblzma PRIVATE
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_generic.map" "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/liblzma/liblzma_generic.map"
) )