From 7b1444979094a365c82c665cce0e2ebc6b69467b Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 4 Aug 2024 13:52:44 +0200 Subject: [PATCH] cmake: add support for versioned symbols option Implement the `--enable-versioned-symbols` feature available in `./configure` for CMake. Enable with `-DCURL_LIBCURL_VERSIONED_SYMBOLS=ON`. Customize the version prefix with `-DCURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX=MYPREFIX_`. By default the prefix matches what autotools uses. When enabled, the feature is detected and a warning shown if unavailable. (E.g. on Apple and Windows, it isn't.) Included `HIDDEN {};` to match autotools, though I don't know if it's necessary, useful or making any difference. Differences from the autotools implementation: - soversion is dynamic instead of hard-coded. - omits referencing non-curl symbols. - allows prefix/flavour override. - more universal feature detection. - doesn't rely on the in-repo `lib/libcurl.vers.in` file. Also: - add mbedTLS and BearSSL versioned symbol prefix support to autotools. - enable this option in an old-linux job. Follow-up to 7cc2e8b349df28d55d5f40bfae323485df9f0cf2 Fixes #14349 Closes #14378 --- .github/workflows/linux-old.yml | 7 ++++-- configure.ac | 4 +++ lib/CMakeLists.txt | 43 ++++++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux-old.yml b/.github/workflows/linux-old.yml index 0aec21683c..4f266b69a4 100644 --- a/.github/workflows/linux-old.yml +++ b/.github/workflows/linux-old.yml @@ -81,7 +81,8 @@ jobs: run: | mkdir bld-1 cd bld-1 - cmake .. -DCMAKE_UNITY_BUILD=ON -DCURL_WERROR=ON -DBUILD_SHARED_LIBS=ON -DENABLE_ARES=OFF -DCURL_ZSTD=OFF -DCURL_USE_GSSAPI=OFF -DCURL_USE_LIBSSH2=ON -DCURL_USE_LIBSSH=OFF + cmake .. -DCMAKE_UNITY_BUILD=ON -DCURL_WERROR=ON -DBUILD_SHARED_LIBS=ON \ + -DENABLE_ARES=OFF -DCURL_ZSTD=OFF -DCURL_USE_GSSAPI=OFF -DCURL_USE_LIBSSH2=ON -DCURL_USE_LIBSSH=OFF make install src/curl --disable --version @@ -89,7 +90,9 @@ jobs: run: | mkdir bld-cares cd bld-cares - cmake .. -DCMAKE_UNITY_BUILD=ON -DCURL_WERROR=ON -DBUILD_SHARED_LIBS=ON -DENABLE_ARES=ON -DCURL_ZSTD=ON -DCURL_USE_GSSAPI=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON + cmake .. -DCMAKE_UNITY_BUILD=ON -DCURL_WERROR=ON -DBUILD_SHARED_LIBS=ON \ + -DENABLE_ARES=ON -DCURL_ZSTD=ON -DCURL_USE_GSSAPI=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON \ + -DCURL_LIBCURL_VERSIONED_SYMBOLS=ON - name: 'build' run: | diff --git a/configure.ac b/configure.ac index 5b0ab4e4a7..056efbe89a 100644 --- a/configure.ac +++ b/configure.ac @@ -2495,6 +2495,10 @@ AS_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shar versioned_symbols_flavour="MULTISSL_" elif test "x$OPENSSL_ENABLED" = "x1"; then versioned_symbols_flavour="OPENSSL_" + elif test "x$MBEDTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="MBEDTLS_" + elif test "x$BEARSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="BEARSSL_" elif test "x$GNUTLS_ENABLED" = "x1"; then versioned_symbols_flavour="GNUTLS_" elif test "x$WOLFSSL_ENABLED" = "x1"; then diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 0f721278cc..35f30f8725 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -212,18 +212,59 @@ if(BUILD_SHARED_LIBS) endif() option(CURL_LIBCURL_SOVERSION "Enable libcurl SOVERSION" ${_soversion_default}) + option(CURL_LIBCURL_VERSIONED_SYMBOLS "Enable libcurl versioned symbols" OFF) - if(CURL_LIBCURL_SOVERSION) + if(CURL_LIBCURL_SOVERSION OR CURL_LIBCURL_VERSIONED_SYMBOLS) # Get 'VERSIONCHANGE', 'VERSIONADD', 'VERSIONDEL', 'VERSIONINFO' variables transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake") include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake) math(EXPR _cmakesoname "${VERSIONCHANGE} - ${VERSIONDEL}") set(_cmakeversion "${_cmakesoname}.${VERSIONDEL}.${VERSIONADD}") + endif() + if(CURL_LIBCURL_SOVERSION) set_target_properties(${LIB_SHARED} PROPERTIES VERSION "${_cmakeversion}" SOVERSION "${_cmakesoname}") endif() + + ## Versioned symbols + + if(CURL_LIBCURL_VERSIONED_SYMBOLS) + if(NOT DEFINED CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX) + # Default to prefixes used by autotools + if(CURL_WITH_MULTI_SSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "MULTISSL_") + elseif(CURL_USE_OPENSSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "OPENSSL_") + elseif(CURL_USE_MBEDTLS) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "MBEDTLS_") + elseif(CURL_USE_BEARSSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "BEARSSL_") + elseif(CURL_USE_WOLFSSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "WOLFSSL_") + elseif(CURL_USE_GNUTLS) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "GNUTLS_") + endif() + endif() + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers" " + HIDDEN {}; + CURL_${CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX}${_cmakesoname} + { + global: curl_*; + local: *; + };") + include(CheckCSourceCompiles) + set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers") + check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSIONED_SYMBOLS) + if(HAVE_VERSIONED_SYMBOLS) + # Superseded by LINK_OPTIONS in CMake 3.13 and later. + set_target_properties(${LIB_SHARED} PROPERTIES LINK_FLAGS "${CMAKE_REQUIRED_LINK_OPTIONS}") + else() + message(WARNING "Versioned symbols requested, but not supported by the toolchain.") + endif() + unset(CMAKE_REQUIRED_LINK_OPTIONS) + endif() endif() add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})