The dictionary-builder sources (lib/dictBuilder) are about to start moving
to Rust, beginning with divsufsort. The Rust crate previously only modeled
the compression/decompression module split plus the forced-HUF decoder
modes, so no build could express "this C configuration includes (or
excludes) dictBuilder" to Cargo. Without that, a Rust archive could carry
dictBuilder modules into a build whose C side disabled them, or worse,
omit a migrated implementation from a build whose C shims require it.
Add a `dict-builder` cargo feature and thread it through every build that
consumes the Rust static archive, mirroring exactly how each build system
already gates the dictBuilder C sources:
- rust/Cargo.toml: new `dict-builder` feature, included in the default
set because the C library builds dictBuilder by default
(ZSTD_LIB_DICTBUILDER ?= 1). The feature is empty until the first
dictBuilder module lands.
- lib/Makefile: RUST_CARGO_FEATURES gains dict-builder when
ZSTD_LIB_DICTBUILDER is enabled, following the existing
ZSTD_LIB_COMPRESSION/ZSTD_LIB_DECOMPRESSION pattern. The archive
directory naming grows a matching `b<0|1>` dimension
(c1-d1-b1-default etc.) so differently configured archives never
collide; the repeated config prefix is factored into
RUST_MODULE_CONFIG.
- programs/Makefile: the full-featured archives now request
compression,decompression,dict-builder (equal to the default set, so
the target directory stays shared with tests). The partial-library
variants gain the `b0` name dimension, and zstd-dictBuilder gets its
own lib-c1-d0-b1 archive because it compiles the dictBuilder C sources
without decompression; it previously shared the compression-only
archive, which will lack the migrated dictBuilder symbols.
- tests/Makefile: no flag change needed since tests use the crate default
feature set; a comment now records that dict-builder arrives that way.
- build/cmake/lib/CMakeLists.txt: ZSTD_BUILD_DICTBUILDER now adds the
dict-builder feature and a `b<0|1>` component in the Rust build-config
directory name, in lockstep with the DictBuilderSources gating.
- build/meson/lib/meson.build: meson compiles the dictBuilder sources
unconditionally, so the feature list and config name gain dict-builder
unconditionally (c1-d1-b1-<huf-mode>).
The `dict-builder` feature deliberately does not imply `compression`.
lib/Makefile forces ZSTD_LIB_DICTBUILDER=0 when compression is disabled,
but CMake does not couple the two options, so encoding the C-side
constraint in Cargo would make the Rust archive diverge from the C source
list in that (already unsupported) CMake configuration.
Test plan:
- cd rust && cargo build --release
- cargo build --release --no-default-features \
--features compression,decompression
- cargo build --release --no-default-features \
--features compression,dict-builder
- Full validation (fuzzer, smoke tests, dictionary byte-identity) runs
with the follow-up commit that ports divsufsort onto this scaffolding.
476 lines
19 KiB
CMake
476 lines
19 KiB
CMake
# ################################################################
|
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
# All rights reserved.
|
|
#
|
|
# This source code is licensed under both the BSD-style license (found in the
|
|
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
# in the COPYING file in the root directory of this source tree).
|
|
# ################################################################
|
|
|
|
project(libzstd C ASM)
|
|
|
|
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
|
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
|
|
option(ZSTD_BUILD_SHARED "BUILD SHARED LIBRARIES" ON)
|
|
option(ZSTD_BUILD_COMPRESSION "BUILD COMPRESSION MODULE" ON)
|
|
option(ZSTD_BUILD_DECOMPRESSION "BUILD DECOMPRESSION MODULE" ON)
|
|
option(ZSTD_BUILD_DICTBUILDER "BUILD DICTBUILDER MODULE" ON)
|
|
option(ZSTD_BUILD_DEPRECATED "BUILD DEPRECATED MODULE" OFF)
|
|
option(ZSTD_HUF_FORCE_DECOMPRESS_X1 "FORCE THE HUF X1 DECODER" OFF)
|
|
option(ZSTD_HUF_FORCE_DECOMPRESS_X2 "FORCE THE HUF X2 DECODER" OFF)
|
|
set(ZSTD_RUST_TARGET "" CACHE STRING
|
|
"Cargo target triple (required when CMake cross-compiles)")
|
|
|
|
set(ZSTDLIB_VISIBLE "" CACHE STRING "Visibility for ZSTDLIB API")
|
|
set(ZSTDERRORLIB_VISIBLE "" CACHE STRING "Visibility for ZSTDERRORLIB_VISIBLE API")
|
|
set(ZDICTLIB_VISIBLE "" CACHE STRING "Visibility for ZDICTLIB_VISIBLE API")
|
|
set(ZSTDLIB_STATIC_API "" CACHE STRING "Visibility for ZSTDLIB_STATIC_API API")
|
|
set(ZDICTLIB_STATIC_API "" CACHE STRING "Visibility for ZDICTLIB_STATIC_API API")
|
|
|
|
set_property(CACHE ZSTDLIB_VISIBLE PROPERTY STRINGS "" "hidden" "default" "protected" "internal")
|
|
set_property(CACHE ZSTDERRORLIB_VISIBLE PROPERTY STRINGS "" "hidden" "default" "protected" "internal")
|
|
set_property(CACHE ZDICTLIB_VISIBLE PROPERTY STRINGS "" "hidden" "default" "protected" "internal")
|
|
set_property(CACHE ZSTDLIB_STATIC_API PROPERTY STRINGS "" "hidden" "default" "protected" "internal")
|
|
set_property(CACHE ZDICTLIB_STATIC_API PROPERTY STRINGS "" "hidden" "default" "protected" "internal")
|
|
|
|
if(NOT ZSTD_BUILD_SHARED AND NOT ZSTD_BUILD_STATIC)
|
|
message(SEND_ERROR "You need to build at least one flavor of libzstd")
|
|
endif()
|
|
|
|
file(GLOB CommonSources ${LIBRARY_DIR}/common/*.c)
|
|
file(GLOB CompressSources ${LIBRARY_DIR}/compress/*.c)
|
|
file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c)
|
|
if (MSVC)
|
|
add_compile_options(-DZSTD_DISABLE_ASM)
|
|
else ()
|
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|AMD64.*|x86_64.*|X86_64.*"
|
|
AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND ${ZSTD_HAS_NOEXECSTACK})
|
|
set(DecompressSources ${DecompressSources} ${LIBRARY_DIR}/decompress/huf_decompress_amd64.S)
|
|
else()
|
|
add_compile_options(-DZSTD_DISABLE_ASM)
|
|
endif()
|
|
endif ()
|
|
file(GLOB DictBuilderSources ${LIBRARY_DIR}/dictBuilder/*.c)
|
|
file(GLOB DeprecatedSources ${LIBRARY_DIR}/deprecated/*.c)
|
|
|
|
file(GLOB PublicHeaders ${LIBRARY_DIR}/*.h)
|
|
file(GLOB CommonHeaders ${LIBRARY_DIR}/common/*.h)
|
|
file(GLOB CompressHeaders ${LIBRARY_DIR}/compress/*.h)
|
|
file(GLOB DecompressHeaders ${LIBRARY_DIR}/decompress/*.h)
|
|
file(GLOB DictBuilderHeaders ${LIBRARY_DIR}/dictBuilder/*.h)
|
|
file(GLOB DeprecatedHeaders ${LIBRARY_DIR}/deprecated/*.h)
|
|
|
|
set(Sources ${CommonSources})
|
|
set(Headers ${PublicHeaders} ${CommonHeaders})
|
|
if (ZSTD_BUILD_COMPRESSION)
|
|
set(Sources ${Sources} ${CompressSources})
|
|
set(Headers ${Headers} ${CompressHeaders})
|
|
endif()
|
|
if (ZSTD_BUILD_DECOMPRESSION)
|
|
set(Sources ${Sources} ${DecompressSources})
|
|
set(Headers ${Headers} ${DecompressHeaders})
|
|
endif()
|
|
if (ZSTD_BUILD_DICTBUILDER)
|
|
set(Sources ${Sources} ${DictBuilderSources})
|
|
set(Headers ${Headers} ${DictBuilderHeaders})
|
|
endif()
|
|
if (ZSTD_BUILD_DEPRECATED)
|
|
set(Sources ${Sources} ${DeprecatedSources})
|
|
set(Headers ${Headers} ${DeprecatedHeaders})
|
|
endif()
|
|
|
|
if (ZSTD_LEGACY_SUPPORT)
|
|
set(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy)
|
|
|
|
set(Sources ${Sources}
|
|
${LIBRARY_LEGACY_DIR}/zstd_v01.c
|
|
${LIBRARY_LEGACY_DIR}/zstd_v02.c
|
|
${LIBRARY_LEGACY_DIR}/zstd_v03.c
|
|
${LIBRARY_LEGACY_DIR}/zstd_v04.c
|
|
${LIBRARY_LEGACY_DIR}/zstd_v05.c
|
|
${LIBRARY_LEGACY_DIR}/zstd_v06.c
|
|
${LIBRARY_LEGACY_DIR}/zstd_v07.c)
|
|
|
|
set(Headers ${Headers}
|
|
${LIBRARY_LEGACY_DIR}/zstd_legacy.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v01.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v02.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v03.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v04.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v05.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v06.h
|
|
${LIBRARY_LEGACY_DIR}/zstd_v07.h)
|
|
endif ()
|
|
|
|
# The C compatibility shims are backed by a Cargo static library. Keep its
|
|
# feature set in lockstep with CMake's partial-library switches, otherwise a
|
|
# Rust object can retain references to a C module that was intentionally left
|
|
# out of this build.
|
|
find_program(ZSTD_CARGO_EXECUTABLE NAMES cargo)
|
|
if(NOT ZSTD_CARGO_EXECUTABLE)
|
|
message(FATAL_ERROR "Cargo is required to build the migrated Rust modules")
|
|
endif()
|
|
mark_as_advanced(ZSTD_CARGO_EXECUTABLE ZSTD_RUST_TARGET)
|
|
|
|
set(_zstd_huf_c_flags "${CMAKE_C_FLAGS}")
|
|
foreach(_zstd_build_type DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
|
|
set(_zstd_c_flag_var "CMAKE_C_FLAGS_${_zstd_build_type}")
|
|
set(_zstd_huf_c_flags "${_zstd_huf_c_flags} ${${_zstd_c_flag_var}}")
|
|
endforeach()
|
|
|
|
set(_zstd_huf_force_x1 ${ZSTD_HUF_FORCE_DECOMPRESS_X1})
|
|
set(_zstd_huf_force_x2 ${ZSTD_HUF_FORCE_DECOMPRESS_X2})
|
|
if(_zstd_huf_c_flags MATCHES "(^|[ \t])(-D|/D)HUF_FORCE_DECOMPRESS_X1(=[^ \t]+)?([ \t]|$)")
|
|
set(_zstd_huf_force_x1 ON)
|
|
endif()
|
|
if(_zstd_huf_c_flags MATCHES "(^|[ \t])(-D|/D)HUF_FORCE_DECOMPRESS_X2(=[^ \t]+)?([ \t]|$)")
|
|
set(_zstd_huf_force_x2 ON)
|
|
endif()
|
|
if(_zstd_huf_force_x1 AND _zstd_huf_force_x2)
|
|
message(FATAL_ERROR
|
|
"HUF_FORCE_DECOMPRESS_X1 and HUF_FORCE_DECOMPRESS_X2 are mutually exclusive")
|
|
endif()
|
|
|
|
set(_zstd_rust_c_definitions)
|
|
if(ZSTD_HUF_FORCE_DECOMPRESS_X1)
|
|
list(APPEND _zstd_rust_c_definitions HUF_FORCE_DECOMPRESS_X1)
|
|
endif()
|
|
if(ZSTD_HUF_FORCE_DECOMPRESS_X2)
|
|
list(APPEND _zstd_rust_c_definitions HUF_FORCE_DECOMPRESS_X2)
|
|
endif()
|
|
|
|
set(_zstd_rust_features)
|
|
set(_zstd_rust_compression 0)
|
|
set(_zstd_rust_decompression 0)
|
|
set(_zstd_rust_dictbuilder 0)
|
|
if(ZSTD_BUILD_COMPRESSION)
|
|
list(APPEND _zstd_rust_features compression)
|
|
set(_zstd_rust_compression 1)
|
|
endif()
|
|
if(ZSTD_BUILD_DECOMPRESSION)
|
|
list(APPEND _zstd_rust_features decompression)
|
|
set(_zstd_rust_decompression 1)
|
|
endif()
|
|
if(ZSTD_BUILD_DICTBUILDER)
|
|
list(APPEND _zstd_rust_features dict-builder)
|
|
set(_zstd_rust_dictbuilder 1)
|
|
endif()
|
|
|
|
set(_zstd_rust_huf_mode default)
|
|
if(_zstd_huf_force_x1)
|
|
set(_zstd_rust_huf_mode huf-force-decompress-x1)
|
|
if(ZSTD_BUILD_DECOMPRESSION)
|
|
list(APPEND _zstd_rust_features huf-force-decompress-x1)
|
|
endif()
|
|
elseif(_zstd_huf_force_x2)
|
|
set(_zstd_rust_huf_mode huf-force-decompress-x2)
|
|
if(ZSTD_BUILD_DECOMPRESSION)
|
|
list(APPEND _zstd_rust_features huf-force-decompress-x2)
|
|
endif()
|
|
endif()
|
|
|
|
set(_zstd_rust_target "${ZSTD_RUST_TARGET}")
|
|
if(NOT _zstd_rust_target AND CMAKE_SYSTEM_NAME STREQUAL "Linux"
|
|
AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
|
set(_zstd_rust_x86_32 OFF)
|
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i[3-6]86|x86)$")
|
|
set(_zstd_rust_x86_32 ON)
|
|
elseif(CMAKE_C_COMPILER_TARGET MATCHES "^(i[3-6]86|x86)-")
|
|
set(_zstd_rust_x86_32 ON)
|
|
elseif(_zstd_huf_c_flags MATCHES "(^|[ \t])-m32([ \t]|$)")
|
|
set(_zstd_rust_x86_32 ON)
|
|
endif()
|
|
if(_zstd_rust_x86_32)
|
|
set(_zstd_rust_target i686-unknown-linux-gnu)
|
|
endif()
|
|
endif()
|
|
if(NOT _zstd_rust_target AND CMAKE_CROSSCOMPILING)
|
|
message(FATAL_ERROR
|
|
"Set ZSTD_RUST_TARGET to the Cargo target triple for this cross build")
|
|
endif()
|
|
|
|
if(_zstd_rust_features)
|
|
string(REPLACE ";" "," _zstd_rust_feature_arg "${_zstd_rust_features}")
|
|
set(_zstd_rust_feature_args --features "${_zstd_rust_feature_arg}")
|
|
endif()
|
|
|
|
set(_zstd_rust_build_config
|
|
"c${_zstd_rust_compression}-d${_zstd_rust_decompression}-b${_zstd_rust_dictbuilder}-${_zstd_rust_huf_mode}")
|
|
set(ZSTD_RUST_MANIFEST "${ZSTD_SOURCE_DIR}/rust/Cargo.toml")
|
|
set(ZSTD_RUST_TARGET_DIR
|
|
"${CMAKE_CURRENT_BINARY_DIR}/rust-target/${_zstd_rust_build_config}")
|
|
set(_zstd_rust_target_args)
|
|
set(_zstd_rust_target_component)
|
|
if(_zstd_rust_target)
|
|
list(APPEND _zstd_rust_target_args --target "${_zstd_rust_target}")
|
|
set(_zstd_rust_target_component "/${_zstd_rust_target}")
|
|
endif()
|
|
if(MSVC)
|
|
set(_zstd_rust_staticlib_name zstd_rs.lib)
|
|
else()
|
|
set(_zstd_rust_staticlib_name libzstd_rs.a)
|
|
endif()
|
|
set(ZSTD_RUST_STATICLIB
|
|
"${ZSTD_RUST_TARGET_DIR}${_zstd_rust_target_component}/release/${_zstd_rust_staticlib_name}")
|
|
|
|
# This is deliberately an always-checked target instead of a configure-time
|
|
# Rust source glob. The project supports CMake 3.10, predating reliable
|
|
# CONFIGURE_DEPENDS handling here, while Cargo already tracks new modules and
|
|
# manifest changes precisely. LINK_DEPENDS below still avoids relinking the
|
|
# C library when Cargo leaves its archive unchanged.
|
|
add_custom_target(zstd_rust_archive
|
|
BYPRODUCTS "${ZSTD_RUST_STATICLIB}"
|
|
COMMAND "${ZSTD_CARGO_EXECUTABLE}" build
|
|
--manifest-path "${ZSTD_RUST_MANIFEST}"
|
|
--release
|
|
--target-dir "${ZSTD_RUST_TARGET_DIR}"
|
|
--no-default-features
|
|
${_zstd_rust_feature_args}
|
|
${_zstd_rust_target_args}
|
|
WORKING_DIRECTORY "${ZSTD_SOURCE_DIR}"
|
|
COMMENT "Building Rust compatibility archive (${_zstd_rust_build_config})"
|
|
VERBATIM)
|
|
|
|
function(zstd_attach_rust_archive target)
|
|
add_dependencies(${target} zstd_rust_archive)
|
|
set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS "${ZSTD_RUST_STATICLIB}")
|
|
endfunction()
|
|
|
|
if (MSVC)
|
|
set(MSVC_RESOURCE_DIR ${ZSTD_SOURCE_DIR}/build/VS2010/libzstd-dll)
|
|
set(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc)
|
|
endif ()
|
|
|
|
# Explicitly set the language to C for all files, including ASM files.
|
|
# Our assembly expects to be compiled by a C compiler, and is only enabled for
|
|
# __GNUC__ compatible compilers. Otherwise all the ASM code is disabled by
|
|
# macros.
|
|
if(NOT CMAKE_ASM_COMPILER STREQUAL CMAKE_C_COMPILER)
|
|
set_source_files_properties(${Sources} PROPERTIES LANGUAGE C)
|
|
endif()
|
|
|
|
macro (add_definition target var)
|
|
if (NOT ("${${var}}" STREQUAL ""))
|
|
set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS "${var}=__attribute__((visibility(\"${${var}}\")))")
|
|
endif ()
|
|
endmacro ()
|
|
|
|
# Define directories containing the library's public headers
|
|
set(PUBLIC_INCLUDE_DIRS ${LIBRARY_DIR})
|
|
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /I \"${LIBRARY_DIR}\"")
|
|
# Split project to static and shared libraries build
|
|
set(library_targets)
|
|
if (ZSTD_BUILD_SHARED)
|
|
add_library(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources})
|
|
target_include_directories(libzstd_shared INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>)
|
|
if(_zstd_rust_c_definitions)
|
|
target_compile_definitions(libzstd_shared PRIVATE ${_zstd_rust_c_definitions})
|
|
endif()
|
|
zstd_attach_rust_archive(libzstd_shared)
|
|
# Link the complete Cargo archive, rather than only the members reached by
|
|
# C code. Several migrated functions are public ABI entry points and are
|
|
# otherwise invisible to the shared-library linker's archive scan.
|
|
if(APPLE)
|
|
target_link_libraries(libzstd_shared PRIVATE
|
|
"-Wl,-force_load,${ZSTD_RUST_STATICLIB}")
|
|
elseif(MSVC)
|
|
target_link_libraries(libzstd_shared PRIVATE
|
|
"/WHOLEARCHIVE:${ZSTD_RUST_STATICLIB}")
|
|
else()
|
|
target_link_libraries(libzstd_shared PRIVATE
|
|
"-Wl,--whole-archive"
|
|
"${ZSTD_RUST_STATICLIB}"
|
|
"-Wl,--no-whole-archive")
|
|
endif()
|
|
list(APPEND library_targets libzstd_shared)
|
|
if (ZSTD_MULTITHREAD_SUPPORT)
|
|
set_property(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD")
|
|
if (UNIX)
|
|
target_link_libraries(libzstd_shared ${THREADS_LIBS})
|
|
endif ()
|
|
endif ()
|
|
add_definition(libzstd_shared ZSTDLIB_VISIBLE)
|
|
add_definition(libzstd_shared ZSTDERRORLIB_VISIBLE)
|
|
add_definition(libzstd_shared ZDICTLIB_VISIBLE)
|
|
endif ()
|
|
if (ZSTD_BUILD_STATIC)
|
|
add_library(libzstd_static STATIC ${Sources} ${Headers})
|
|
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>)
|
|
if(_zstd_rust_c_definitions)
|
|
target_compile_definitions(libzstd_static PRIVATE ${_zstd_rust_c_definitions})
|
|
endif()
|
|
zstd_attach_rust_archive(libzstd_static)
|
|
if(MSVC)
|
|
set(_zstd_archive_style MSVC)
|
|
else()
|
|
set(_zstd_archive_style AR)
|
|
endif()
|
|
# CMake builds the C archive first. Merge Cargo's object members after
|
|
# that step so external C consumers need only one libzstd archive and do
|
|
# not depend on a particular C/Rust archive ordering.
|
|
add_custom_command(TARGET libzstd_static POST_BUILD
|
|
COMMAND "${CMAKE_COMMAND}"
|
|
"-DARCHIVER:FILEPATH=${CMAKE_AR}"
|
|
"-DARCHIVER_STYLE:STRING=${_zstd_archive_style}"
|
|
"-DRANLIB:FILEPATH=${CMAKE_RANLIB}"
|
|
"-DRUST_ARCHIVE:FILEPATH=${ZSTD_RUST_STATICLIB}"
|
|
"-DTARGET_ARCHIVE:FILEPATH=$<TARGET_FILE:libzstd_static>"
|
|
"-DWORK_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/rust-archive-members"
|
|
-P "${CMAKE_CURRENT_LIST_DIR}/merge_rust_archive.cmake"
|
|
VERBATIM)
|
|
list(APPEND library_targets libzstd_static)
|
|
if (ZSTD_MULTITHREAD_SUPPORT)
|
|
set_property(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD")
|
|
if (UNIX)
|
|
target_link_libraries(libzstd_static ${THREADS_LIBS})
|
|
endif ()
|
|
endif ()
|
|
add_definition(libzstd_static ZSTDLIB_VISIBLE)
|
|
add_definition(libzstd_static ZSTDERRORLIB_VISIBLE)
|
|
add_definition(libzstd_static ZDICTLIB_VISIBLE)
|
|
add_definition(libzstd_static ZSTDLIB_STATIC_API)
|
|
add_definition(libzstd_static ZDICTLIB_STATIC_API)
|
|
endif ()
|
|
if (ZSTD_BUILD_SHARED AND NOT ZSTD_BUILD_STATIC)
|
|
if (NOT BUILD_SHARED_LIBS)
|
|
message(WARNING "BUILD_SHARED_LIBS is OFF, but ZSTD_BUILD_SHARED is ON and ZSTD_BUILD_STATIC is OFF, which takes precedence, so libzstd is a shared library")
|
|
endif ()
|
|
add_library(libzstd INTERFACE)
|
|
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
|
list(APPEND library_targets libzstd)
|
|
endif ()
|
|
if (ZSTD_BUILD_STATIC AND NOT ZSTD_BUILD_SHARED)
|
|
if (BUILD_SHARED_LIBS)
|
|
message(WARNING "BUILD_SHARED_LIBS is ON, but ZSTD_BUILD_SHARED is OFF and ZSTD_BUILD_STATIC is ON, which takes precedence, is set so libzstd is a static library")
|
|
endif ()
|
|
add_library(libzstd INTERFACE)
|
|
target_link_libraries(libzstd INTERFACE libzstd_static)
|
|
list(APPEND library_targets libzstd)
|
|
endif ()
|
|
if (ZSTD_BUILD_SHARED AND ZSTD_BUILD_STATIC)
|
|
# If both ZSTD_BUILD_SHARED and ZSTD_BUILD_STATIC are set, which is the
|
|
# default, fallback to using BUILD_SHARED_LIBS to determine whether to
|
|
# set libzstd to static or shared.
|
|
if (BUILD_SHARED_LIBS)
|
|
add_library(libzstd INTERFACE)
|
|
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
|
list(APPEND library_targets libzstd)
|
|
else ()
|
|
add_library(libzstd INTERFACE)
|
|
target_link_libraries(libzstd INTERFACE libzstd_static)
|
|
list(APPEND library_targets libzstd)
|
|
endif ()
|
|
endif ()
|
|
|
|
# Add specific compile definitions for MSVC project
|
|
if (MSVC)
|
|
if (ZSTD_BUILD_SHARED)
|
|
set_property(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS")
|
|
endif ()
|
|
if (ZSTD_BUILD_STATIC)
|
|
set_property(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_HEAPMODE=0;_CRT_SECURE_NO_WARNINGS")
|
|
endif ()
|
|
endif ()
|
|
|
|
# With MSVC static library needs to be renamed to avoid conflict with import library
|
|
if (MSVC OR (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT MINGW))
|
|
set(STATIC_LIBRARY_BASE_NAME zstd_static)
|
|
else ()
|
|
set(STATIC_LIBRARY_BASE_NAME zstd)
|
|
endif ()
|
|
|
|
# Define static and shared library names
|
|
if (ZSTD_BUILD_SHARED)
|
|
set_target_properties(
|
|
libzstd_shared
|
|
PROPERTIES
|
|
OUTPUT_NAME zstd
|
|
VERSION ${ZSTD_FULL_VERSION}
|
|
SOVERSION ${zstd_VERSION_MAJOR})
|
|
|
|
if (ZSTD_FRAMEWORK)
|
|
set_target_properties(
|
|
libzstd_shared
|
|
PROPERTIES
|
|
FRAMEWORK TRUE
|
|
FRAMEWORK_VERSION "${ZSTD_FULL_VERSION}"
|
|
PRODUCT_BUNDLE_IDENTIFIER "github.com/facebook/zstd"
|
|
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
|
|
PUBLIC_HEADER "${PublicHeaders}"
|
|
OUTPUT_NAME "zstd"
|
|
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
|
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
|
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
|
|
MACOSX_FRAMEWORK_IDENTIFIER "github.com/facebook/zstd"
|
|
MACOSX_FRAMEWORK_BUNDLE_VERSION "${ZSTD_FULL_VERSION}"
|
|
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${ZSTD_SHORT_VERSION}"
|
|
MACOSX_RPATH TRUE
|
|
RESOURCE ${PublicHeaders})
|
|
endif ()
|
|
endif ()
|
|
|
|
if (ZSTD_BUILD_STATIC)
|
|
set_target_properties(
|
|
libzstd_static
|
|
PROPERTIES
|
|
POSITION_INDEPENDENT_CODE On
|
|
OUTPUT_NAME ${STATIC_LIBRARY_BASE_NAME})
|
|
|
|
if (ZSTD_FRAMEWORK)
|
|
set_target_properties(
|
|
libzstd_static
|
|
PROPERTIES
|
|
FRAMEWORK TRUE
|
|
FRAMEWORK_VERSION "${ZSTD_FULL_VERSION}"
|
|
PRODUCT_BUNDLE_IDENTIFIER "github.com/facebook/zstd/${STATIC_LIBRARY_BASE_NAME}"
|
|
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
|
|
PUBLIC_HEADER "${PublicHeaders}"
|
|
OUTPUT_NAME "${STATIC_LIBRARY_BASE_NAME}"
|
|
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
|
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
|
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
|
|
MACOSX_FRAMEWORK_IDENTIFIER "github.com/facebook/zstd/${STATIC_LIBRARY_BASE_NAME}"
|
|
MACOSX_FRAMEWORK_BUNDLE_VERSION "${ZSTD_FULL_VERSION}"
|
|
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${ZSTD_SHORT_VERSION}"
|
|
MACOSX_RPATH TRUE
|
|
RESOURCE ${PublicHeaders})
|
|
endif ()
|
|
endif ()
|
|
|
|
# pkg-config
|
|
include(JoinPaths) # can be replaced by cmake_path(APPEND) in CMake 3.20
|
|
set(PREFIX "${CMAKE_INSTALL_PREFIX}")
|
|
set(EXEC_PREFIX "\${prefix}")
|
|
join_paths(LIBDIR "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
|
|
join_paths(INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
set(LIBS_PRIVATE "${THREADS_LIBS}")
|
|
set(VERSION "${zstd_VERSION}")
|
|
|
|
configure_file("${LIBRARY_DIR}/libzstd.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" @ONLY)
|
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
|
|
|
# install target
|
|
install(FILES ${PublicHeaders} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
|
|
install(TARGETS ${library_targets}
|
|
EXPORT zstdExports
|
|
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
|
BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
|
FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime OPTIONAL
|
|
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
)
|
|
|
|
# uninstall target
|
|
if (NOT TARGET uninstall)
|
|
configure_file(
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
|
IMMEDIATE @ONLY)
|
|
|
|
add_custom_target(uninstall
|
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
|
endif ()
|