• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# CMakeLists.txt -- Build madler/pigz against zlib variant
2
3# Copyright (C) 2021 Nathan Moinvaziri
4# Licensed under the Zlib license, see LICENSE.md for details
5
6# By default pigz will be linked against the system zlib and
7# pthread libraries if installed.
8
9# For compilation on Windows download and use shim:
10#  https://github.com/zlib-ng/pigzbench/tree/master/pigz/win
11
12# Optional Variables
13#   WITH_CODE_COVERAGE  - Enable code coverage reporting
14#   WITH_THREADS        - Enable threading support
15#   PIGZ_ENABLE_TESTS   - Enable adding unit tests
16#   PIGZ_VERSION        - Set the version of pigz to build
17#   ZLIB_ROOT           - Path to the zlib source directory
18#   PTHREADS4W_ROOT     - Path to pthreads4w source directory on Windows.
19#                         If not specified then threading will be disabled.
20
21cmake_minimum_required(VERSION 3.11)
22
23include(CheckCCompilerFlag)
24include(FeatureSummary)
25include(FetchContent)
26
27include(../../cmake/detect-coverage.cmake)
28
29option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF)
30option(WITH_THREADS "Enable threading support" ON)
31option(PIGZ_ENABLE_TESTS "Build unit tests" ON)
32option(PIGZ_VERSION "Set the version of pigz to build" "")
33
34project(pigz LANGUAGES C)
35
36# Set code coverage compiler flags
37if(WITH_CODE_COVERAGE)
38    add_code_coverage()
39endif()
40
41# Compiler definitions
42if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
43    add_definitions(-fno-caret-diagnostics)
44elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
45    if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5.0)
46        add_definitions(-Wno-unused-result)
47    endif()
48    if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8.0)
49        add_definitions(-fno-diagnostics-show-caret)
50    endif()
51elseif(WIN32)
52    add_definitions(-D_TIMESPEC_DEFINED)
53    if(MSVC)
54        add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
55    endif()
56endif()
57
58# Fetch pigz source code from official repository
59if(PIGZ_VERSION STREQUAL "")
60    set(PIGZ_TAG master)
61else()
62    set(PIGZ_TAG ${PIGZ_VERSION})
63endif()
64FetchContent_Declare(pigz
65    GIT_REPOSITORY https://github.com/madler/pigz.git
66    GIT_TAG ${PIGZ_TAG})
67FetchContent_MakeAvailable(pigz)
68FetchContent_GetProperties(pigz)
69
70if(NOT pigz_POPULATED)
71    FetchContent_Populate(pigz)
72endif()
73
74set(PIGZ_SRCS
75    ${pigz_SOURCE_DIR}/pigz.c
76    ${pigz_SOURCE_DIR}/try.c)
77
78set(PIGZ_HDRS
79    ${pigz_SOURCE_DIR}/try.h)
80
81add_executable(${PROJECT_NAME} ${PIGZ_SRCS} ${PIGZ_HDRS})
82add_definitions(-DNOZOPFLI)
83if(WIN32)
84    target_include_directories(${PROJECT_NAME} PRIVATE win)
85endif()
86
87# Find and link against pthreads or pthreads4w
88if(WITH_THREADS)
89    if(WIN32)
90        if(DEFINED PTHREADS4W_ROOT)
91            set(CLEANUP_STYLE VC)
92            set(PTHREADS4W_VERSION 3)
93
94            add_subdirectory(${PTHREADS4W_ROOT} ${PTHREADS4W_ROOT} EXCLUDE_FROM_ALL)
95            target_link_libraries(${PROJECT_NAME} pthreadVC3)
96            target_include_directories(${PROJECT_NAME} PRIVATE ${PTHREADS4W_ROOT})
97        else()
98            message(WARNING "Missing pthreads4w root directory")
99            set(WITH_THREADS OFF)
100        endif()
101    else()
102        find_package(Threads REQUIRED)
103        target_link_libraries(${PROJECT_NAME} Threads::Threads)
104        if(NOT APPLE)
105            target_link_libraries(${PROJECT_NAME} m)
106        endif()
107    endif()
108endif()
109
110# Disable threading support
111if(NOT WITH_THREADS)
112    add_definitions(-DNOTHREAD)
113else()
114    set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY SOURCES
115        ${pigz_SOURCE_DIR}/yarn.c
116        ${pigz_SOURCE_DIR}/yarn.h)
117endif()
118
119# Find and link against zlib
120if(NOT DEFINED ZLIB_ROOT)
121    find_package(Zlib REQUIRED)
122endif()
123
124set(ZLIB_COMPAT ON)
125set(ZLIB_ENABLE_TESTS OFF)
126
127add_subdirectory(${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib EXCLUDE_FROM_ALL)
128
129if(NOT DEFINED BUILD_SHARED_LIBS OR NOT BUILD_SHARED_LIBS)
130    set(ZLIB_TARGET zlibstatic)
131else()
132    set(ZLIB_TARGET zlib)
133endif()
134
135target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib)
136target_link_libraries(${PROJECT_NAME} ${ZLIB_TARGET})
137
138if(NOT SKIP_INSTALL_BINARIES AND NOT SKIP_INSTALL_ALL)
139    install(TARGETS ${PROJECT_NAME} DESTINATION "bin")
140endif()
141
142# Add unit tests
143if(PIGZ_ENABLE_TESTS)
144    enable_testing()
145
146    set(PIGZ_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:pigz>)
147
148    macro(test_pigz name path)
149        # Construct compression arguments for pigz
150        set(compress_args -k -c)
151        foreach(extra_arg IN ITEMS "${ARGN}")
152            list(APPEND compress_args ${extra_arg})
153        endforeach()
154
155        # Create unique friendly string for test
156        string(REPLACE ";" "" arg_list "${ARGN}")
157        string(REPLACE " " "" arg_list "${arg_list}")
158        string(REPLACE "-" "" arg_list "${arg_list}")
159
160        set(test_id pigz-${name}-${arg_list})
161
162        if(NOT TEST ${test_id})
163            add_test(NAME ${test_id}
164                COMMAND ${CMAKE_COMMAND}
165                "-DTARGET=${PIGZ_COMMAND}"
166                "-DCOMPRESS_ARGS=${compress_args}"
167                "-DDECOMPRESS_ARGS=-d;-c"
168                -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path}
169                -DTEST_NAME=${test_id}
170                -P ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/test-compress.cmake)
171        endif()
172    endmacro()
173
174    set(TEST_CONFIGS
175        -U       # RLE compression
176        #-H      # Z_HUFFMAN_ONLY (broken in 2.6)
177        -0      # No compression
178        -1      # Deflate quick
179        -4      # Deflate medium (lazy matches)
180        -6      # Deflate medium
181        -9      # Deflate slow
182    )
183
184    file(GLOB_RECURSE TEST_FILE_PATHS
185        LIST_DIRECTORIES false
186        RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
187        ${CMAKE_CURRENT_SOURCE_DIR}/../data/*)
188
189    foreach(TEST_FILE_PATH ${TEST_FILE_PATHS})
190        if("${TEST_FILE_PATH}" MATCHES ".gz$" OR "${TEST_FILE_PATH}" MATCHES ".out$" OR
191           "${TEST_FILE_PATH}" MATCHES "/.git/" OR "${TEST_FILE_PATH}" MATCHES ".md$")
192            continue()
193        endif()
194        foreach(TEST_CONFIG ${TEST_CONFIGS})
195            get_filename_component(TEST_NAME ${TEST_FILE_PATH} NAME)
196            if (TEST_NAME STREQUAL "")
197                continue()
198            endif()
199            test_pigz(${TEST_NAME} ${TEST_FILE_PATH} ${TEST_CONFIG})
200        endforeach()
201    endforeach()
202
203    set(GH979_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:pigz>
204        -d -k -f ${CMAKE_CURRENT_SOURCE_DIR}/../GH-979/pigz-2.6.tar.gz)
205    add_test(NAME GH-979 COMMAND ${GH979_COMMAND})
206endif()
207
208add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting")
209add_feature_info(WITH_THREADS WITH_THREADS "Enable threading support")
210add_feature_info(PIGZ_ENABLE_TESTS PIGZ_ENABLE_TESTS "Build unit tests")
211
212FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES)
213