1# CMake support for LZ4 2# 3# To the extent possible under law, the author(s) have dedicated all 4# copyright and related and neighboring rights to this software to 5# the public domain worldwide. This software is distributed without 6# any warranty. 7# 8# For details, see <http://creativecommons.org/publicdomain/zero/1.0/>. 9 10 11cmake_minimum_required(VERSION 3.5) 12 13set(LZ4_TOP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..") 14 15# Parse version information 16function(parse_lz4_version VERSION_TYPE) 17 file(STRINGS "${LZ4_TOP_SOURCE_DIR}/lib/lz4.h" version_line REGEX "^#define LZ4_VERSION_${VERSION_TYPE} +([0-9]+).*$") 18 string(REGEX REPLACE "^#define LZ4_VERSION_${VERSION_TYPE} +([0-9]+).*$" "\\1" version_number "${version_line}") 19 set(LZ4_VERSION_${VERSION_TYPE} ${version_number} PARENT_SCOPE) 20endfunction() 21 22foreach(version_type IN ITEMS MAJOR MINOR RELEASE) 23 parse_lz4_version(${version_type}) 24endforeach() 25 26set(LZ4_VERSION_STRING "${LZ4_VERSION_MAJOR}.${LZ4_VERSION_MINOR}.${LZ4_VERSION_RELEASE}") 27mark_as_advanced(LZ4_VERSION_STRING LZ4_VERSION_MAJOR LZ4_VERSION_MINOR LZ4_VERSION_RELEASE) 28 29message(STATUS "Creating build script for LZ4 version: ${LZ4_VERSION_STRING}") 30 31project(LZ4 VERSION ${LZ4_VERSION_STRING} LANGUAGES C) 32 33 34option(LZ4_BUILD_CLI "Build lz4 program" ON) 35 36 37# Determine if LZ4 is being built as part of another project. 38# If LZ4 is bundled in another project, we don't want to install anything. 39# Default behavior can be overridden by setting the LZ4_BUNDLED_MODE variable. 40if(NOT DEFINED LZ4_BUNDLED_MODE) 41 get_directory_property(LZ4_IS_SUBPROJECT PARENT_DIRECTORY) 42 if(LZ4_IS_SUBPROJECT) 43 set(LZ4_BUNDLED_MODE ON) 44 else() 45 set(LZ4_BUNDLED_MODE OFF) 46 endif() 47endif() 48mark_as_advanced(LZ4_BUNDLED_MODE) 49 50# CPack 51if(NOT LZ4_BUNDLED_MODE AND NOT CPack_CMake_INCLUDED) 52 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LZ4 compression library") 53 set(CPACK_PACKAGE_DESCRIPTION_FILE "${LZ4_TOP_SOURCE_DIR}/README.md") 54 set(CPACK_RESOURCE_FILE_LICENSE "${LZ4_TOP_SOURCE_DIR}/LICENSE") 55 set(CPACK_PACKAGE_VERSION_MAJOR ${LZ4_VERSION_MAJOR}) 56 set(CPACK_PACKAGE_VERSION_MINOR ${LZ4_VERSION_MINOR}) 57 set(CPACK_PACKAGE_VERSION_PATCH ${LZ4_VERSION_RELEASE}) 58 include(CPack) 59endif(NOT LZ4_BUNDLED_MODE AND NOT CPack_CMake_INCLUDED) 60 61# Allow people to choose whether to build shared or static libraries 62# via the BUILD_SHARED_LIBS option unless we are in bundled mode, in 63# which case we always use static libraries. 64include(CMakeDependentOption) 65CMAKE_DEPENDENT_OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON "NOT LZ4_BUNDLED_MODE" OFF) 66CMAKE_DEPENDENT_OPTION(BUILD_STATIC_LIBS "Build static libraries" OFF "BUILD_SHARED_LIBS" ON) 67 68if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS) 69 message(FATAL_ERROR "Both BUILD_SHARED_LIBS and BUILD_STATIC_LIBS have been disabled") 70endif() 71 72set(LZ4_LIB_SOURCE_DIR "${LZ4_TOP_SOURCE_DIR}/lib") 73set(LZ4_PROG_SOURCE_DIR "${LZ4_TOP_SOURCE_DIR}/programs") 74 75include_directories("${LZ4_LIB_SOURCE_DIR}") 76 77# CLI sources 78file(GLOB LZ4_SOURCES 79 "${LZ4_LIB_SOURCE_DIR}/*.c") 80file(GLOB LZ4_CLI_SOURCES 81 "${LZ4_PROG_SOURCE_DIR}/*.c") 82list(APPEND LZ4_CLI_SOURCES ${LZ4_SOURCES}) # LZ4_CLI always use liblz4 sources directly. 83 84# Whether to use position independent code for the static library. If 85# we're building a shared library this is ignored and PIC is always 86# used. 87option(LZ4_POSITION_INDEPENDENT_LIB "Use position independent code for static library (if applicable)" ON) 88 89# liblz4 90include(GNUInstallDirs) 91set(LZ4_LIBRARIES_BUILT) 92if(BUILD_SHARED_LIBS) 93 add_library(lz4_shared SHARED ${LZ4_SOURCES}) 94 target_include_directories(lz4_shared 95 PUBLIC $<BUILD_INTERFACE:${LZ4_LIB_SOURCE_DIR}> 96 INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) 97 set_target_properties(lz4_shared PROPERTIES 98 OUTPUT_NAME lz4 99 SOVERSION "${LZ4_VERSION_MAJOR}" 100 VERSION "${LZ4_VERSION_STRING}") 101 if(MSVC) 102 target_compile_definitions(lz4_shared PRIVATE 103 LZ4_DLL_EXPORT=1) 104 endif() 105 list(APPEND LZ4_LIBRARIES_BUILT lz4_shared) 106endif() 107if(BUILD_STATIC_LIBS) 108 set(STATIC_LIB_NAME lz4) 109 if (MSVC AND BUILD_SHARED_LIBS) 110 set(STATIC_LIB_NAME lz4_static) 111 endif() 112 add_library(lz4_static STATIC ${LZ4_SOURCES}) 113 target_include_directories(lz4_static 114 PUBLIC $<BUILD_INTERFACE:${LZ4_LIB_SOURCE_DIR}> 115 INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) 116 set_target_properties(lz4_static PROPERTIES 117 OUTPUT_NAME ${STATIC_LIB_NAME} 118 POSITION_INDEPENDENT_CODE ${LZ4_POSITION_INDEPENDENT_LIB}) 119 list(APPEND LZ4_LIBRARIES_BUILT lz4_static) 120endif() 121# Add unified target. 122add_library(lz4 INTERFACE) 123list(APPEND LZ4_LIBRARIES_BUILT lz4) 124if(BUILD_SHARED_LIBS) 125 target_link_libraries(lz4 INTERFACE lz4_shared) 126else() 127 target_link_libraries(lz4 INTERFACE lz4_static) 128endif() 129 130# xxhash namespace 131if(BUILD_SHARED_LIBS) 132 target_compile_definitions(lz4_shared PRIVATE 133 XXH_NAMESPACE=LZ4_) 134endif() 135if(BUILD_STATIC_LIBS) 136 target_compile_definitions(lz4_static PRIVATE 137 XXH_NAMESPACE=LZ4_) 138endif() 139 140# lz4 141if (LZ4_BUILD_CLI) 142 set(LZ4_PROGRAMS_BUILT lz4cli) 143 add_executable(lz4cli ${LZ4_CLI_SOURCES}) 144 set_target_properties(lz4cli PROPERTIES OUTPUT_NAME lz4) 145endif() 146 147# Extra warning flags 148if(MSVC) 149 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /W4") 150else() 151 include (CheckCCompilerFlag) 152 foreach (flag 153 # GCC-style 154 -pedantic-errors 155 -Wall 156 -Wextra 157 -Wundef 158 -Wcast-qual 159 -Wcast-align 160 -Wshadow 161 -Wswitch-enum 162 -Wdeclaration-after-statement 163 -Wstrict-prototypes 164 -Wpointer-arith) 165 166 # Because https://gcc.gnu.org/wiki/FAQ#wnowarning 167 string(REGEX REPLACE "\\-Wno\\-(.+)" "-W\\1" flag_to_test "${flag}") 168 string(REGEX REPLACE "[^a-zA-Z0-9]+" "_" test_name "CFLAG_${flag_to_test}") 169 170 check_c_compiler_flag("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${test_name}) 171 172 if(${test_name}) 173 set(CMAKE_C_FLAGS_DEBUG "${flag} ${CMAKE_C_FLAGS_DEBUG}") 174 endif() 175 176 unset(test_name) 177 unset(flag_to_test) 178 endforeach (flag) 179endif() 180 181 182if(NOT LZ4_BUNDLED_MODE) 183 install(TARGETS ${LZ4_PROGRAMS_BUILT} 184 BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}" 185 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") 186 install(TARGETS ${LZ4_LIBRARIES_BUILT} 187 EXPORT lz4Targets 188 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 189 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 190 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") 191 install(FILES 192 "${LZ4_LIB_SOURCE_DIR}/lz4.h" 193 "${LZ4_LIB_SOURCE_DIR}/lz4hc.h" 194 "${LZ4_LIB_SOURCE_DIR}/lz4frame.h" 195 "${LZ4_LIB_SOURCE_DIR}/lz4file.h" 196 DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 197 install(FILES "${LZ4_PROG_SOURCE_DIR}/lz4.1" 198 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") 199 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/liblz4.pc" 200 DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 201 202 include(CMakePackageConfigHelpers) 203 write_basic_package_version_file( 204 "${CMAKE_CURRENT_BINARY_DIR}/lz4ConfigVersion.cmake" 205 VERSION ${LZ4_VERSION_STRING} 206 COMPATIBILITY SameMajorVersion) 207 208 set(LZ4_PKG_INSTALLDIR "${CMAKE_INSTALL_LIBDIR}/cmake/lz4") 209 configure_package_config_file( 210 "${CMAKE_CURRENT_LIST_DIR}/lz4Config.cmake.in" 211 "${CMAKE_CURRENT_BINARY_DIR}/lz4Config.cmake" 212 INSTALL_DESTINATION ${LZ4_PKG_INSTALLDIR}) 213 export(EXPORT lz4Targets 214 FILE ${CMAKE_CURRENT_BINARY_DIR}/lz4Targets.cmake 215 NAMESPACE LZ4::) 216 217 install(EXPORT lz4Targets 218 FILE lz4Targets.cmake 219 NAMESPACE LZ4:: 220 DESTINATION ${LZ4_PKG_INSTALLDIR}) 221 install(FILES 222 ${CMAKE_CURRENT_BINARY_DIR}/lz4Config.cmake 223 ${CMAKE_CURRENT_BINARY_DIR}/lz4ConfigVersion.cmake 224 DESTINATION ${LZ4_PKG_INSTALLDIR}) 225 226 # Install lz4cat and unlz4 symlinks on Unix systems 227 if(UNIX AND LZ4_BUILD_CLI) 228 foreach(cli_tool IN ITEMS lz4cat unlz4) 229 # Create a custom target for the symlink creation 230 add_custom_target("create_${cli_tool}_symlink" ALL 231 COMMAND ${CMAKE_COMMAND} -E create_symlink 232 $<TARGET_FILE_NAME:lz4cli> ${cli_tool} 233 COMMENT "Creating symlink for ${cli_tool}" 234 VERBATIM) 235 236 # Install the symlink into the binary installation directory 237 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${cli_tool}" 238 DESTINATION ${CMAKE_INSTALL_BINDIR} 239 RENAME ${cli_tool}) 240 endforeach() 241 242 # create manpage aliases 243 foreach(f lz4cat unlz4) 244 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${f}.1" ".so man1/lz4.1\n") 245 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${f}.1" 246 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") 247 endforeach() 248 endif(UNIX AND LZ4_BUILD_CLI) 249endif(NOT LZ4_BUNDLED_MODE) 250 251# pkg-config 252set(PREFIX "${CMAKE_INSTALL_PREFIX}") 253 254if("${CMAKE_INSTALL_FULL_LIBDIR}" STREQUAL "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") 255 set(LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") 256else() 257 set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}") 258endif() 259 260if("${CMAKE_INSTALL_FULL_INCLUDEDIR}" STREQUAL "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") 261 set(INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") 262else() 263 set(INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}") 264endif() 265 266# for liblz4.pc substitution 267set(VERSION ${LZ4_VERSION_STRING}) 268configure_file(${LZ4_LIB_SOURCE_DIR}/liblz4.pc.in liblz4.pc @ONLY) 269