1cmake_minimum_required(VERSION 2.4.4...3.15.0) 2set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) 3 4project(zlib C) 5 6set(VERSION "1.3.0.1") 7 8set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") 9set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") 10set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") 11set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") 12set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") 13 14include(CheckTypeSize) 15include(CheckFunctionExists) 16include(CheckIncludeFile) 17include(CheckCSourceCompiles) 18enable_testing() 19 20check_include_file(sys/types.h HAVE_SYS_TYPES_H) 21check_include_file(stdint.h HAVE_STDINT_H) 22check_include_file(stddef.h HAVE_STDDEF_H) 23 24option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) 25option(ENABLE_SIMD_AVX512 "Enable SIMD AXV512 optimizations" OFF) 26option(USE_ZLIB_RABIN_KARP_HASH "Enable bitstream compatibility with canonical zlib" OFF) 27option(BUILD_UNITTESTS "Enable standalone unit tests build" OFF) 28option(BUILD_MINIZIP_BIN "Enable building minzip_bin tool" OFF) 29option(BUILD_ZPIPE "Enable building zpipe tool" OFF) 30option(BUILD_MINIGZIP "Enable building minigzip tool" OFF) 31 32if (USE_ZLIB_RABIN_KARP_HASH) 33 add_definitions(-DUSE_ZLIB_RABIN_KARP_ROLLING_HASH) 34endif() 35 36# TODO(cavalcantii): add support for other OSes (e.g. Android, Fuchsia, etc) 37# and architectures (e.g. RISCV). 38if (ENABLE_SIMD_OPTIMIZATIONS) 39 # Apparently some environments (e.g. CentOS) require to explicitly link 40 # with pthread and that is required by the CPU features detection code. 41 find_package (Threads REQUIRED) 42 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") 43 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") 44 45 if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") 46 add_definitions(-DINFLATE_CHUNK_SIMD_SSE2) 47 add_definitions(-DADLER32_SIMD_SSSE3) 48 add_definitions(-DINFLATE_CHUNK_READ_64LE) 49 add_definitions(-DCRC32_SIMD_SSE42_PCLMUL) 50 if (ENABLE_SIMD_AVX512) 51 add_definitions(-DCRC32_SIMD_AVX512_PCLMUL) 52 add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul) 53 else() 54 add_compile_options(-msse4.2 -mpclmul) 55 endif() 56 add_definitions(-DDEFLATE_SLIDE_HASH_SSE2) 57 # Required by CPU features detection code. 58 add_definitions(-DX86_NOT_WINDOWS) 59 endif() 60 61 if ((CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") OR 62 (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")) 63 add_definitions(-DINFLATE_CHUNK_SIMD_NEON) 64 add_definitions(-DADLER32_SIMD_NEON) 65 add_definitions(-DINFLATE_CHUNK_READ_64LE) 66 add_definitions(-DCRC32_ARMV8_CRC32) 67 add_definitions(-DDEFLATE_SLIDE_HASH_NEON) 68 # Required by CPU features detection code. 69 if (APPLE) 70 add_definitions(-DARMV8_OS_MACOS) 71 endif() 72 73 if (UNIX AND NOT APPLE) 74 add_definitions(-DARMV8_OS_LINUX) 75 endif() 76 77 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crc+crypto") 78 endif() 79 80 if (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") 81 add_definitions(-DRISCV_RVV) 82 add_definitions(-DDEFLATE_SLIDE_HASH_RVV) 83 add_definitions(-DADLER32_SIMD_RVV) 84 85 # TODO(cavalcantii): add remaining flags as we port optimizations to RVV. 86 # chunk_copy is required for READ64 and unconditional decode of literals. 87 add_definitions(-DINFLATE_CHUNK_GENERIC) 88 add_definitions(-DINFLATE_CHUNK_READ_64LE) 89 90 # Tested with clang-17, unaligned loads are required by read64 & chunk_copy. 91 # TODO(cavalcantii): replace internal clang flags for -munaligned-access 92 # when we have a newer compiler available. 93 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=riscv64-unknown-linux-gnu -march=rv64gcv -Xclang -target-feature -Xclang +unaligned-scalar-mem") 94 endif() 95 96endif() 97 98# 99# Check to see if we have large file support 100# 101set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) 102# We add these other definitions here because CheckTypeSize.cmake 103# in CMake 2.4.x does not automatically do so and we want 104# compatibility with CMake 2.4.x. 105if(HAVE_SYS_TYPES_H) 106 list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) 107endif() 108if(HAVE_STDINT_H) 109 list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) 110endif() 111if(HAVE_STDDEF_H) 112 list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) 113endif() 114check_type_size(off64_t OFF64_T) 115if(HAVE_OFF64_T) 116 add_definitions(-D_LARGEFILE64_SOURCE=1) 117endif() 118set(CMAKE_REQUIRED_DEFINITIONS) # clear variable 119 120# 121# Check for fseeko 122# 123check_function_exists(fseeko HAVE_FSEEKO) 124if(NOT HAVE_FSEEKO) 125 add_definitions(-DNO_FSEEKO) 126endif() 127 128# 129# Check for unistd.h 130# 131check_include_file(unistd.h Z_HAVE_UNISTD_H) 132 133if(MSVC) 134 set(CMAKE_DEBUG_POSTFIX "d") 135 add_definitions(-D_CRT_SECURE_NO_DEPRECATE) 136 add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) 137 include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 138endif() 139 140if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) 141 # If we're doing an out of source build and the user has a zconf.h 142 # in their source tree... 143 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) 144 message(STATUS "Renaming") 145 message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") 146 message(STATUS "to 'zconf.h.included' because this file is included with zlib") 147 message(STATUS "but CMake generates it automatically in the build directory.") 148 file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) 149 endif() 150endif() 151 152set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) 153configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein 154 ${ZLIB_PC} @ONLY) 155configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein 156 ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) 157include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) 158 159 160#============================================================================ 161# zlib 162#============================================================================ 163 164set(ZLIB_PUBLIC_HDRS 165 ${CMAKE_CURRENT_BINARY_DIR}/zconf.h 166 zlib.h 167) 168set(ZLIB_PRIVATE_HDRS 169 crc32.h 170 deflate.h 171 gzguts.h 172 inffast.h 173 inffixed.h 174 inflate.h 175 inftrees.h 176 trees.h 177 zutil.h 178) 179set(ZLIB_SRCS 180 adler32.c 181 compress.c 182 crc32.c 183 deflate.c 184 gzclose.c 185 gzlib.c 186 gzread.c 187 gzwrite.c 188 inflate.c 189 infback.c 190 inftrees.c 191 inffast.c 192 trees.c 193 uncompr.c 194 zutil.c 195) 196 197 198#============================================================================ 199# Update list of source files if optimizations were enabled 200#============================================================================ 201if (ENABLE_SIMD_OPTIMIZATIONS) 202 if (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") 203 message("RISCVV: Add optimizations.") 204 list(REMOVE_ITEM ZLIB_SRCS inflate.c) 205 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h) 206 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h) 207 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h) 208 209 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c) 210 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c) 211 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c) 212 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c) 213 else() 214 list(REMOVE_ITEM ZLIB_SRCS inflate.c) 215 216 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h) 217 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h) 218 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h) 219 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h) 220 list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.h) 221 222 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c) 223 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c) 224 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c) 225 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c) 226 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.c) 227 list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc_folding.c) 228 endif() 229endif() 230 231# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION 232file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) 233string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" 234 "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) 235 236if(MINGW) 237 # This gets us DLL resource information when compiling on MinGW. 238 if(NOT CMAKE_RC_COMPILER) 239 set(CMAKE_RC_COMPILER windres.exe) 240 endif() 241 242 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj 243 COMMAND ${CMAKE_RC_COMPILER} 244 -D GCC_WINDRES 245 -I ${CMAKE_CURRENT_SOURCE_DIR} 246 -I ${CMAKE_CURRENT_BINARY_DIR} 247 -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj 248 -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) 249 set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) 250endif(MINGW) 251 252add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) 253add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) 254set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) 255set_target_properties(zlib PROPERTIES SOVERSION 1) 256 257if(NOT CYGWIN) 258 # This property causes shared libraries on Linux to have the full version 259 # encoded into their final filename. We disable this on Cygwin because 260 # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll 261 # seems to be the default. 262 # 263 # This has no effect with MSVC, on that platform the version info for 264 # the DLL comes from the resource file win32/zlib1.rc 265 set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) 266endif() 267 268if(UNIX) 269 # On unix-like platforms the library is almost always called libz 270 set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) 271 if(NOT APPLE) 272 set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") 273 endif() 274elseif(BUILD_SHARED_LIBS AND WIN32) 275 # Creates zlib1.dll when building shared library version 276 set_target_properties(zlib PROPERTIES SUFFIX "1.dll") 277endif() 278 279if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) 280 install(TARGETS zlib zlibstatic 281 RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 282 ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 283 LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) 284endif() 285if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) 286 install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") 287endif() 288if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) 289 install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") 290endif() 291if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) 292 install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") 293endif() 294 295#============================================================================ 296# Benchmarker 297#============================================================================ 298enable_language(CXX) 299set(CMAKE_CXX_STANDARD 14) # workaround for older compilers (e.g. g++ 5.4). 300add_executable(zlib_bench contrib/bench/zlib_bench.cc) 301target_link_libraries(zlib_bench zlib) 302 303#============================================================================ 304# Unit Tests 305#============================================================================ 306if (BUILD_UNITTESTS) 307 include (ExternalProject) 308 set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/third_party) 309 ExternalProject_add( 310 googletest 311 GIT_REPOSITORY https://github.com/google/googletest.git 312 GIT_TAG d1467f5813f4d363cfd11aba99c4e9fe47a85e99 313 UPDATE_COMMAND "" 314 INSTALL_COMMAND "" 315 LOG_DOWNLOAD ON 316 LOG_CONFIGURE ON 317 LOG_BUILD ON 318 ) 319 320 # gtest includedir 321 ExternalProject_Get_Property(googletest source_dir) 322 set(GTEST_INCLUDE_DIRS 323 ${source_dir}/googletest/include 324 ${source_dir}/googletest/include/gtest 325 ) 326 327 # gtest library 328 ExternalProject_Get_Property(googletest binary_dir) 329 set(GTEST_LIBRARY_PATH ${binary_dir}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a) 330 set(GTEST_LIBRARY gtest) 331 add_library(${GTEST_LIBRARY} UNKNOWN IMPORTED) 332 set_property(TARGET ${GTEST_LIBRARY} PROPERTY IMPORTED_LOCATION ${GTEST_LIBRARY_PATH}) 333 add_dependencies(${GTEST_LIBRARY} googletest) 334 335 set(UTEST_SRC 336 ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/infcover.cc 337 ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/infcover.h 338 ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/utils_unittest.cc 339 ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/standalone_test_runner.cc 340 ${CMAKE_CURRENT_SOURCE_DIR}/google/compression_utils_portable.cc 341 ) 342 343 add_compile_definitions(CMAKE_STANDALONE_UNITTESTS) 344 345 add_executable(zlib_unittests ${UTEST_SRC}) 346 target_include_directories(zlib_unittests PUBLIC ${GTEST_INCLUDE_DIRS}) 347 target_include_directories(zlib_unittests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/google) 348 349 target_link_libraries(zlib_unittests ${GTEST_LIBRARY}) 350 target_link_libraries(zlib_unittests zlib) 351 # Needed by gtest 352 target_link_libraries(zlib_unittests pthread) 353endif() 354 355#============================================================================ 356# Minizip tool 357#============================================================================ 358# TODO(cavalcantii): get it working on Windows. 359if (BUILD_MINIZIP_BIN) 360 add_executable(minizip_bin contrib/minizip/minizip.c contrib/minizip/ioapi.c 361 contrib/minizip/ioapi.h contrib/minizip/unzip.c 362 contrib/minizip/unzip.h contrib/minizip/zip.c contrib/minizip/zip.h 363 ) 364 target_link_libraries(minizip_bin zlib) 365endif() 366 367#============================================================================ 368# zpipe tool 369#============================================================================ 370if (BUILD_ZPIPE) 371 add_executable(zpipe examples/zpipe.c) 372 target_link_libraries(zpipe zlib) 373endif() 374#============================================================================ 375# MiniGzip tool 376#============================================================================ 377if (BUILD_MINIGZIP) 378 add_executable(minigzip_bin test/minigzip.c) 379 target_link_libraries(minigzip_bin zlib) 380endif() 381