diff --git a/components/core/CMakeLists.txt b/components/core/CMakeLists.txt index d7f1df3938..66271113f8 100644 --- a/components/core/CMakeLists.txt +++ b/components/core/CMakeLists.txt @@ -123,7 +123,8 @@ if(PROJECT_IS_TOP_LEVEL) # Include dependency settings if the project isn't being included as a subproject. # NOTE: We mark the file optional since it's not required if the user happens to have the # dependencies installed already. - include("${CMAKE_SOURCE_DIR}/../../build/deps/core/cmake-settings/all.cmake" + set(CLP_CORE_DEPS_DIR "${CMAKE_SOURCE_DIR}/../../build/deps/core") + include("${CLP_CORE_DEPS_DIR}/cmake-settings/all.cmake" OPTIONAL RESULT_VARIABLE CLP_DEPS_SETTINGS_FILE_PATH ) @@ -308,31 +309,16 @@ if(CLP_NEED_ZSTD) endif() endif() -# Find and setup LZMA Library -# TODO: Add a script in ./cmake/Modules to properly import LZMA in find_package()'s module mode -if(CLP_NEED_LZMA) +if(CLP_NEED_LIBLZMA) if(CLP_USE_STATIC_LIBS) - set(LIBLZMA_USE_STATIC_LIBS ON) - endif() - find_package(LibLZMA REQUIRED) - if(LIBLZMA_FOUND) - message(STATUS "Found Lzma ${LIBLZMA_VERSION_STRING}") - message(STATUS "Lzma library location: ${LIBLZMA_LIBRARIES}") - message(STATUS "Lzma Include Dir: ${LIBLZMA_INCLUDE_DIRS}") - - # Version 5.8.1 and above address CVE-2024-3094 and CVE-2025-31115. - set(REQUIRED_LIBLZMA_VERSION "5.8.1") - if(LIBLZMA_VERSION_STRING VERSION_LESS ${REQUIRED_LIBLZMA_VERSION}) - message( - FATAL_ERROR - "Detected LibLZMA version ${LIBLZMA_VERSION_STRING} is older than required" - " ${REQUIRED_LIBLZMA_VERSION}" - ) - endif() + set(LibLZMA_ROOT ${LibLZMA-static_ROOT}) + set(LibLZMA_USE_STATIC_LIBS ON) else() - message(FATAL_ERROR "Could not find ${CLP_LIBS_STRING} libraries for Lzma") + set(LibLZMA_ROOT ${LibLZMA-shared_ROOT}) endif() - include_directories(${LIBLZMA_INCLUDE_DIRS}) + # Version 5.8.1 and above address CVE-2024-3094 and CVE-2025-31115. + find_package(LibLZMA 5.8.1 REQUIRED) + message(STATUS "Found LibLZMA ${LibLZMA_VERSION}") endif() # sqlite dependencies @@ -759,6 +745,7 @@ if(CLP_BUILD_TESTING) fmt::fmt log_surgeon::log_surgeon LibArchive::LibArchive + LibLZMA::LibLZMA MariaDBClient::MariaDBClient ${MONGOCXX_TARGET} nlohmann_json::nlohmann_json @@ -771,7 +758,6 @@ if(CLP_BUILD_TESTING) clp::string_utils ystdlib::containers ystdlib::error_handling - ${LIBLZMA_LIBRARIES} ${zstd_TARGET} ) target_compile_features(unitTest diff --git a/components/core/cmake/Modules/FindLibLZMA.cmake b/components/core/cmake/Modules/FindLibLZMA.cmake new file mode 100644 index 0000000000..60e3488f49 --- /dev/null +++ b/components/core/cmake/Modules/FindLibLZMA.cmake @@ -0,0 +1,96 @@ +# Try to find LibLZMA +# NOTE: The FindLibLZMA.cmake included with CMake has no support for static libraries, so we use our +# own. +# +# Set LibLZMA_USE_STATIC_LIBS=ON to look for static libraries. +# +# Once done, this will define: +# LibLZMA_FOUND - Whether the library was found on the system +# LibLZMA_INCLUDE_DIR - The library include directories +# LibLZMA_LIBRARY - The path to the library file +# LibLZMA_VERSION - The version of the library installed on the system +# +# Conventions: +# - Variables only for use within the script are prefixed with "liblzma_" +# - Variables that should be externally visible are prefixed with "LibLZMA_" + +set(liblzma_HEADER "lzma.h") +set(liblzma_LIBNAME "lzma") +set(liblzma_PKGCONFIG_NAME "liblzma") + +if(DEFINED CLP_CORE_DEPS_DIR) + set(ENV{liblzma_ORIG_PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}") + set(ENV{PKG_CONFIG_PATH} "${CLP_CORE_DEPS_DIR}:$ENV{PKG_CONFIG_PATH}") +endif() + +# Run pkg-config +find_package(PkgConfig) +pkg_check_modules(liblzma_PKGCONF QUIET "${liblzma_PKGCONFIG_NAME}") + +# Set include directory +find_path(LibLZMA_INCLUDE_DIR ${liblzma_HEADER} + HINTS ${liblzma_PKGCONF_INCLUDEDIR} + PATH_SUFFIXES include + ) + +# Handle static libraries +if(LibLZMA_USE_STATIC_LIBS) + set(liblzma_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}") +endif() + +# Find library +find_library(LibLZMA_LIBRARY + NAMES "${liblzma_LIBNAME}" + HINTS ${liblzma_PKGCONF_LIBDIR} + PATH_SUFFIXES lib + ) + +if(LibLZMA_USE_STATIC_LIBS) + # Restore original value of CMAKE_FIND_LIBRARY_SUFFIXES + set(CMAKE_FIND_LIBRARY_SUFFIXES ${liblzma_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(liblzma_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() + +# Set version +set(LibLZMA_VERSION ${liblzma_PKGCONF_VERSION}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibLZMA + REQUIRED_VARS LibLZMA_LIBRARY LibLZMA_INCLUDE_DIR + VERSION_VAR LibLZMA_VERSION + ) + +if(NOT TARGET LibLZMA::LibLZMA) + # Add library to build + if (LibLZMA_USE_STATIC_LIBS) + add_library(LibLZMA::LibLZMA STATIC IMPORTED) + else() + # NOTE: We use UNKNOWN so that if the user doesn't have the SHARED + # libraries installed, we can still use the STATIC libraries + add_library(LibLZMA::LibLZMA UNKNOWN IMPORTED) + endif() + + # Set include directories for library + if(LibLZMA_INCLUDE_DIR) + set_target_properties(LibLZMA::LibLZMA + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LibLZMA_INCLUDE_DIR}" + ) + endif() + + # Set location of library + if(EXISTS "${LibLZMA_LIBRARY}") + set_target_properties(LibLZMA::LibLZMA + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${LibLZMA_LIBRARY}" + ) + endif() +endif() + +# Restore original value of PKG_CONFIG_PATH +if(DEFINED CLP_CORE_DEPS_DIR) + set(ENV{PKG_CONFIG_PATH} "$ENV{liblzma_ORIG_PKG_CONFIG_PATH}") + unset(ENV{liblzma_ORIG_PKG_CONFIG_PATH}) +endif() diff --git a/components/core/cmake/Options/options.cmake b/components/core/cmake/Options/options.cmake index cc46c03234..42edf242e1 100644 --- a/components/core/cmake/Options/options.cmake +++ b/components/core/cmake/Options/options.cmake @@ -171,8 +171,8 @@ function(set_clp_tests_dependencies) CLP_NEED_DATE CLP_NEED_FMT CLP_NEED_LIBARCHIVE + CLP_NEED_LIBLZMA CLP_NEED_LOG_SURGEON - CLP_NEED_LZMA CLP_NEED_MARIADB CLP_NEED_MONGOCXX CLP_NEED_NLOHMANN_JSON @@ -455,9 +455,9 @@ function (convert_clp_dependency_properties_to_variables) CLP_NEED_CURL CLP_NEED_DATE CLP_NEED_FMT - CLP_NEED_LOG_SURGEON CLP_NEED_LIBARCHIVE - CLP_NEED_LZMA + CLP_NEED_LIBLZMA + CLP_NEED_LOG_SURGEON CLP_NEED_MARIADB CLP_NEED_MONGOCXX CLP_NEED_MSGPACKCXX diff --git a/taskfiles/deps/main.yaml b/taskfiles/deps/main.yaml index bbd75a46eb..3b42015956 100644 --- a/taskfiles/deps/main.yaml +++ b/taskfiles/deps/main.yaml @@ -66,6 +66,7 @@ tasks: - task: "catch2" - task: "date" - task: "fmt" + - task: "liblzma" - task: "log-surgeon" - task: "lz4" - task: "microsoft.gsl" @@ -221,6 +222,54 @@ tasks: TARBALL_SHA256: "1250e4cc58bf06ee631567523f48848dc4596133e163f02615c97f78bab6c811" TARBALL_URL: "https://github.com/fmtlib/fmt/archive/refs/tags/10.2.1.tar.gz" + liblzma: + internal: true + vars: + COMMON_CMAKE_GEN_ARGS: + - "-DBUILD_TESTING=OFF" + - "-DCMAKE_BUILD_TYPE=Release" + - "-DCMAKE_INSTALL_MESSAGE=LAZY" + - "-DXZ_DOC=OFF" + - "-DXZ_TOOL_LZMADEC=OFF" + - "-DXZ_TOOL_LZMAINFO=OFF" + - "-DXZ_TOOL_SCRIPTS=OFF" + - "-DXZ_TOOL_SYMLINKS_LZMA=OFF" + - "-DXZ_TOOL_XZ=OFF" + - "-DXZ_TOOL_XZDEC=OFF" + TARBALL_SHA256: "507825b599356c10dca1cd720c9d0d0c9d5400b9de300af00e4d1ea150795543" + TARBALL_URL: "https://github.com/tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1.tar.gz" + run: "once" + deps: + - task: "liblzma-install" + vars: + BUILD_SHARED_LIBS: true + COMMON_CMAKE_GEN_ARGS: + ref: ".COMMON_CMAKE_GEN_ARGS" + TARBALL_SHA256: "{{.TARBALL_SHA256}}" + TARBALL_URL: "{{.TARBALL_URL}}" + - task: "liblzma-install" + vars: + BUILD_SHARED_LIBS: false + COMMON_CMAKE_GEN_ARGS: + ref: ".COMMON_CMAKE_GEN_ARGS" + TARBALL_SHA256: "{{.TARBALL_SHA256}}" + TARBALL_URL: "{{.TARBALL_URL}}" + + liblzma-install: + internal: true + requires: + vars: ["BUILD_SHARED_LIBS", "COMMON_CMAKE_GEN_ARGS", "TARBALL_SHA256", "TARBALL_URL"] + cmds: + - task: "utils:install-remote-cmake-lib" + vars: + CMAKE_GEN_ARGS: + - "-DBUILD_SHARED_LIBS={{ if .BUILD_SHARED_LIBS }}ON{{ else }}OFF{{ end }}" + - >- + {{ join " " .COMMON_CMAKE_GEN_ARGS }} + LIB_NAME: "LibLZMA-{{ if .BUILD_SHARED_LIBS }}shared{{ else }}static{{ end }}" + TARBALL_SHA256: "{{.TARBALL_SHA256}}" + TARBALL_URL: "{{.TARBALL_URL}}" + log-surgeon: internal: true run: "once"