diff --git a/CMakeLists.txt b/CMakeLists.txt index c179607f7..b2ba952ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ option(OPENZL_ALLOW_INTROSPECTION "Allow introspection" ON) option(OPENZL_INSTALL "Install OpenZL" ON) option(OPENZL_CPP_INSTALL "Install C++ bindings" ${OPENZL_INSTALL}) option(OPENZL_BUILD_PYTHON_DEMO "Build openzl_demo Python extension" ${OPENZL_BUILD_ALL}) +option(OPENZL_USE_SYSTEM_ZSTD "Use system-installed zstd library instead of bundled" OFF) # Fine-grained control of build directories that can be disabled. # NOTE: Disabling some but not all of these may break the build, use with caution. diff --git a/build-scripts/cmake/openzl-config.cmake.in b/build-scripts/cmake/openzl-config.cmake.in index 60a354f6f..7aa200458 100644 --- a/build-scripts/cmake/openzl-config.cmake.in +++ b/build-scripts/cmake/openzl-config.cmake.in @@ -14,6 +14,11 @@ include(CMakeFindDependencyMacro) +# Ensure zstd is available when openzl was built with system zstd +if (@OPENZL_USE_SYSTEM_ZSTD@) + find_dependency(zstd CONFIG REQUIRED) +endif() + set_and_check(OPENZL_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") set_and_check(OPENZL_CMAKE_DIR "@PACKAGE_CMAKE_INSTALL_DIR@") diff --git a/build-scripts/cmake/openzl-deps.cmake b/build-scripts/cmake/openzl-deps.cmake index 59b691a2d..a83a17a31 100644 --- a/build-scripts/cmake/openzl-deps.cmake +++ b/build-scripts/cmake/openzl-deps.cmake @@ -18,82 +18,99 @@ endif() set(ZSTD_LEGACY_SUPPORT OFF) -# Two-tier zstd dependency resolution with automated hash verification -# 1. Git submodule (matches Makefile behavior) -# 2. FetchContent + URL (no git required, cryptographically verified) - -set(ZSTD_VERSION "1.5.7") -set(ZSTD_DIRNAME "zstd-${ZSTD_VERSION}") -set(ZSTD_TARBALL_SHA256 "eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3") -set(ZSTD_EXPECTED_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd/lib/zstd.h") -set(ZSTD_EXPECTED_CMAKE "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd/build/cmake/CMakeLists.txt") - -# Helper function to check if zstd is available and working -function(check_zstd_available RESULT_VAR) - if(EXISTS "${ZSTD_EXPECTED_HEADER}" AND EXISTS "${ZSTD_EXPECTED_CMAKE}") - set(${RESULT_VAR} TRUE PARENT_SCOPE) +if(OPENZL_USE_SYSTEM_ZSTD) + message(STATUS "Using system-installed zstd (OPENZL_USE_SYSTEM_ZSTD=ON)") + find_package(zstd CONFIG REQUIRED) + + # Create 'libzstd' alias for compatibility, preferring static library + if(TARGET zstd::libzstd_static) + add_library(libzstd ALIAS zstd::libzstd_static) + message(STATUS "Found system zstd: using zstd::libzstd_static") + elseif(TARGET zstd::libzstd_shared) + add_library(libzstd ALIAS zstd::libzstd_shared) + message(STATUS "Found system zstd: using zstd::libzstd_shared") else() - set(${RESULT_VAR} FALSE PARENT_SCOPE) + message(FATAL_ERROR "System zstd package found but no suitable target (zstd::libzstd_static or zstd::libzstd_shared) available") endif() -endfunction() - -message(STATUS "Attempting zstd dependency resolution...") - -# Check if zstd is already available -check_zstd_available(ZSTD_AVAILABLE) -if(ZSTD_AVAILABLE) - message(STATUS "zstd dependency already present") + list(APPEND OPENZL_LINK_LIBRARIES libzstd) else() - # Tier 1: Git Submodule (existing approach, matches Makefile) - message(STATUS "Tier 1: Trying git submodule...") - execute_process( - COMMAND git submodule update --init --single-branch --depth 1 deps/zstd - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE GIT_SUBMOD_RESULT - OUTPUT_QUIET ERROR_QUIET - ) - + # Two-tier zstd dependency resolution with automated hash verification + # 1. Git submodule (matches Makefile behavior) + # 2. FetchContent + URL (no git required, cryptographically verified) + + set(ZSTD_VERSION "1.5.7") + set(ZSTD_DIRNAME "zstd-${ZSTD_VERSION}") + set(ZSTD_TARBALL_SHA256 "eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3") + set(ZSTD_EXPECTED_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd/lib/zstd.h") + set(ZSTD_EXPECTED_CMAKE "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd/build/cmake/CMakeLists.txt") + + # Helper function to check if zstd is available and working + function(check_zstd_available RESULT_VAR) + if(EXISTS "${ZSTD_EXPECTED_HEADER}" AND EXISTS "${ZSTD_EXPECTED_CMAKE}") + set(${RESULT_VAR} TRUE PARENT_SCOPE) + else() + set(${RESULT_VAR} FALSE PARENT_SCOPE) + endif() + endfunction() + + message(STATUS "Attempting zstd dependency resolution...") + + # Check if zstd is already available check_zstd_available(ZSTD_AVAILABLE) -endif() + if(ZSTD_AVAILABLE) + message(STATUS "zstd dependency already present") + else() + # Tier 1: Git Submodule (existing approach, matches Makefile) + message(STATUS "Tier 1: Trying git submodule...") + execute_process( + COMMAND git submodule update --init --single-branch --depth 1 deps/zstd + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE GIT_SUBMOD_RESULT + OUTPUT_QUIET ERROR_QUIET + ) + + check_zstd_available(ZSTD_AVAILABLE) + endif() -# Tier 2: FetchContent + URL with Hash Verification -if(NOT ZSTD_AVAILABLE) - message(STATUS "Tier 1 failed. Tier 2: Trying FetchContent with verified tarball...") + # Tier 2: FetchContent + URL with Hash Verification + if(NOT ZSTD_AVAILABLE) + message(STATUS "Tier 1 failed. Tier 2: Trying FetchContent with verified tarball...") - include(FetchContent) + include(FetchContent) - # Clean up any partial downloads first - file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd") - file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/deps/${ZSTD_DIRNAME}") + # Clean up any partial downloads first + file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd") + file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/deps/${ZSTD_DIRNAME}") - message(STATUS "Using hash verification for tarball download") - FetchContent_Declare(zstd_tarball - URL https://github.com/facebook/zstd/releases/download/v${ZSTD_VERSION}/${ZSTD_DIRNAME}.tar.gz - URL_HASH SHA256=${ZSTD_TARBALL_SHA256} - DOWNLOAD_EXTRACT_TIMESTAMP ON - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd" - ) + message(STATUS "Using hash verification for tarball download") + FetchContent_Declare(zstd_tarball + URL https://github.com/facebook/zstd/releases/download/v${ZSTD_VERSION}/${ZSTD_DIRNAME}.tar.gz + URL_HASH SHA256=${ZSTD_TARBALL_SHA256} + DOWNLOAD_EXTRACT_TIMESTAMP ON + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd" + ) - FetchContent_MakeAvailable(zstd_tarball) - check_zstd_available(ZSTD_AVAILABLE) -endif() + FetchContent_MakeAvailable(zstd_tarball) + check_zstd_available(ZSTD_AVAILABLE) + endif() -# Final check -if(NOT ZSTD_AVAILABLE) - message(FATAL_ERROR "Failed to obtain zstd dependency through all available methods (git submodule, FetchContent+tarball)") -endif() + # Final check + if(NOT ZSTD_AVAILABLE) + message(FATAL_ERROR "Failed to obtain zstd dependency through all available methods (git submodule, FetchContent+tarball)") + endif() -message(STATUS "zstd dependency resolved successfully") + message(STATUS "zstd dependency resolved successfully") -# Set zstd build options before making it available -set(ZSTD_BUILD_PROGRAMS OFF CACHE BOOL "") -set(ZSTD_BUILD_CONTRIB OFF CACHE BOOL "") -set(ZSTD_BUILD_TESTS OFF CACHE BOOL "") + # Set zstd build options before making it available + set(ZSTD_BUILD_PROGRAMS OFF CACHE BOOL "") + set(ZSTD_BUILD_CONTRIB OFF CACHE BOOL "") + set(ZSTD_BUILD_TESTS OFF CACHE BOOL "") -# Add zstd subdirectory directly instead of using FetchContent -add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd/build/cmake" zstd_build) -# Note: find_package not needed when using add_subdirectory - targets are directly available -list(APPEND OPENZL_LINK_LIBRARIES libzstd) + # Add zstd subdirectory directly instead of using FetchContent + add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/deps/zstd/build/cmake" zstd_build) + # Note: find_package not needed when using add_subdirectory - targets are directly available + list(APPEND OPENZL_LINK_LIBRARIES libzstd) +endif() find_library(MATH_LIBRARY m) if(MATH_LIBRARY) diff --git a/tools/parquet/CMakeLists.txt b/tools/parquet/CMakeLists.txt index 68675ef54..f064737b4 100644 --- a/tools/parquet/CMakeLists.txt +++ b/tools/parquet/CMakeLists.txt @@ -3,8 +3,10 @@ if (OPENZL_BUILD_PARQUET_TOOLS) set(ARROW_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/arrow_ep") - # Point arrow to the zstd build directory - list(APPEND CMAKE_PREFIX_PATH "${zstd_BINARY_DIR}") + # Point arrow to the bundled zstd build directory + if(NOT OPENZL_USE_SYSTEM_ZSTD) + list(APPEND CMAKE_PREFIX_PATH "${zstd_BINARY_DIR}") + endif() set(ARROW_CMAKE_ARGS -DARROW_PARQUET=ON