xref: /aosp_15_r20/external/zlib/CMakeLists.txt (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
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