From 47de001a9b9e7f60251d53e937021cc25f5ba8d9 Mon Sep 17 00:00:00 2001 From: Yunze Xu Date: Sun, 9 Oct 2022 13:53:01 +0800 Subject: [PATCH 1/3] [fix] Force static libraries to be linked when LINK_STATIC is enabled ### Motivation Currently, even with `LINK_STATIC=ON` option, dynamic libraries could still be linked. For example, on macOS, the following libcurl library will be found: ``` /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/lib/libcurl.tbd ``` Then, the `libpulsar.dylib` will link to `/usr/lib/libcurl.4.dylib`, which is not a dynamic library. ### Modifications When `LINK_STATIC` is enabled, change `CMAKE_FIND_LIBRARY_SUFFIXES` to `.a` for non-MSVC compilers so that only static libraries could be found except OpenSSL, which should not be linked statically. In addition, use `find_package` as much as possible instead of raw usages of `find_path` and `find_library`. --- CMakeLists.txt | 92 ++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 59 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3876f89..868ea750 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ add_definitions(-DLOG_CATEGORY_NAME=${LOG_CATEGORY_NAME} -DBUILDING_PULSAR -DBOO set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} /usr/lib64/) +find_package(OpenSSL REQUIRED) ### This part is to find and keep SSL dynamic libs in RECORD_OPENSSL_SSL_LIBRARY and RECORD_OPENSSL_CRYPTO_LIBRARY ### After find the libs, will unset related cache, and will not affect another same call to find_package. if (APPLE) @@ -135,6 +136,8 @@ set(OPENSSL_USE_STATIC_LIBS FALSE) find_package(OpenSSL REQUIRED) set(RECORD_OPENSSL_SSL_LIBRARY ${OPENSSL_SSL_LIBRARY}) set(RECORD_OPENSSL_CRYPTO_LIBRARY ${OPENSSL_CRYPTO_LIBRARY}) +message("RECORD_OPENSSL_SSL_LIBRARY: " ${RECORD_OPENSSL_SSL_LIBRARY}) +message("RECORD_OPENSSL_CRYPTO_LIBRARY: " ${RECORD_OPENSSL_CRYPTO_LIBRARY}) unset(OPENSSL_FOUND CACHE) unset(OPENSSL_INCLUDE_DIR CACHE) @@ -145,18 +148,38 @@ unset(OPENSSL_SSL_LIBRARIES CACHE) unset(OPENSSL_LIBRARIES CACHE) unset(OPENSSL_VERSION CACHE) +find_package(OpenSSL REQUIRED) +message("OPENSSL_INCLUDE_DIR: " ${OPENSSL_INCLUDE_DIR}) +message("OPENSSL_SSL_LIBRARY: " ${OPENSSL_SSL_LIBRARY}) +message("OPENSSL_CRYPTO_LIBRARY: " ${OPENSSL_CRYPTO_LIBRARY}) + +# For dependencies other than OpenSSL, dynamic libraries are forbidden to link when LINK_STATIC is ON +if (LINK_STATIC) + if (NOT MSVC) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + endif() +endif () + +find_package(Boost REQUIRED) +message("Boost_INCLUDE_DIRS: " ${Boost_INCLUDE_DIRS}) + +find_package(Protobuf REQUIRED) +message("Protobuf_INCLUDE_DIRS: " ${Protobuf_INCLUDE_DIRS}) +message("Protobuf_LIBRARIES: " ${Protobuf_LIBRARIES}) + +find_package(curl REQUIRED) +message("CURL_INCLUDE_DIRS: " ${CURL_INCLUDE_DIRS}) +message("CURL_LIBRARIES: " ${CURL_LIBRARIES}) + +find_package(zlib REQUIRED) +message("ZLIB_INCLUDE_DIRS: " ${ZLIB_INCLUDE_DIRS}) +message("ZLIB_LIBRARIES: " ${ZLIB_LIBRARIES}) + if (LINK_STATIC) - find_library(ZLIB_LIBRARIES REQUIRED NAMES libz.a z zlib) - message(STATUS "ZLIB_LIBRARIES: ${ZLIB_LIBRARIES}") - find_library(Protobuf_LIBRARIES NAMES libprotobuf.a libprotobuf) - message(STATUS "Protobuf: ${Protobuf_LIBRARIES}") - find_library(CURL_LIBRARIES NAMES libcurl.a curl curl_a libcurl_a) - message(STATUS "CURL_LIBRARIES: ${CURL_LIBRARIES}") find_library(LIB_ZSTD NAMES libzstd.a) message(STATUS "ZStd: ${LIB_ZSTD}") find_library(LIB_SNAPPY NAMES libsnappy.a) message(STATUS "LIB_SNAPPY: ${LIB_SNAPPY}") - set(COMMON_LIBS ${Protobuf_LIBRARIES} ${COMMON_LIBS}) if (USE_LOG4CXX) if (LOG4CXX_USE_DYNAMIC_LIBS) @@ -180,43 +203,9 @@ if (LINK_STATIC) add_definitions(-DCURL_STATICLIB) endif() - if (UNIX AND NOT APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() - SET(Boost_USE_STATIC_LIBS ON) SET(OPENSSL_USE_STATIC_LIBS TRUE) else() - # Link to shared libraries - find_package(ZLIB REQUIRED) - set(ZLIB_LIBRARIES ${ZLIB_LIBRARIES}) - # NOTE: The default MODULE mode may not find debug libraries so use CONFIG mode here - unset(Protobuf_INCLUDE_DIRS CACHE) - unset(Protobuf_LIBRARIES CACHE) - find_package(Protobuf QUIET CONFIG) - # NOTE: On Windows x86 platform, Protobuf_FOUND might be set false but Protobuf_INCLUDE_DIRS and - # Protobuf_LIBRARIES are both found. - if (Protobuf_INCLUDE_DIRS AND Protobuf_LIBRARIES AND NOT Protobuf_FOUND) - set(Protobuf_FOUND TRUE) - endif () - if (Protobuf_FOUND) - message("Found Protobuf in config mode") - message(STATUS "Protobuf_LIBRARIES: ${Protobuf_LIBRARIES}") - message(STATUS "Protobuf_INCLUDE_DIRS: ${Protobuf_INCLUDE_DIRS}") - else () - message("Failed to find Protobuf in config mode, try to find it from system path") - find_library(Protobuf_LIBRARIES protobuf libprotobuf) - find_path(Protobuf_INCLUDE_DIRS google/protobuf/stubs/common.h) - message(STATUS "Protobuf_LIBRARIES: ${Protobuf_LIBRARIES}") - message(STATUS "Protobuf_INCLUDE_DIRS: ${Protobuf_INCLUDE_DIRS}") - endif () - - if (${Protobuf_FOUND} AND (${CMAKE_VERSION} VERSION_GREATER 3.8)) - set(COMMON_LIBS protobuf::libprotobuf ${COMMON_LIBS}) - else () - set(COMMON_LIBS ${Protobuf_LIBRARIES} ${COMMON_LIBS}) - endif () - if (MSVC AND (${CMAKE_BUILD_TYPE} STREQUAL Debug)) find_library(LIB_ZSTD zstdd HINTS "${VCPKG_DEBUG_ROOT}/lib") else () @@ -228,20 +217,12 @@ else() find_library(LIB_SNAPPY NAMES snappy libsnappy) endif () - find_package(CURL REQUIRED) - if (${CMAKE_VERSION} VERSION_GREATER "3.12") - set(COMMON_LIBS ${COMMON_LIBS} CURL::libcurl) - endif () - if (USE_LOG4CXX) find_library(LOG4CXX_LIBRARY_PATH log4cxx) find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h) endif (USE_LOG4CXX) endif (LINK_STATIC) - -find_package(Boost) - if (Boost_MAJOR_VERSION EQUAL 1 AND Boost_MINOR_VERSION LESS 69) # Boost System does not require linking since 1.69 set(BOOST_COMPONENTS ${BOOST_COMPONENTS} system) @@ -269,8 +250,6 @@ endif() find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -find_package(OpenSSL REQUIRED) - if (BUILD_TESTS) find_path(GTEST_INCLUDE_PATH gtest/gtest.h) find_path(GMOCK_INCLUDE_PATH gmock/gmock.h) @@ -314,7 +293,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include ${AUTOGEN_DIR} - ${Boost_INCLUDE_DIR} + ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} @@ -329,6 +308,8 @@ set(COMMON_LIBS Threads::Threads ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY} + ${Boost_DATE_TIME_LIBRARY} + ${Protobuf_LIBRARIES} ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} @@ -336,13 +317,6 @@ set(COMMON_LIBS ${CMAKE_DL_LIBS} ) -if (MSVC) - set(COMMON_LIBS - ${COMMON_LIBS} - ${Boost_DATE_TIME_LIBRARY} - ) -endif() - if (NOT MSVC) set(COMMON_LIBS ${COMMON_LIBS} m) else() From e47a448556ffa8039a335301357ba9bf12545639 Mon Sep 17 00:00:00 2001 From: Yunze Xu Date: Sun, 9 Oct 2022 15:20:33 +0800 Subject: [PATCH 2/3] Find curl and zlib manually --- CMakeLists.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 868ea750..264b7bde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,13 +167,28 @@ find_package(Protobuf REQUIRED) message("Protobuf_INCLUDE_DIRS: " ${Protobuf_INCLUDE_DIRS}) message("Protobuf_LIBRARIES: " ${Protobuf_LIBRARIES}) -find_package(curl REQUIRED) +# NOTE: CMake might not find curl and zlib on some platforms like Ubuntu, in this case, find them manually +find_package(curl QUIET) +if (NOT CURL_FOUND) + find_path(CURL_INCLUDE_DIRS NAMES curl/curl.h) + find_library(CURL_LIBRARIES NAMES curl curllib libcurl_imp curllib_static libcurl) +endif () message("CURL_INCLUDE_DIRS: " ${CURL_INCLUDE_DIRS}) message("CURL_LIBRARIES: " ${CURL_LIBRARIES}) +if (NOT CURL_INCLUDE_DIRS OR NOT CURL_LIBRARIES) + message(FATAL_ERROR "Could not find libcurl") +endif () -find_package(zlib REQUIRED) +find_package(zlib QUIET) +if (NOT ZLIB_FOUND) + find_path(ZLIB_INCLUDE_DIRS NAMES zlib.h) + find_library(ZLIB_LIBRARIES NAMES z zlib zdll zlib1 zlibstatic) +endif () message("ZLIB_INCLUDE_DIRS: " ${ZLIB_INCLUDE_DIRS}) message("ZLIB_LIBRARIES: " ${ZLIB_LIBRARIES}) +if (NOT ZLIB_INCLUDE_DIRS OR NOT ZLIB_LIBRARIES) + message(FATAL_ERROR "Could not find zlib") +endif () if (LINK_STATIC) find_library(LIB_ZSTD NAMES libzstd.a) From f0c571cb311a5227bd75fd7ec5a5b283efad5a29 Mon Sep 17 00:00:00 2001 From: Yunze Xu Date: Sun, 9 Oct 2022 17:04:26 +0800 Subject: [PATCH 3/3] Fix Windows build --- .github/workflows/ci-pr-validation.yaml | 4 +--- CMakeLists.txt | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-pr-validation.yaml b/.github/workflows/ci-pr-validation.yaml index 083d61d1..229e6fa7 100644 --- a/.github/workflows/ci-pr-validation.yaml +++ b/.github/workflows/ci-pr-validation.yaml @@ -146,7 +146,6 @@ jobs: -G "${{ matrix.generator }}" ${{ matrix.arch }} \ -DBUILD_TESTS=OFF \ -DVCPKG_TRIPLET=${{ matrix.triplet }} \ - -DCMAKE_BUILD_TYPE=Release \ -S . fi @@ -166,7 +165,6 @@ jobs: -G "${{ matrix.generator }}" ${{ matrix.arch }} \ -DBUILD_TESTS=OFF \ -DVCPKG_TRIPLET=${{ matrix.triplet }} \ - -DCMAKE_BUILD_TYPE=Release \ -DBUILD_STATIC_LIB=OFF \ -S . fi @@ -265,4 +263,4 @@ jobs: cache-to: type=gha,mode=max - name: Build APK packages - run: pkg/apk/docker-build-apk-x86_64.sh build-apk-x86_64:latest \ No newline at end of file + run: pkg/apk/docker-build-apk-x86_64.sh build-apk-x86_64:latest diff --git a/CMakeLists.txt b/CMakeLists.txt index 264b7bde..cd7eaff7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ MESSAGE(STATUS "LINK_STATIC: " ${LINK_STATIC}) option(USE_LOG4CXX "Build with Log4cxx support" OFF) MESSAGE(STATUS "USE_LOG4CXX: " ${USE_LOG4CXX}) -IF (CMAKE_BUILD_TYPE STREQUAL "") +IF (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo) ENDIF () @@ -168,6 +168,7 @@ message("Protobuf_INCLUDE_DIRS: " ${Protobuf_INCLUDE_DIRS}) message("Protobuf_LIBRARIES: " ${Protobuf_LIBRARIES}) # NOTE: CMake might not find curl and zlib on some platforms like Ubuntu, in this case, find them manually +set(CURL_NO_CURL_CMAKE ON) find_package(curl QUIET) if (NOT CURL_FOUND) find_path(CURL_INCLUDE_DIRS NAMES curl/curl.h)