Commit b8aff90997116a84350018f88f1eabdaa368d11b
Committed by
Jay Berkenbilt
1 parent
105862da
Add cmake configuration files
Showing
11 changed files
with
1454 additions
and
0 deletions
CMakeLists.txt
0 → 100644
| 1 | +# manual/installation.rst mentions the minimum cmake version. | |
| 2 | +cmake_minimum_required(VERSION 3.16) | |
| 3 | + | |
| 4 | +# make_dist expects the version line to be on a line by itself after | |
| 5 | +# the project line. | |
| 6 | +project(qpdf | |
| 7 | + VERSION 10.6.3 | |
| 8 | + LANGUAGES C CXX) | |
| 9 | + | |
| 10 | +# Enable correct rpath handling for MacOSX | |
| 11 | +cmake_policy(SET CMP0042 NEW) | |
| 12 | +# Honor CMAKE_REQUIRED_LIBRARIES when checking for include files | |
| 13 | +cmake_policy(SET CMP0075 NEW) | |
| 14 | + | |
| 15 | +# *** OPTIONS *** | |
| 16 | + | |
| 17 | +# Keep all options here. It's easier to see the interdependencies this | |
| 18 | +# way than spreading them throughout the files. | |
| 19 | +# | |
| 20 | +# ***** Keep manual/installation.rst (_build-options) up to date. ***** | |
| 21 | + | |
| 22 | +include(CMakeDependentOption) | |
| 23 | + | |
| 24 | +# CMAKE_DEPENDENT_OPTION( | |
| 25 | +# OPTION "Description" default-value-if-visible | |
| 26 | +# "when-visible" value-if-not-visible) | |
| 27 | + | |
| 28 | +# Don't write tests based on MAINTAINER_MODE or CI_MODE. Instead, use | |
| 29 | +# them as the basis for dependent options. | |
| 30 | + | |
| 31 | +option(MAINTAINER_MODE "Set options for developing qpdf" OFF) | |
| 32 | +CMAKE_DEPENDENT_OPTION( | |
| 33 | + CI_MODE "Set options for running in CI" OFF | |
| 34 | + "NOT MAINTAINER_MODE" OFF) | |
| 35 | +CMAKE_DEPENDENT_OPTION( | |
| 36 | + WERROR "Treat compiler warnings as errors" OFF | |
| 37 | + "NOT MAINTAINER_MODE; NOT CI_MODE" ON) | |
| 38 | +CMAKE_DEPENDENT_OPTION( | |
| 39 | + GENERATE_AUTO_JOB "Automatically regenerate job files" OFF | |
| 40 | + "NOT MAINTAINER_MODE" ON) | |
| 41 | +CMAKE_DEPENDENT_OPTION( | |
| 42 | + SHOW_FAILED_TEST_OUTPUT "Show qtest output on failure" OFF | |
| 43 | + "NOT CI_MODE" ON) | |
| 44 | + | |
| 45 | +# To allow building doc to be disabled in maintainer mode, handle the | |
| 46 | +# condition manually rather than using a dependent option. | |
| 47 | +if(MAINTAINER_MODE) | |
| 48 | + set(default_BUILD_DOC ON) | |
| 49 | +else() | |
| 50 | + set(default_BUILD_DOC OFF) | |
| 51 | +endif() | |
| 52 | +option(BUILD_DOC "Build documentation" ${default_BUILD_DOC}) | |
| 53 | +# The values of BUILD_DOC_HTML and BUILD_DOC_PDF are ignored without | |
| 54 | +# BUILD_DOC, so setting them to ON when not visible forces them to be | |
| 55 | +# on in MAINTAINER_MODE and is harmless if BUILD_DOC is off. | |
| 56 | +CMAKE_DEPENDENT_OPTION( | |
| 57 | + BUILD_DOC_HTML "Build HTML documentation" | |
| 58 | + ON "BUILD_DOC;NOT MAINTAINER_MODE" ON) | |
| 59 | +CMAKE_DEPENDENT_OPTION( | |
| 60 | + BUILD_DOC_PDF "Build PDF documentation" | |
| 61 | + ON "BUILD_DOC;NOT MAINTAINER_MODE" ON) | |
| 62 | +CMAKE_DEPENDENT_OPTION( | |
| 63 | + BUILD_DOC_DIST "Create distribution of manual" ON | |
| 64 | + "BUILD_DOC_PDF;BUILD_DOC_HTML" OFF) | |
| 65 | + | |
| 66 | +option(BUILD_SHARED_LIBS "Build qpdf shared libraries" ON) | |
| 67 | +option(BUILD_STATIC_LIBS "Build qpdf static libraries" ON) | |
| 68 | +option(QTEST_COLOR "Whether qtest's output should be in color" ON) | |
| 69 | +option(USE_INSECURE_RANDOM "Use insecure random numbers" OFF) | |
| 70 | +option(SKIP_OS_SECURE_RANDOM | |
| 71 | + "Suppress use of OS-provided secure random numbers" OFF) | |
| 72 | +CMAKE_DEPENDENT_OPTION( | |
| 73 | + AVOID_WINDOWS_HANDLE "Avoid use of HANDLE in Windows" OFF | |
| 74 | + "WIN32" OFF) | |
| 75 | + | |
| 76 | +option(OSS_FUZZ "Specific build configuration for the oss-fuzz project" OFF) | |
| 77 | + | |
| 78 | +option(USE_IMPLICIT_CRYPTO "Enable any available external crypto provider" ON) | |
| 79 | +CMAKE_DEPENDENT_OPTION( | |
| 80 | + ALLOW_CRYPTO_NATIVE "Allow native crypto as as fallback" ON | |
| 81 | + "USE_IMPLICIT_CRYPTO" OFF) | |
| 82 | +CMAKE_DEPENDENT_OPTION( | |
| 83 | + REQUIRE_CRYPTO_NATIVE "Require native crypto provider" OFF | |
| 84 | + "NOT MAINTAINER_MODE; NOT CI_MODE" ON) | |
| 85 | +option(REQUIRE_CRYPTO_OPENSSL "Require openssl crypto" OFF) | |
| 86 | +option(REQUIRE_CRYPTO_GNUTLS "Require gnutls crypto" OFF) | |
| 87 | +set(DEFAULT_CRYPTO CACHE STRING "") | |
| 88 | +option(DEFAULT_CRYPTO | |
| 89 | + "Specify default crypto; otherwise chosen automatically" "") | |
| 90 | + | |
| 91 | +# INSTALL_MANUAL is not dependent on building docs. When creating some | |
| 92 | +# distributions, we build the doc in one run, copy doc-dist in, and | |
| 93 | +# install it elsewhere. | |
| 94 | +option(INSTALL_MANUAL "Install documentation" OFF) | |
| 95 | + | |
| 96 | +option(INSTALL_PKGCONFIG "Install pkgconfig file" ON) | |
| 97 | +option(INSTALL_CMAKE_PACKAGE "Install cmake package files" ON) | |
| 98 | +option(INSTALL_EXAMPLES "Install example files" ON) | |
| 99 | + | |
| 100 | +# *** END OPTIONS *** | |
| 101 | + | |
| 102 | +if(NOT (BUILD_STATIC_LIBS OR BUILD_SHARED_LIBS)) | |
| 103 | + message( | |
| 104 | + FATAL_ERROR "At least one of static or shared libraries must be built") | |
| 105 | +endif() | |
| 106 | + | |
| 107 | +add_compile_definitions($<$<COMPILE_LANGUAGE:CXX>:POINTERHOLDER_TRANSITION=2>) | |
| 108 | + | |
| 109 | +enable_testing() | |
| 110 | +set(RUN_QTEST perl ${qpdf_SOURCE_DIR}/run-qtest) | |
| 111 | + | |
| 112 | +if(WIN32) | |
| 113 | + find_program(COPY_COMMAND NAMES cp copy) | |
| 114 | + if(COPY_COMMAND STREQUAL "COPY_COMMAND-NOTFOUND") | |
| 115 | + set(COPY_COMMAND "copy") | |
| 116 | + endif() | |
| 117 | +else() | |
| 118 | + set(COPY_COMMAND "cp") | |
| 119 | +endif() | |
| 120 | + | |
| 121 | +# For a long time, qpdf used libtool's version system. We are no | |
| 122 | +# longer doing that, but to avoid potential conflict with older | |
| 123 | +# versions, continue to have the shared library symlink point to a | |
| 124 | +# file whose version shares minor and patch with the project version | |
| 125 | +# and major with the SOVERSION. Starting with the transition to cmake, | |
| 126 | +# increment SOVERSION every time we increment the project major | |
| 127 | +# version. This works because qpdf uses semantic versioning. qpdf 10.x | |
| 128 | +# was libqpdf28, so start from there. | |
| 129 | +math(EXPR qpdf_SOVERSION "${PROJECT_VERSION_MAJOR} + 18") | |
| 130 | +set(qpdf_LIBVERSION ${qpdf_SOVERSION}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) | |
| 131 | + | |
| 132 | +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) | |
| 133 | + message(FATAL_ERROR " | |
| 134 | +Please build with cmake in a subdirectory, e.g. | |
| 135 | + mkdir build | |
| 136 | + cmake .. | |
| 137 | + cmake --build . | |
| 138 | +Please remove CMakeCache.txt and the CMakeFiles directories.") | |
| 139 | +endif() | |
| 140 | + | |
| 141 | +set(CMAKE_CXX_STANDARD 14) | |
| 142 | +set(CMAKE_CXX_EXTENSIONS OFF) | |
| 143 | +set(CMAKE_CXX_STANDARD_REQUIRED ON) | |
| 144 | +set(CMAKE_C_VISIBILITY_PRESET hidden) | |
| 145 | +set(CMAKE_CXX_VISIBILITY_PRESET hidden) | |
| 146 | + | |
| 147 | +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") | |
| 148 | + | |
| 149 | +if(WIN32 AND NOT SKIP_OS_SECURE_RANDOM) | |
| 150 | + list(APPEND CMAKE_REQUIRED_LIBRARIES Advapi32) | |
| 151 | +endif() | |
| 152 | + | |
| 153 | +include(CheckCXXSourceCompiles) | |
| 154 | +function(check_atomic) | |
| 155 | + foreach(I 0 1) | |
| 156 | + if(I) | |
| 157 | + set(CMAKE_REQUIRED_LIBRARIES atomic) | |
| 158 | + endif() | |
| 159 | + check_cxx_source_compiles( | |
| 160 | + "#include <atomic> | |
| 161 | +int main() { | |
| 162 | + static std::atomic<int> a{0}; | |
| 163 | + a = a.fetch_add(1); | |
| 164 | + return 0; | |
| 165 | +}" | |
| 166 | + ATOMIC_WORKED${I}) | |
| 167 | + if(ATOMIC_WORKED0) | |
| 168 | + return() | |
| 169 | + endif() | |
| 170 | + endforeach() | |
| 171 | + if(ATOMIC_WORKED1) | |
| 172 | + list(APPEND CMAKE_REQUIRED_LIBRARIES atomic) | |
| 173 | + endif() | |
| 174 | +endfunction() | |
| 175 | +check_atomic() | |
| 176 | + | |
| 177 | +set(WINDOWS_WMAIN_COMPILE "") | |
| 178 | +set(WINDOWS_WMAIN_LINK "") | |
| 179 | +if(WIN32) | |
| 180 | + function(check_wmain) | |
| 181 | + foreach(I 0 1) | |
| 182 | + if(NOT WINDOWS_WMAIN_COMPILE) | |
| 183 | + if(I) | |
| 184 | + set(CMAKE_REQUIRED_LINK_OPTIONS -municode) | |
| 185 | + endif() | |
| 186 | + check_cxx_source_compiles( | |
| 187 | + "#include <windows.h> | |
| 188 | +#include <string.h> | |
| 189 | +#include <stdio.h> | |
| 190 | +extern \"C\" | |
| 191 | +int wmain(int argc, wchar_t* argv[]) | |
| 192 | +{ | |
| 193 | + size_t x = wcslen(argv[0]); | |
| 194 | + return 0; | |
| 195 | +} | |
| 196 | +" | |
| 197 | + WMAIN_WORKED${I}) | |
| 198 | + endif() | |
| 199 | + endforeach() | |
| 200 | + if(WMAIN_WORKED1 OR WMAIN_WORKED1) | |
| 201 | + set(WINDOWS_WMAIN_COMPILE -DWINDOWS_WMAIN PARENT_SCOPE) | |
| 202 | + if(WMAIN_WORKED1 AND NOT WMAIN_WORKED0) | |
| 203 | + set(WINDOWS_WMAIN_LINK -municode PARENT_SCOPE) | |
| 204 | + endif() | |
| 205 | + endif() | |
| 206 | + endfunction() | |
| 207 | + check_wmain() | |
| 208 | +endif() | |
| 209 | + | |
| 210 | +if(MSVC) | |
| 211 | + list(APPEND CMAKE_REQUIRED_LINK_OPTIONS -link setargv.obj) | |
| 212 | + list(APPEND WINDOWS_WMAIN_LINK -link wsetargv.obj) | |
| 213 | +endif() | |
| 214 | + | |
| 215 | +include(GNUInstallDirs) | |
| 216 | + | |
| 217 | +# Compiler flags | |
| 218 | +# | |
| 219 | +# **NOTE** -- each flag must have its own cache variable. | |
| 220 | + | |
| 221 | +include(qpdfCheckFlag) | |
| 222 | +if(WERROR) | |
| 223 | + if(MSVC) | |
| 224 | + add_compile_options(/WX) | |
| 225 | + else() | |
| 226 | + qpdf_maybe_add_flag(C -Werror flag_werror) | |
| 227 | + endif() | |
| 228 | +endif() | |
| 229 | + | |
| 230 | +if(MSVC) | |
| 231 | + # /Gy combines identical functions -- useful with C++ templates | |
| 232 | + add_compile_options(/Gy) | |
| 233 | + add_compile_options(/W3) # warning level 3 | |
| 234 | +else() | |
| 235 | + qpdf_maybe_add_flag(C -Wall flag_wall) | |
| 236 | + qpdf_maybe_add_flag(C -Wconversion flag_conversion) | |
| 237 | + qpdf_maybe_add_flag(C -Wsign-conversion flag_sign-conversion) | |
| 238 | + qpdf_maybe_add_flag(C -Wshadow=local flag_shadow_local) | |
| 239 | + qpdf_maybe_add_flag(CXX -Wold-style-cast flag_old-style-cast) | |
| 240 | +endif() | |
| 241 | + | |
| 242 | +# We don't include the jpeg library's include path in the PUBLIC | |
| 243 | +# interface for libqpdf since only Pl_DCT.hh requires it. This is | |
| 244 | +# documented. Some examples and tests use it though so we have to | |
| 245 | +# define it. CMakeLists.txt for libqpdf sets the value for | |
| 246 | +# JPEG_INCLUDE which can be selectively added to include paths other | |
| 247 | +# tools. | |
| 248 | +set(JPEG_INCLUDE) | |
| 249 | + | |
| 250 | +if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) | |
| 251 | + set(WORDSIZE 64) | |
| 252 | +else() | |
| 253 | + set(WORDSIZE 32) | |
| 254 | +endif() | |
| 255 | +if(MSVC) | |
| 256 | + set(CPACK_SYSTEM_NAME "msvc${WORDSIZE}") | |
| 257 | +elseif(MINGW) | |
| 258 | + set(CPACK_SYSTEM_NAME "mingw${WORDSIZE}") | |
| 259 | +endif() | |
| 260 | +set(CPACK_RESOURCE_FILE_LICENSE "${qpdf_SOURCE_DIR}/LICENSE.txt") | |
| 261 | +set(CPACK_PACKAGE_HOMEPAGE_URL "https://qpdf.sourceforge.io/") | |
| 262 | +set(CPACK_NSIS_MUI_ICON "${qpdf_SOURCE_DIR}/logo/qpdf.ico") | |
| 263 | + | |
| 264 | +include(CPack) | |
| 265 | + | |
| 266 | +# Install components -- documented in _installation in | |
| 267 | +# manual/installation.rst. | |
| 268 | +set(COMPONENT_DEV "dev") | |
| 269 | +set(COMPONENT_LIB "lib") # runtime library | |
| 270 | +set(COMPONENT_CLI "cli") | |
| 271 | +set(COMPONENT_DOC "doc") | |
| 272 | +set(COMPONENT_EXAMPLES "examples") # example sources | |
| 273 | + | |
| 274 | +if(WIN32) | |
| 275 | + include(InstallRequiredSystemLibraries) | |
| 276 | +endif() | |
| 277 | + | |
| 278 | +# add_subdirectory order affects test order | |
| 279 | +add_subdirectory(include) | |
| 280 | +add_subdirectory(libqpdf) | |
| 281 | +add_subdirectory(qpdf) | |
| 282 | +add_subdirectory(libtests) | |
| 283 | +add_subdirectory(examples) | |
| 284 | +add_subdirectory(zlib-flate) | |
| 285 | +add_subdirectory(manual) | |
| 286 | +add_subdirectory(fuzz) | |
| 287 | + | |
| 288 | +# We don't need to show everything -- just the things that we really | |
| 289 | +# need to be sure are right or that are turned on or off with complex | |
| 290 | +# logic. | |
| 291 | +get_property(MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | |
| 292 | +message(STATUS "") | |
| 293 | +message(STATUS "*** Summary ***") | |
| 294 | +message(STATUS " qpdf version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") | |
| 295 | +if(MULTI_CONFIG) | |
| 296 | + message(STATUS " build type: specify --config at build time") | |
| 297 | +elseif(CMAKE_BUILD_TYPE) | |
| 298 | + message(STATUS " build type: ${CMAKE_BUILD_TYPE}") | |
| 299 | +endif() | |
| 300 | +message(STATUS " build shared libraries: ${BUILD_SHARED_LIBS}") | |
| 301 | +message(STATUS " build static libraries: ${BUILD_STATIC_LIBS}") | |
| 302 | +message(STATUS " build manual: ${BUILD_DOC}") | |
| 303 | +message(STATUS " compiler warnings are errors: ${WERROR}") | |
| 304 | +message(STATUS " system: ${CPACK_SYSTEM_NAME}") | |
| 305 | +message(STATUS "") | |
| 306 | +message(STATUS "*** Options Summary ***") | |
| 307 | +foreach(PROP | |
| 308 | + COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS | |
| 309 | + COMPILE_DEFINITIONS INTERFACE_COMPILE_DEFINITIONS | |
| 310 | + INCLUDE_DIRECTORIES INTERFACE_INCLUDE_DIRECTORIES | |
| 311 | + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES | |
| 312 | + LINK_OPTIONS INTERFACE_LINK_OPTIONS | |
| 313 | + LINK_LIBRARIES INTERFACE_LINK_LIBRARIES | |
| 314 | + LINK_DIRECTORIES INTERFACE_LINK_DIRECTORIES) | |
| 315 | + get_target_property(VAL libqpdf ${PROP}) | |
| 316 | + if(NOT (VAL STREQUAL "VAL-NOTFOUND")) | |
| 317 | + message(STATUS " ${PROP}: ${VAL}") | |
| 318 | + endif() | |
| 319 | +endforeach() | |
| 320 | +if(APPLE) | |
| 321 | + message(STATUS " CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}") | |
| 322 | +endif() | |
| 323 | +message(STATUS "") | |
| 324 | +message(STATUS "See above for crypto summary.") | |
| 325 | +message(STATUS "") | |
| 326 | +if(NOT (MULTI_CONFIG OR CMAKE_BUILD_TYPE)) | |
| 327 | + message(WARNING " CMAKE_BUILD_TYPE is not set; using default settings") | |
| 328 | +endif() | ... | ... |
cmake/qpdfCheckFlag.cmake
0 → 100644
| 1 | +include(CheckCXXCompilerFlag) | |
| 2 | +include(CheckCCompilerFlag) | |
| 3 | + | |
| 4 | +function(qpdf_maybe_add_flag lang flag var) | |
| 5 | + if(${lang} STREQUAL "C") | |
| 6 | + check_c_compiler_flag(${flag} ${var}) | |
| 7 | + elseif(${lang} STREQUAL "CXX") | |
| 8 | + check_cxx_compiler_flag(${flag} ${var}) | |
| 9 | + endif() | |
| 10 | + if(${var}) | |
| 11 | + message(STATUS "Using ${flag}: YES") | |
| 12 | + if(${lang} STREQUAL "C") | |
| 13 | + # Add for C and C++ | |
| 14 | + add_compile_options(${flag}) | |
| 15 | + else() | |
| 16 | + add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${flag}>) | |
| 17 | + endif() | |
| 18 | + else() | |
| 19 | + message(STATUS "Using ${flag}: NO") | |
| 20 | + endif() | |
| 21 | +endfunction() | ... | ... |
examples/CMakeLists.txt
0 → 100644
| 1 | +set(EXAMPLE_CXX_PROGRAMS | |
| 2 | + pdf-attach-file | |
| 3 | + pdf-bookmarks | |
| 4 | + pdf-count-strings | |
| 5 | + pdf-create | |
| 6 | + pdf-custom-filter | |
| 7 | + pdf-double-page-size | |
| 8 | + pdf-filter-tokens | |
| 9 | + pdf-invert-images | |
| 10 | + pdf-mod-info | |
| 11 | + pdf-name-number-tree | |
| 12 | + pdf-npages | |
| 13 | + pdf-overlay-page | |
| 14 | + pdf-parse-content | |
| 15 | + pdf-set-form-values | |
| 16 | + pdf-split-pages | |
| 17 | + qpdf-job) | |
| 18 | +set(EXAMPLE_C_PROGRAMS | |
| 19 | + pdf-c-objects | |
| 20 | + pdf-linearize | |
| 21 | + qpdfjob-c) | |
| 22 | + | |
| 23 | +foreach(PROG ${EXAMPLE_CXX_PROGRAMS}) | |
| 24 | + add_executable(${PROG} ${PROG}.cc) | |
| 25 | + target_link_libraries(${PROG} libqpdf) | |
| 26 | +endforeach() | |
| 27 | +foreach(PROG ${EXAMPLE_C_PROGRAMS}) | |
| 28 | + add_executable(${PROG} ${PROG}.c) | |
| 29 | + target_link_libraries(${PROG} libqpdf) | |
| 30 | + set_property(TARGET ${PROG} PROPERTY LINKER_LANGUAGE CXX) | |
| 31 | +endforeach() | |
| 32 | +target_include_directories(pdf-create PRIVATE ${JPEG_INCLUDE}) | |
| 33 | + | |
| 34 | +add_test( | |
| 35 | + NAME examples | |
| 36 | + COMMAND ${RUN_QTEST} | |
| 37 | + --top ${qpdf_SOURCE_DIR} | |
| 38 | + --bin $<TARGET_FILE_DIR:pdf-create> | |
| 39 | + --bin $<TARGET_FILE_DIR:qpdf> | |
| 40 | + --bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL | |
| 41 | + --code ${qpdf_SOURCE_DIR}/examples | |
| 42 | + --color ${QTEST_COLOR} | |
| 43 | + --show-on-failure ${SHOW_FAILED_TEST_OUTPUT} | |
| 44 | + --tc "${qpdf_SOURCE_DIR}/examples/*.cc" | |
| 45 | + --tc "${qpdf_SOURCE_DIR}/examples/*.c") | |
| 46 | + | |
| 47 | +file(GLOB EXAMPLES_SRC "*.c" "*.cc") | |
| 48 | +if(INSTALL_EXAMPLES) | |
| 49 | + install(FILES ${EXAMPLES_SRC} | |
| 50 | + DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples | |
| 51 | + COMPONENT ${COMPONENT_EXAMPLES}) | |
| 52 | +endif() | ... | ... |
fuzz/CMakeLists.txt
0 → 100644
| 1 | +# This directory contains support for Google's oss-fuzz project. See | |
| 2 | +# https://github.com/google/oss-fuzz/tree/master/projects/qpdf | |
| 3 | + | |
| 4 | +set(FUZZERS | |
| 5 | + qpdf_fuzzer | |
| 6 | + ascii85_fuzzer | |
| 7 | + dct_fuzzer | |
| 8 | + flate_fuzzer | |
| 9 | + hex_fuzzer | |
| 10 | + lzw_fuzzer | |
| 11 | + pngpredictor_fuzzer | |
| 12 | + runlength_fuzzer | |
| 13 | + tiffpredictor_fuzzer) | |
| 14 | + | |
| 15 | +# The oss-fuzz project provides LIB_FUZZING_ENGINE and OUT environment | |
| 16 | +# variables. For local testing, provide values if not set. | |
| 17 | +set(LIB_FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE}) | |
| 18 | +if(NOT LIB_FUZZING_ENGINE) | |
| 19 | + # When running from oss-fuzz, LIB_FUZZING_ENGINE points to a | |
| 20 | + # static library that contains main. | |
| 21 | + add_library(standalone_fuzzer STATIC standalone_fuzz_target_runner.cc) | |
| 22 | + target_include_directories( | |
| 23 | + standalone_fuzzer PRIVATE ${qpdf_SOURCE_DIR}/include) | |
| 24 | + set(LIB_FUZZING_ENGINE standalone_fuzzer) | |
| 25 | +endif() | |
| 26 | +set(FUZZ_OUT $ENV{OUT}) | |
| 27 | +if(NOT FUZZ_OUT) | |
| 28 | + set(FUZZ_OUT ${CMAKE_CURRENT_BINARY_DIR}/fuzz-install) | |
| 29 | +endif() | |
| 30 | + | |
| 31 | +if(OSS_FUZZ) | |
| 32 | + # We need to link jpeg and zlib statically for oss-fuzz. Construct | |
| 33 | + # our own object library without the external dependencies and add | |
| 34 | + # what we need. | |
| 35 | + add_library(libqpdf_fuzz STATIC $<TARGET_OBJECTS:libqpdf_object>) | |
| 36 | + target_link_libraries(libqpdf_fuzz INTERFACE libjpeg.a libz.a) | |
| 37 | + target_include_directories(libqpdf_fuzz | |
| 38 | + PUBLIC | |
| 39 | + ${JPEG_INCLUDE} | |
| 40 | + ${qpdf_SOURCE_DIR}/include | |
| 41 | + ${qpdf_SOURCE_DIR}/libqpdf) | |
| 42 | +else() | |
| 43 | + add_library(libqpdf_fuzz ALIAS libqpdf_object) | |
| 44 | +endif() | |
| 45 | + | |
| 46 | +foreach(PROG ${FUZZERS}) | |
| 47 | + add_executable(${PROG} ${PROG}.cc) | |
| 48 | + target_link_libraries(${PROG} ${LIB_FUZZING_ENGINE}) | |
| 49 | + target_link_libraries(${PROG} libqpdf_fuzz) | |
| 50 | +endforeach() | |
| 51 | + | |
| 52 | +# Files from the test suite that are good for seeding the fuzzer. | |
| 53 | +# Update count for qpdf in @fuzzers qtest/fuzz.test if you change this list. | |
| 54 | +set(CORPUS_FROM_TEST | |
| 55 | + stream-data.pdf | |
| 56 | + lin5.pdf | |
| 57 | + field-types.pdf | |
| 58 | + image-streams-small.pdf | |
| 59 | + need-appearances.pdf | |
| 60 | + outlines-with-actions.pdf | |
| 61 | + outlines-with-old-root-dests.pdf | |
| 62 | + page-labels-and-outlines.pdf | |
| 63 | + page-labels-num-tree.pdf | |
| 64 | + dr-with-indirect-item.pdf | |
| 65 | + fuzz-16214.pdf | |
| 66 | + issue-99b.pdf | |
| 67 | + issue-99.pdf | |
| 68 | + issue-100.pdf | |
| 69 | + issue-101.pdf | |
| 70 | + issue-106.pdf | |
| 71 | + issue-117.pdf | |
| 72 | + issue-119.pdf | |
| 73 | + issue-120.pdf | |
| 74 | + issue-141a.pdf | |
| 75 | + issue-141b.pdf | |
| 76 | + issue-143.pdf | |
| 77 | + issue-146.pdf | |
| 78 | + issue-147.pdf | |
| 79 | + issue-148.pdf | |
| 80 | + issue-149.pdf | |
| 81 | + issue-150.pdf | |
| 82 | + issue-202.pdf | |
| 83 | + issue-263.pdf | |
| 84 | + issue-335a.pdf | |
| 85 | + issue-335b.pdf) | |
| 86 | + | |
| 87 | +# Any file that qpdf_fuzzer should be tested with can be named | |
| 88 | +# something.fuzz and dropped into qpdf_extra. Update count for qpdf in | |
| 89 | +# @fuzzers qtest/fuzz.test if you change this list. | |
| 90 | +set(CORPUS_OTHER | |
| 91 | + 15316.fuzz | |
| 92 | + 15387.fuzz | |
| 93 | + 15390.fuzz | |
| 94 | + 15442.fuzz | |
| 95 | + 15445.fuzz | |
| 96 | + 15983.fuzz | |
| 97 | + 16172.fuzz | |
| 98 | + 16301.fuzz | |
| 99 | + 16953.fuzz | |
| 100 | + 18241.fuzz | |
| 101 | + 18247.fuzz | |
| 102 | + 23172.fuzz | |
| 103 | + 23599.fuzz | |
| 104 | + 23642.fuzz | |
| 105 | + 23642-mod.fuzz | |
| 106 | + 26761.fuzz | |
| 107 | + 26994.fuzz | |
| 108 | + 27393.fuzz | |
| 109 | + 28262.fuzz | |
| 110 | + 30507.fuzz | |
| 111 | + 37740.fuzz) | |
| 112 | + | |
| 113 | +set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) | |
| 114 | +file(MAKE_DIRECTORY ${CORPUS_DIR}) | |
| 115 | +function(copy_fuzz FROM) | |
| 116 | + file(SHA1 ${FROM} SHA) | |
| 117 | + set(OUT ${CORPUS_DIR}/${SHA}) | |
| 118 | + add_custom_command( | |
| 119 | + OUTPUT ${OUT} | |
| 120 | + COMMAND ${COPY_COMMAND} $<SHELL_PATH:${FROM}> $<SHELL_PATH:${OUT}>) | |
| 121 | + set(CORPUS_FILE ${OUT} PARENT_SCOPE) | |
| 122 | +endfunction() | |
| 123 | + | |
| 124 | +list(APPEND CORPUS_FILES) | |
| 125 | +foreach(F ${CORPUS_FROM_TEST}) | |
| 126 | + copy_fuzz(${qpdf_SOURCE_DIR}/qpdf/qtest/qpdf/${F}) | |
| 127 | + list(APPEND CORPUS_FILES ${CORPUS_FILE}) | |
| 128 | +endforeach() | |
| 129 | +foreach(F ${CORPUS_OTHER}) | |
| 130 | + copy_fuzz(${CMAKE_CURRENT_SOURCE_DIR}/qpdf_extra/${F}) | |
| 131 | + list(APPEND CORPUS_FILES ${CORPUS_FILE}) | |
| 132 | +endforeach() | |
| 133 | +add_custom_target(qpdf_corpus ALL | |
| 134 | + DEPENDS ${CORPUS_FILES}) | |
| 135 | + | |
| 136 | +add_test( | |
| 137 | + NAME fuzz | |
| 138 | + COMMAND ${RUN_QTEST} | |
| 139 | + --env QPDF_FUZZ_CORPUS=${CORPUS_DIR} | |
| 140 | + --top ${qpdf_SOURCE_DIR} | |
| 141 | + --bin $<TARGET_FILE_DIR:qpdf_fuzzer> | |
| 142 | + --bin $<TARGET_FILE_DIR:qpdf> | |
| 143 | + --code ${qpdf_SOURCE_DIR}/fuzz | |
| 144 | + --color ${QTEST_COLOR} | |
| 145 | + --show-on-failure ${SHOW_FAILED_TEST_OUTPUT}) | |
| 146 | + | |
| 147 | +if(OSS_FUZZ) | |
| 148 | + list(APPEND SEED_CORPUS_ZIPS) | |
| 149 | + foreach(F ${FUZZERS}) | |
| 150 | + if(F STREQUAL qpdf_fuzzer) | |
| 151 | + set(SEED_DIR ${CORPUS_DIR}) | |
| 152 | + else() | |
| 153 | + set(SEED_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${F}_seed_corpus) | |
| 154 | + endif() | |
| 155 | + set(SEED_ZIP ${CMAKE_CURRENT_BINARY_DIR}/${F}_seed_corpus.zip) | |
| 156 | + add_custom_command(OUTPUT ${SEED_ZIP} | |
| 157 | + COMMAND zip -q -r ${SEED_ZIP} . | |
| 158 | + WORKING_DIRECTORY ${SEED_DIR}) | |
| 159 | + list(APPEND SEED_CORPUS_ZIPS ${SEED_ZIP}) | |
| 160 | + endforeach() | |
| 161 | + add_custom_target(seed_corpus_zips ALL DEPENDS ${SEED_CORPUS_ZIPS}) | |
| 162 | + add_dependencies(seed_corpus_zips qpdf_corpus) | |
| 163 | + add_custom_target(fuzzers) | |
| 164 | + add_dependencies(fuzzers ${FUZZERS} seed_corpus_zips) | |
| 165 | + install( | |
| 166 | + TARGETS ${FUZZERS} | |
| 167 | + DESTINATION ${FUZZ_OUT} | |
| 168 | + EXCLUDE_FROM_ALL | |
| 169 | + COMPONENT fuzz) | |
| 170 | + install( | |
| 171 | + FILES | |
| 172 | + ${CMAKE_CURRENT_SOURCE_DIR}/pdf.dict | |
| 173 | + ${CMAKE_CURRENT_SOURCE_DIR}/qpdf_fuzzer.options | |
| 174 | + ${SEED_CORPUS_ZIPS} | |
| 175 | + DESTINATION ${FUZZ_OUT} | |
| 176 | + EXCLUDE_FROM_ALL | |
| 177 | + COMPONENT fuzz) | |
| 178 | +endif() | ... | ... |
include/CMakeLists.txt
0 → 100644
| 1 | +set(qpdf_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) | |
| 2 | + | |
| 3 | +# While globs are not considered best practice, it makes sense for | |
| 4 | +# installation o header files. When compiling, you specify an entire | |
| 5 | +# directory, so not doing the same at installation time creates a high | |
| 6 | +# risk that forgetting to explicitly add a header to an installation | |
| 7 | +# list would not be detected in CI or at any time until an end user | |
| 8 | +# tries to build code. | |
| 9 | +install(DIRECTORY qpdf | |
| 10 | + TYPE INCLUDE | |
| 11 | + COMPONENT ${COMPONENT_DEV} | |
| 12 | + FILES_MATCHING PATTERN "*.h" PATTERN "*.hh") | ... | ... |
libqpdf/CMakeLists.txt
0 → 100644
| 1 | + | |
| 2 | +if(GENERATE_AUTO_JOB) | |
| 3 | + execute_process( | |
| 4 | + COMMAND ${qpdf_SOURCE_DIR}/generate_auto_job --generate | |
| 5 | + WORKING_DIRECTORY ${qpdf_SOURCE_DIR}) | |
| 6 | +endif() | |
| 7 | + | |
| 8 | +set(libqpdf_crypto_native | |
| 9 | + AES_PDF_native.cc | |
| 10 | + MD5_native.cc | |
| 11 | + QPDFCrypto_native.cc | |
| 12 | + RC4_native.cc | |
| 13 | + SHA2_native.cc | |
| 14 | + rijndael.cc | |
| 15 | + sha2.c | |
| 16 | + sha2big.c) | |
| 17 | + | |
| 18 | +set(libqpdf_crypto_openssl | |
| 19 | + QPDFCrypto_openssl.cc) | |
| 20 | + | |
| 21 | +set(libqpdf_crypto_gnutls | |
| 22 | + QPDFCrypto_gnutls.cc) | |
| 23 | + | |
| 24 | +set(libqpdf_SOURCES | |
| 25 | + BitStream.cc | |
| 26 | + BitWriter.cc | |
| 27 | + Buffer.cc | |
| 28 | + BufferInputSource.cc | |
| 29 | + ClosedFileInputSource.cc | |
| 30 | + ContentNormalizer.cc | |
| 31 | + CryptoRandomDataProvider.cc | |
| 32 | + FileInputSource.cc | |
| 33 | + InputSource.cc | |
| 34 | + InsecureRandomDataProvider.cc | |
| 35 | + JSON.cc | |
| 36 | + JSONHandler.cc | |
| 37 | + MD5.cc | |
| 38 | + NNTree.cc | |
| 39 | + OffsetInputSource.cc | |
| 40 | + PDFVersion.cc | |
| 41 | + Pipeline.cc | |
| 42 | + Pl_AES_PDF.cc | |
| 43 | + Pl_ASCII85Decoder.cc | |
| 44 | + Pl_ASCIIHexDecoder.cc | |
| 45 | + Pl_Buffer.cc | |
| 46 | + Pl_Concatenate.cc | |
| 47 | + Pl_Count.cc | |
| 48 | + Pl_DCT.cc | |
| 49 | + Pl_Discard.cc | |
| 50 | + Pl_Flate.cc | |
| 51 | + Pl_LZWDecoder.cc | |
| 52 | + Pl_MD5.cc | |
| 53 | + Pl_PNGFilter.cc | |
| 54 | + Pl_QPDFTokenizer.cc | |
| 55 | + Pl_RC4.cc | |
| 56 | + Pl_RunLength.cc | |
| 57 | + Pl_SHA2.cc | |
| 58 | + Pl_StdioFile.cc | |
| 59 | + Pl_TIFFPredictor.cc | |
| 60 | + QPDF.cc | |
| 61 | + QPDFAcroFormDocumentHelper.cc | |
| 62 | + QPDFAnnotationObjectHelper.cc | |
| 63 | + QPDFArgParser.cc | |
| 64 | + QPDFCryptoProvider.cc | |
| 65 | + QPDFEFStreamObjectHelper.cc | |
| 66 | + QPDFEmbeddedFileDocumentHelper.cc | |
| 67 | + QPDFExc.cc | |
| 68 | + QPDFFileSpecObjectHelper.cc | |
| 69 | + QPDFFormFieldObjectHelper.cc | |
| 70 | + QPDFJob.cc | |
| 71 | + QPDFJob_argv.cc | |
| 72 | + QPDFJob_config.cc | |
| 73 | + QPDFJob_json.cc | |
| 74 | + QPDFMatrix.cc | |
| 75 | + QPDFNameTreeObjectHelper.cc | |
| 76 | + QPDFNumberTreeObjectHelper.cc | |
| 77 | + QPDFObjGen.cc | |
| 78 | + QPDFObject.cc | |
| 79 | + QPDFObjectHandle.cc | |
| 80 | + QPDFOutlineDocumentHelper.cc | |
| 81 | + QPDFOutlineObjectHelper.cc | |
| 82 | + QPDFPageDocumentHelper.cc | |
| 83 | + QPDFPageLabelDocumentHelper.cc | |
| 84 | + QPDFPageObjectHelper.cc | |
| 85 | + QPDFStreamFilter.cc | |
| 86 | + QPDFSystemError.cc | |
| 87 | + QPDFTokenizer.cc | |
| 88 | + QPDFUsage.cc | |
| 89 | + QPDFWriter.cc | |
| 90 | + QPDFXRefEntry.cc | |
| 91 | + QPDF_Array.cc | |
| 92 | + QPDF_Bool.cc | |
| 93 | + QPDF_Dictionary.cc | |
| 94 | + QPDF_InlineImage.cc | |
| 95 | + QPDF_Integer.cc | |
| 96 | + QPDF_Name.cc | |
| 97 | + QPDF_Null.cc | |
| 98 | + QPDF_Operator.cc | |
| 99 | + QPDF_Real.cc | |
| 100 | + QPDF_Reserved.cc | |
| 101 | + QPDF_Stream.cc | |
| 102 | + QPDF_String.cc | |
| 103 | + QPDF_encryption.cc | |
| 104 | + QPDF_linearization.cc | |
| 105 | + QPDF_optimization.cc | |
| 106 | + QPDF_pages.cc | |
| 107 | + QTC.cc | |
| 108 | + QUtil.cc | |
| 109 | + RC4.cc | |
| 110 | + ResourceFinder.cc | |
| 111 | + SecureRandomDataProvider.cc | |
| 112 | + SF_FlateLzwDecode.cc | |
| 113 | + SparseOHArray.cc | |
| 114 | + qpdf-c.cc | |
| 115 | + qpdfjob-c.cc) | |
| 116 | + | |
| 117 | +include(FindPkgConfig) | |
| 118 | +include(CheckTypeSize) | |
| 119 | +include(CheckIncludeFile) | |
| 120 | +include(CheckCSourceCompiles) | |
| 121 | +include(CheckCSourceRuns) | |
| 122 | +include(CheckSymbolExists) | |
| 123 | + | |
| 124 | +set(dep_include_directories) | |
| 125 | +set(dep_link_directories) | |
| 126 | +set(dep_link_libraries) | |
| 127 | +set(ANYTHING_MISSING 0) | |
| 128 | + | |
| 129 | +if(WIN32 AND (EXISTS ${qpdf_SOURCE_DIR}/external-libs)) | |
| 130 | + set(EXTERNAL_LIBS 1) | |
| 131 | +else() | |
| 132 | + set(EXTERNAL_LIBS 0) | |
| 133 | +endif() | |
| 134 | + | |
| 135 | +if(EXTERNAL_LIBS) | |
| 136 | + set(EXTLIBDIR ${qpdf_SOURCE_DIR}/external-libs) | |
| 137 | + list(APPEND dep_include_directories ${EXTLIBDIR}/include) | |
| 138 | + set(JPEG_INCLUDE ${EXTLIBDIR}/include) | |
| 139 | + list(APPEND dep_link_libraries | |
| 140 | + z jpeg ssl crypto msvcrt ws2_32 shell32 advapi32 gdi32 user32 crypt32) | |
| 141 | + if (MSVC) | |
| 142 | + list(APPEND dep_link_directories ${EXTLIBDIR}/lib-msvc${WORDSIZE}) | |
| 143 | + else() | |
| 144 | + list(APPEND dep_link_directories ${EXTLIBDIR}/lib-mingw${WORDSIZE}) | |
| 145 | + endif() | |
| 146 | +endif() | |
| 147 | + | |
| 148 | +if(NOT EXTERNAL_LIBS) | |
| 149 | + pkg_check_modules(pc_zlib zlib) | |
| 150 | + if(pc_zlib_FOUND) | |
| 151 | + list(APPEND dep_include_directories ${pc_zlib_INCLUDEDIR}) | |
| 152 | + list(APPEND dep_link_directories ${pc_zlib_LIBDIR}) | |
| 153 | + list(APPEND dep_link_libraries ${pc_zlib_LIBRARIES}) | |
| 154 | + else() | |
| 155 | + find_path(ZLIB_H_PATH zlib.h) | |
| 156 | + find_library(ZLIB_LIB_PATH z zlib) | |
| 157 | + if(ZLIB_H_PATH AND ZLIB_LIB_PATH) | |
| 158 | + list(APPEND dep_include_directories ${ZLIB_H_PATH}) | |
| 159 | + list(APPEND dep_link_libraries ${ZLIB_LIB_PATH}) | |
| 160 | + else() | |
| 161 | + message(SEND_ERROR "zlib not found") | |
| 162 | + set(ANYTHING_MISSING 1) | |
| 163 | + endif() | |
| 164 | + endif() | |
| 165 | +endif() | |
| 166 | + | |
| 167 | +if(NOT EXTERNAL_LIBS) | |
| 168 | + pkg_check_modules(pc_libjpeg libjpeg) | |
| 169 | + if(pc_libjpeg_FOUND) | |
| 170 | + list(APPEND dep_include_directories ${pc_libjpeg_INCLUDEDIR}) | |
| 171 | + list(APPEND dep_link_directories ${pc_libjpeg_LIBDIR}) | |
| 172 | + list(APPEND dep_link_libraries ${pc_libjpeg_LIBRARIES}) | |
| 173 | + set(JPEG_INCLUDE ${pc_libjpeg_INCLUDEDIR}) | |
| 174 | + else() | |
| 175 | + find_path(LIBJPEG_H_PATH jpeglib.h) | |
| 176 | + find_library(LIBJPEG_LIB_PATH jpeg) | |
| 177 | + if(LIBJPEG_H_PATH AND LIBJPEG_LIB_PATH) | |
| 178 | + list(APPEND dep_include_directories ${LIBJPEG_H_PATH}) | |
| 179 | + list(APPEND dep_link_libraries ${LIBJPEG_LIB_PATH}) | |
| 180 | + set(JPEG_INCLUDE ${LIBJPEG_H_PATH}) | |
| 181 | + else() | |
| 182 | + message(SEND_ERROR "libjpeg not found") | |
| 183 | + set(ANYTHING_MISSING 1) | |
| 184 | + endif() | |
| 185 | + endif() | |
| 186 | +endif() | |
| 187 | + | |
| 188 | +# Update JPEG_INCLUDE in PARENT_SCOPE after we have finished setting it. | |
| 189 | +set(JPEG_INCLUDE ${JPEG_INCLUDE} PARENT_SCOPE) | |
| 190 | + | |
| 191 | +# Crypto provider selection. Prefer external crypto providers. If | |
| 192 | +# implicit selection is allowed, use native only when no other options | |
| 193 | +# are available or when explicitly requested. Allowing native as a | |
| 194 | +# fallback can be disabled using the ALLOW_CRYPTO_NATIVE option. | |
| 195 | +list(APPEND CRYPTO_PKG) | |
| 196 | + | |
| 197 | +set(USE_CRYPTO_GNUTLS OFF) | |
| 198 | +set(USE_CRYPTO_OPENSSL OFF) | |
| 199 | +set(USE_CRYPTO_NATIVE OFF) | |
| 200 | +set(FOUND_CRYPTO OFF) | |
| 201 | + | |
| 202 | +if(USE_IMPLICIT_CRYPTO OR REQUIRE_CRYPTO_OPENSSL) | |
| 203 | + if(EXTERNAL_LIBS) | |
| 204 | + set(USE_CRYPTO_OPENSSL ON) | |
| 205 | + else() | |
| 206 | + pkg_check_modules(pc_openssl openssl>=1.1.0) | |
| 207 | + if(pc_openssl_FOUND) | |
| 208 | + set(USE_CRYPTO_OPENSSL ON) | |
| 209 | + set(FOUND_CRYPTO ON) | |
| 210 | + set(CRYPTO_PKG "${CRYPTO_PKG}, openssl>=1.1.0") | |
| 211 | + else() | |
| 212 | + find_path(OPENSSL_H_PATH openssl/evp.h) | |
| 213 | + find_library(OPENSSL_LIB_PATH crypto) | |
| 214 | + if(OPENSSL_H_PATH AND OPENSSL_LIB_PATH) | |
| 215 | + list(APPEND dep_include_directories ${OPENSSL_H_PATH}) | |
| 216 | + list(APPEND dep_link_libraries ${OPENSSL_LIB_PATH}) | |
| 217 | + set(USE_CRYPTO_OPENSSL ON) | |
| 218 | + set(FOUND_CRYPTO ON) | |
| 219 | + elseif(REQUIRE_CRYPTO_OPENSSL) | |
| 220 | + message(SEND_ERROR "openssl not found") | |
| 221 | + set(ANYTHING_MISSING 1) | |
| 222 | + endif() | |
| 223 | + endif() | |
| 224 | + endif() | |
| 225 | +endif() | |
| 226 | +if(USE_IMPLICIT_CRYPTO OR REQUIRE_CRYPTO_GNUTLS) | |
| 227 | + pkg_check_modules(pc_gnutls gnutls) | |
| 228 | + if(pc_gnutls_FOUND) | |
| 229 | + set(USE_CRYPTO_GNUTLS ON) | |
| 230 | + set(FOUND_CRYPTO ON) | |
| 231 | + set(CRYPTO_PKG "${CRYPTO_PKG}, gnutls") | |
| 232 | + else() | |
| 233 | + find_path(GNUTLS_H_PATH gnutls/gnutls.h) | |
| 234 | + find_library(GNUTLS_LIB_PATH gnutls) | |
| 235 | + if(GNUTLS_H_PATH AND GNUTLS_LIB_PATH) | |
| 236 | + list(APPEND dep_include_directories ${GNUTLS_H_PATH}) | |
| 237 | + list(APPEND dep_link_libraries ${GNUTLS_LIB_PATH}) | |
| 238 | + set(USE_CRYPTO_GNUTLS ON) | |
| 239 | + set(FOUND_CRYPTO ON) | |
| 240 | + elseif(REQUIRE_CRYPTO_GNUTLS) | |
| 241 | + message(SEND_ERROR "gnutls not found") | |
| 242 | + set(ANYTHING_MISSING 1) | |
| 243 | + endif() | |
| 244 | + endif() | |
| 245 | +endif() | |
| 246 | +if(REQUIRE_CRYPTO_NATIVE) | |
| 247 | + set(USE_CRYPTO_NATIVE ON) | |
| 248 | + set(FOUND_CRYPTO ON) | |
| 249 | +elseif(USE_IMPLICIT_CRYPTO) | |
| 250 | + if(ALLOW_CRYPTO_NATIVE AND (NOT FOUND_CRYPTO)) | |
| 251 | + set(USE_CRYPTO_NATIVE ON) | |
| 252 | + set(FOUND_CRYPTO ON) | |
| 253 | + endif() | |
| 254 | +endif() | |
| 255 | +if(FOUND_CRYPTO) | |
| 256 | + if(NOT DEFAULT_CRYPTO) | |
| 257 | + # The preferred order of crypto providers is documented in | |
| 258 | + # manual/installation.rst in the crypto.build section. | |
| 259 | + if(USE_CRYPTO_GNUTLS) | |
| 260 | + set(DEFAULT_CRYPTO "gnutls") | |
| 261 | + elseif(USE_CRYPTO_OPENSSL) | |
| 262 | + set(DEFAULT_CRYPTO "openssl") | |
| 263 | + else() | |
| 264 | + set(DEFAULT_CRYPTO "native") | |
| 265 | + endif() | |
| 266 | + endif() | |
| 267 | +else() | |
| 268 | + message(SEND_ERROR "no crypto provider is available") | |
| 269 | + set(ANYTHING_MISSING 1) | |
| 270 | +endif() | |
| 271 | +if(ANYTHING_MISSING) | |
| 272 | + message(FATAL_ERROR "Missing dependencies; unable to continue") | |
| 273 | +endif() | |
| 274 | + | |
| 275 | +message(STATUS "") | |
| 276 | +message(STATUS "*** Crypto Summary ***") | |
| 277 | +message(STATUS " GNU TLS crypto enabled: " ${USE_CRYPTO_GNUTLS}) | |
| 278 | +message(STATUS " OpenSSL crypto enabled: " ${USE_CRYPTO_OPENSSL}) | |
| 279 | +message(STATUS " Native crypto enabled: " ${USE_CRYPTO_NATIVE}) | |
| 280 | +message(STATUS " Default crypto: " ${DEFAULT_CRYPTO}) | |
| 281 | +message(STATUS "") | |
| 282 | + | |
| 283 | +if(USE_CRYPTO_OPENSSL) | |
| 284 | + list(APPEND libqpdf_SOURCES ${libqpdf_crypto_openssl}) | |
| 285 | + if(NOT EXTERNAL_LIBS) | |
| 286 | + list(APPEND dep_include_directories ${pc_openssl_INCLUDEDIR}) | |
| 287 | + list(APPEND dep_link_directories ${pc_openssl_LIBDIR}) | |
| 288 | + list(APPEND dep_link_libraries ${pc_openssl_LIBRARIES}) | |
| 289 | + endif() | |
| 290 | +endif() | |
| 291 | +if(USE_CRYPTO_GNUTLS) | |
| 292 | + list(APPEND libqpdf_SOURCES ${libqpdf_crypto_gnutls}) | |
| 293 | + list(APPEND dep_include_directories ${pc_gnutls_INCLUDEDIR}) | |
| 294 | + list(APPEND dep_link_directories ${pc_gnutls_LIBDIR}) | |
| 295 | + list(APPEND dep_link_libraries ${pc_gnutls_LIBRARIES}) | |
| 296 | +endif() | |
| 297 | +if(USE_CRYPTO_NATIVE) | |
| 298 | + list(APPEND libqpdf_SOURCES ${libqpdf_crypto_native}) | |
| 299 | +endif() | |
| 300 | + | |
| 301 | +if(APPLE) | |
| 302 | + # 2022: in CI (GitHub actions), pkg-config for zlib was adding a | |
| 303 | + # broken directory to the include path. This effectively filters it | |
| 304 | + # out. | |
| 305 | + list(FILTER dep_include_directories EXCLUDE REGEX "^/Library/") | |
| 306 | +endif() | |
| 307 | + | |
| 308 | +list(REMOVE_DUPLICATES dep_include_directories) | |
| 309 | +list(REMOVE_DUPLICATES dep_link_directories) | |
| 310 | +list(REMOVE_DUPLICATES dep_link_libraries) | |
| 311 | + | |
| 312 | +check_type_size(size_t SIZEOF_SIZE_T) | |
| 313 | +check_include_file("inttypes.h" HAVE_INTTYPES_H) | |
| 314 | +check_symbol_exists(fseeko "stdio.h" HAVE_FSEEKO) | |
| 315 | +check_symbol_exists(fseeko64 "stdio.h" HAVE_FSEEKO64) | |
| 316 | +check_symbol_exists(localtime_r "time.h" HAVE_LOCALTIME_R) | |
| 317 | +check_symbol_exists(random "stdlib.h" HAVE_RANDOM) | |
| 318 | +find_file(RANDOM_DEVICE | |
| 319 | + "urandom" "arandom" "arandom" PATHS "/dev" NO_DEFAULT_PATH) | |
| 320 | + | |
| 321 | +check_c_source_compiles( | |
| 322 | +"#include <time.h> | |
| 323 | +#include <stdio.h> | |
| 324 | +int main(int argc, char* argv[]) { | |
| 325 | + tzset(); | |
| 326 | + printf(\"%ld\", timezone); | |
| 327 | + return 0; | |
| 328 | +}" | |
| 329 | + HAVE_EXTERN_LONG_TIMEZONE) | |
| 330 | + | |
| 331 | +check_c_source_compiles( | |
| 332 | +"#include <time.h> | |
| 333 | +int main(int argc, char* argv[]) { | |
| 334 | + struct tm tm; | |
| 335 | + tm.tm_gmtoff = 1; | |
| 336 | + return 0; | |
| 337 | +}" | |
| 338 | + HAVE_EXTERN_TM_GMTOFF) | |
| 339 | + | |
| 340 | +check_c_source_compiles( | |
| 341 | +"#include <stdio.h> | |
| 342 | +#include <sys/types.h> | |
| 343 | +int main(int argc, char* argv[]) { | |
| 344 | + int a[sizeof(off_t) >= 8 ? 1 : -1]; | |
| 345 | +}" | |
| 346 | + LFS_WITHOUT_MACROS) | |
| 347 | + | |
| 348 | +check_c_source_compiles( | |
| 349 | +"#define _FILE_OFFSET_BITS 64 | |
| 350 | +#include <stdio.h> | |
| 351 | +#include <sys/types.h> | |
| 352 | +int main(int argc, char* argv[]) { | |
| 353 | + int a[sizeof(off_t) >= 8 ? 1 : -1]; | |
| 354 | +}" | |
| 355 | + LFS_WITH_MACROS) | |
| 356 | +if(LFS_WITH_MACROS AND NOT LFS_WITHOUT_MACROS) | |
| 357 | + set(_FILE_OFFSET_BITS 64) | |
| 358 | +endif() | |
| 359 | + | |
| 360 | +function(qpdf_check_ll_fmt fmt var) | |
| 361 | + if(NOT DEFINED LL_FMT) | |
| 362 | + check_c_source_runs( | |
| 363 | + "#define _CRT_SECURE_NO_WARNINGS | |
| 364 | +#include <stdio.h> | |
| 365 | +#include <string.h> | |
| 366 | +int main(int argc, char* argv[]) { | |
| 367 | + long long int a = 123456789012345ll; | |
| 368 | + char s[30]; | |
| 369 | + sprintf(s, \"${fmt}\", a); | |
| 370 | + return (strcmp(s, \"123456789012345\") == 0) ? 0 : 1; | |
| 371 | +}" ${var}) | |
| 372 | + if(${var}) | |
| 373 | + set(LL_FMT "${fmt}" PARENT_SCOPE) | |
| 374 | + endif() | |
| 375 | + endif() | |
| 376 | +endfunction() | |
| 377 | + | |
| 378 | +qpdf_check_ll_fmt("%lld" fmt_lld) | |
| 379 | +qpdf_check_ll_fmt("%I64d" fmt_i64d) | |
| 380 | +qpdf_check_ll_fmt("%I64lld" fmt_i64lld) | |
| 381 | + | |
| 382 | +configure_file( | |
| 383 | + "${CMAKE_CURRENT_SOURCE_DIR}/qpdf/qpdf-config.h.in" | |
| 384 | + "${CMAKE_CURRENT_BINARY_DIR}/qpdf/qpdf-config.h" | |
| 385 | + NEWLINE_STYLE UNIX) | |
| 386 | + | |
| 387 | +if(NOT BUILD_STATIC_LIBS) | |
| 388 | + set(OBJECT_LIB_IS_PIC ON) | |
| 389 | +else() | |
| 390 | + set(OBJECT_LIB_IS_PIC OFF) | |
| 391 | +endif() | |
| 392 | + | |
| 393 | +# Build an "object library" for use in libtests so we don't have to | |
| 394 | +# export symbols that are not officially part of the public API. If we | |
| 395 | +# are building static libraries, the object library won't use | |
| 396 | +# position-independent code and will provided objects for the static | |
| 397 | +# library. If we are only building the shared library, go ahead and | |
| 398 | +# use PIC for the object library so we don't have to compile twice. | |
| 399 | +set(OBJECT_LIB libqpdf_object) | |
| 400 | +add_library(${OBJECT_LIB} OBJECT ${libqpdf_SOURCES}) | |
| 401 | +set_target_properties(${OBJECT_LIB} PROPERTIES | |
| 402 | + POSITION_INDEPENDENT_CODE ${OBJECT_LIB_IS_PIC}) | |
| 403 | +target_include_directories(${OBJECT_LIB} | |
| 404 | + SYSTEM PRIVATE ${dep_include_directories}) | |
| 405 | +target_include_directories(${OBJECT_LIB} | |
| 406 | + PUBLIC | |
| 407 | + ${JPEG_INCLUDE} | |
| 408 | + ${qpdf_INCLUDE} | |
| 409 | + ${qpdf_SOURCE_DIR}/libqpdf | |
| 410 | + ${CMAKE_CURRENT_BINARY_DIR}) | |
| 411 | +target_link_directories(${OBJECT_LIB} INTERFACE ${dep_link_directories}) | |
| 412 | +target_link_libraries(${OBJECT_LIB} INTERFACE ${dep_link_libraries}) | |
| 413 | + | |
| 414 | +set(LD_VERSION_FLAGS "") | |
| 415 | +function(ld_version_script) | |
| 416 | + # Check if the linker supports linker scripts, and use if it does. | |
| 417 | + # This functionality is currently constrained to compilers using GNU | |
| 418 | + # ld on ELF systems or systems that emulation this behavior. | |
| 419 | + set(ld_script | |
| 420 | + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/qpdf-tmp/conftest.map") | |
| 421 | + file(WRITE ${ld_script} | |
| 422 | +"VERS_1 { | |
| 423 | + global: sym; | |
| 424 | +}; | |
| 425 | + | |
| 426 | +VERS_2 { | |
| 427 | + global: sym; | |
| 428 | +} VERS_1; | |
| 429 | +") | |
| 430 | + set(CMAKE_REQUIRED_LINK_OPTIONS -Wl,--version-script=${ld_script}) | |
| 431 | + check_c_source_compiles("int main() { return 0; }" HAVE_LD_SCRIPT) | |
| 432 | + if(HAVE_LD_SCRIPT) | |
| 433 | + set(LD_VERSION_FLAGS | |
| 434 | + -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libqpdf.map PARENT_SCOPE) | |
| 435 | + configure_file( | |
| 436 | + "${qpdf_SOURCE_DIR}/libqpdf.map.in" | |
| 437 | + "${CMAKE_CURRENT_BINARY_DIR}/libqpdf.map" | |
| 438 | + NEWLINE_STYLE UNIX) | |
| 439 | + endif() | |
| 440 | +endfunction() | |
| 441 | +if(NOT WIN32) | |
| 442 | + ld_version_script() | |
| 443 | +endif() | |
| 444 | + | |
| 445 | +if(BUILD_SHARED_LIBS) | |
| 446 | + add_compile_definitions(DLL_EXPORT) | |
| 447 | + | |
| 448 | + set(SHARED_LIB libqpdf) | |
| 449 | + if(OBJECT_LIB_IS_PIC) | |
| 450 | + add_library(${SHARED_LIB} SHARED $<TARGET_OBJECTS:libqpdf_object>) | |
| 451 | + else() | |
| 452 | + add_library(${SHARED_LIB} SHARED ${libqpdf_SOURCES}) | |
| 453 | + endif() | |
| 454 | + if(WIN32) | |
| 455 | + # Goal: the DLL import library should be libqpdf.a or qpdf.lib so | |
| 456 | + # that linking with -lqpdf gets you a shared library link on all | |
| 457 | + # platforms. The DLL should be qpdf${SONAME}.dll rather than just | |
| 458 | + # qpdf.dll. qpdf has always done this, and it gives us some | |
| 459 | + # protection against binary incompatible DLLs being installed. | |
| 460 | + set(SHARED_OUT qpdf${qpdf_SOVERSION}) # Put API version number in DLL | |
| 461 | + if(MINGW) | |
| 462 | + # Reference: Platform/Windows-GNU.cmake in the cmake installation | |
| 463 | + set(CMAKE_SHARED_LIBRARY_PREFIX "") # libqpdf$v.dll -> qpdf$v.dll | |
| 464 | + set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a") # libqpdf.dll.a -> libqpdf.a | |
| 465 | + endif() | |
| 466 | + if(MSVC) | |
| 467 | + # Avoid linker warning from mixing libraries built with /MT and /MD. | |
| 468 | + set_target_properties(${SHARED_LIB} | |
| 469 | + PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD") | |
| 470 | + endif() | |
| 471 | + else() | |
| 472 | + set(SHARED_OUT qpdf) | |
| 473 | + endif() | |
| 474 | + # Setting OUTPUT_NAME and ARCHIVE_OUTPUT_NAME separate enables us to | |
| 475 | + # have a versioned DLL and an unversioned import library, which | |
| 476 | + # gives us semantics similar to ELF shared libraries and makes | |
| 477 | + # linking against qpdf the same across all platforms. | |
| 478 | + set_target_properties(${SHARED_LIB} PROPERTIES | |
| 479 | + OUTPUT_NAME ${SHARED_OUT} | |
| 480 | + ARCHIVE_OUTPUT_NAME qpdf | |
| 481 | + VERSION ${qpdf_LIBVERSION} | |
| 482 | + SOVERSION ${qpdf_SOVERSION} | |
| 483 | + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}) | |
| 484 | + | |
| 485 | + target_include_directories(${SHARED_LIB} | |
| 486 | + SYSTEM PRIVATE ${dep_include_directories}) | |
| 487 | + target_include_directories(${SHARED_LIB} | |
| 488 | + PUBLIC | |
| 489 | + $<BUILD_INTERFACE:${qpdf_INCLUDE}> | |
| 490 | + $<INSTALL_INTERFACE:include>) | |
| 491 | + target_link_directories(${SHARED_LIB} PRIVATE ${dep_link_directories}) | |
| 492 | + target_link_libraries(${SHARED_LIB} PRIVATE ${dep_link_libraries}) | |
| 493 | + if(LD_VERSION_FLAGS) | |
| 494 | + target_link_options(${SHARED_LIB} PRIVATE ${LD_VERSION_FLAGS}) | |
| 495 | + endif() | |
| 496 | + | |
| 497 | + target_include_directories(${SHARED_LIB} | |
| 498 | + PRIVATE ${qpdf_SOURCE_DIR}/libqpdf ${CMAKE_CURRENT_BINARY_DIR}) | |
| 499 | + | |
| 500 | + install(TARGETS ${SHARED_LIB} | |
| 501 | + EXPORT libqpdfTargets | |
| 502 | + TYPE LIBRARY | |
| 503 | + COMPONENT ${COMPONENT_LIB} | |
| 504 | + NAMELINK_COMPONENT ${COMPONENT_DEV} | |
| 505 | + INCLUDES ${qpdf_INCLUDE}) | |
| 506 | +endif() | |
| 507 | + | |
| 508 | +if(BUILD_STATIC_LIBS) | |
| 509 | + if(BUILD_SHARED_LIBS) | |
| 510 | + set(STATIC_LIB libqpdf_static) | |
| 511 | + else() | |
| 512 | + set(STATIC_LIB libqpdf) | |
| 513 | + endif() | |
| 514 | + if(OBJECT_LIB_IS_PIC) | |
| 515 | + add_library(${STATIC_LIB} STATIC ${libqpdf_SOURCES}) | |
| 516 | + else() | |
| 517 | + add_library(${STATIC_LIB} STATIC $<TARGET_OBJECTS:libqpdf_object>) | |
| 518 | + endif() | |
| 519 | + | |
| 520 | + target_include_directories(${STATIC_LIB} | |
| 521 | + SYSTEM PRIVATE ${dep_include_directories}) | |
| 522 | + target_include_directories(${STATIC_LIB} | |
| 523 | + PUBLIC | |
| 524 | + $<BUILD_INTERFACE:${qpdf_INCLUDE}> | |
| 525 | + $<INSTALL_INTERFACE:include>) | |
| 526 | + target_link_directories(${STATIC_LIB} | |
| 527 | + INTERFACE $<BUILD_INTERFACE:${dep_link_directories}> | |
| 528 | + PRIVATE $<INSTALL_INTERFACE:${dep_link_directories}>) | |
| 529 | + target_link_libraries(${STATIC_LIB} INTERFACE ${dep_link_libraries}) | |
| 530 | + | |
| 531 | + # Avoid name clashes on Windows with the the DLL import library. | |
| 532 | + if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) | |
| 533 | + if (WIN32) | |
| 534 | + set(STATIC_SUFFIX "_static") | |
| 535 | + else() | |
| 536 | + set(STATIC_SUFFIX "") | |
| 537 | + endif() | |
| 538 | + endif() | |
| 539 | + | |
| 540 | + set_target_properties(${STATIC_LIB} PROPERTIES | |
| 541 | + OUTPUT_NAME qpdf${STATIC_SUFFIX} | |
| 542 | + VERSION ${PROJECT_VERSION}) | |
| 543 | + target_include_directories(${STATIC_LIB} | |
| 544 | + PRIVATE ${qpdf_SOURCE_DIR}/libqpdf ${CMAKE_CURRENT_BINARY_DIR}) | |
| 545 | + | |
| 546 | + install(TARGETS ${STATIC_LIB} | |
| 547 | + EXPORT libqpdfTargets | |
| 548 | + TYPE ARCHIVE | |
| 549 | + COMPONENT ${COMPONENT_DEV} | |
| 550 | + INCLUDES ${qpdf_INCLUDE}) | |
| 551 | +endif() | |
| 552 | + | |
| 553 | +configure_file( | |
| 554 | + "${qpdf_SOURCE_DIR}/libqpdf.pc.in" | |
| 555 | + "${CMAKE_CURRENT_BINARY_DIR}/libqpdf.pc" | |
| 556 | + @ONLY NEWLINE_STYLE UNIX) | |
| 557 | +if(INSTALL_PKGCONFIG) | |
| 558 | + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libqpdf.pc | |
| 559 | + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig | |
| 560 | + COMPONENT ${COMPONENT_DEV}) | |
| 561 | +endif() | |
| 562 | + | |
| 563 | +if(INSTALL_CMAKE_PACKAGE) | |
| 564 | + include(CMakePackageConfigHelpers) | |
| 565 | + configure_package_config_file( | |
| 566 | + ${qpdf_SOURCE_DIR}/qpdfConfig.cmake.in | |
| 567 | + ${CMAKE_CURRENT_BINARY_DIR}/qpdfConfig.cmake | |
| 568 | + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpdf) | |
| 569 | + write_basic_package_version_file( | |
| 570 | + "${CMAKE_CURRENT_BINARY_DIR}/qpdfConfigVersion.cmake" | |
| 571 | + VERSION ${PROJECT_VERSION} | |
| 572 | + COMPATIBILITY SameMajorVersion) | |
| 573 | + install(EXPORT libqpdfTargets | |
| 574 | + NAMESPACE qpdf:: | |
| 575 | + FILE libqpdfTargets.cmake | |
| 576 | + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpdf) | |
| 577 | + install(FILES | |
| 578 | + ${CMAKE_CURRENT_BINARY_DIR}/qpdfConfigVersion.cmake | |
| 579 | + ${CMAKE_CURRENT_BINARY_DIR}/qpdfConfig.cmake | |
| 580 | + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpdf) | |
| 581 | +endif() | ... | ... |
libtests/CMakeLists.txt
0 → 100644
| 1 | +set(TEST_PROGRAMS | |
| 2 | + cxx11 | |
| 3 | + aes | |
| 4 | + arg_parser | |
| 5 | + ascii85 | |
| 6 | + bits | |
| 7 | + buffer | |
| 8 | + closed_file_input_source | |
| 9 | + concatenate | |
| 10 | + dct_compress | |
| 11 | + dct_uncompress | |
| 12 | + flate | |
| 13 | + hex | |
| 14 | + input_source | |
| 15 | + json | |
| 16 | + json_handler | |
| 17 | + json_parse | |
| 18 | + lzw | |
| 19 | + main_from_wmain | |
| 20 | + matrix | |
| 21 | + md5 | |
| 22 | + nntree | |
| 23 | + numrange | |
| 24 | + pdf_version | |
| 25 | + pointer_holder | |
| 26 | + predictors | |
| 27 | + qintc | |
| 28 | + qutil | |
| 29 | + random | |
| 30 | + rc4 | |
| 31 | + runlength | |
| 32 | + sha2 | |
| 33 | + sparse_array) | |
| 34 | +foreach(PROG ${TEST_PROGRAMS}) | |
| 35 | + add_executable(${PROG} ${PROG}.cc) | |
| 36 | + target_link_libraries(${PROG} libqpdf_object) | |
| 37 | +endforeach() | |
| 38 | + | |
| 39 | +# Since libtests link with the object library and don't use the DLL, | |
| 40 | +# we don't need to (and shouldn't) add the libqpdf target directory to | |
| 41 | +# the path for libtests. | |
| 42 | +add_test( | |
| 43 | + NAME libtests | |
| 44 | + COMMAND ${RUN_QTEST} | |
| 45 | + --top ${qpdf_SOURCE_DIR} | |
| 46 | + --bin $<TARGET_FILE_DIR:qutil> | |
| 47 | + --bin $<TARGET_FILE_DIR:qpdf> | |
| 48 | + --code ${qpdf_SOURCE_DIR}/libtests | |
| 49 | + --color ${QTEST_COLOR} | |
| 50 | + --show-on-failure ${SHOW_FAILED_TEST_OUTPUT} | |
| 51 | + --tc "${qpdf_SOURCE_DIR}/libtests/*.cc" | |
| 52 | + --tc "${qpdf_SOURCE_DIR}/libqpdf/*.cc" | |
| 53 | + --tc "${qpdf_SOURCE_DIR}/libqpdf/qpdf/bits_functions.hh") | ... | ... |
manual/CMakeLists.txt
0 → 100644
| 1 | +# There is a FindLATEX module, but it does some things we don't care | |
| 2 | +# about and doesn't do everything we need. | |
| 3 | +find_program(LATEX latex) | |
| 4 | +find_program(PDFLATEX pdflatex) | |
| 5 | +find_program(LATEXMK latexmk) | |
| 6 | +find_program(SPHINX sphinx-build) | |
| 7 | + | |
| 8 | +# *** NOTE: Never check BUILD_DOC_PDF if BUILD_DOC is not set. See | |
| 9 | +# *** comments in top-level CMakeLists.txt. | |
| 10 | + | |
| 11 | +if(BUILD_DOC) | |
| 12 | + if(SPHINX STREQUAL SPHINX-NOTFOUND) | |
| 13 | + message(FATAL_ERROR "sphinx-build is required for building documentation") | |
| 14 | + endif() | |
| 15 | + if(BUILD_DOC_PDF AND | |
| 16 | + ((LATEX STREQUAL LATEX-NOTFOUND) OR | |
| 17 | + (LATEXMK STREQUAL LATEXMK-NOTFOUND) OR | |
| 18 | + (PDFLATEX STREQUAL PDFLATEX-NOTFOUND))) | |
| 19 | + message(FATAL_ERROR | |
| 20 | + "latex, latexmk, and pdflatex are required to build PDF documentation") | |
| 21 | + endif() | |
| 22 | +endif() | |
| 23 | + | |
| 24 | +set(MANUAL_SRC ${qpdf_SOURCE_DIR}/manual) | |
| 25 | +foreach(F qpdf.1 fix-qdf.1 zlib-flate.1) | |
| 26 | + configure_file( | |
| 27 | + ${MANUAL_SRC}/${F}.in | |
| 28 | + ${CMAKE_CURRENT_BINARY_DIR}/${F} | |
| 29 | + NEWLINE_STYLE UNIX) | |
| 30 | +endforeach() | |
| 31 | + | |
| 32 | +SET(MANUAL_DEPS | |
| 33 | + conf.py | |
| 34 | + _ext/qpdf.py | |
| 35 | + acknowledgement.rst | |
| 36 | + cli.rst | |
| 37 | + design.rst | |
| 38 | + download.rst | |
| 39 | + encryption.rst | |
| 40 | + index.rst | |
| 41 | + installation.rst | |
| 42 | + json.rst | |
| 43 | + library.rst | |
| 44 | + license.rst | |
| 45 | + linearization.rst | |
| 46 | + object-streams.rst | |
| 47 | + overview.rst | |
| 48 | + packaging.rst | |
| 49 | + qdf.rst | |
| 50 | + qpdf-job.rst | |
| 51 | + release-notes.rst | |
| 52 | + weak-crypto.rst) | |
| 53 | + | |
| 54 | +# Prevent targets that run ${SPHINX} from running in parallel by using | |
| 55 | +# dependencies. This avoids clashes in temporary files that cause the | |
| 56 | +# build to fail with the error "_pickle.UnpicklingError: pickle data | |
| 57 | +# was truncated". It would be better if we could use order-only | |
| 58 | +# dependencies like gnu make to make it possible to build the targets | |
| 59 | +# independently. | |
| 60 | +set(DOC_HTML_OUTPUT html/index.html) | |
| 61 | +set(DOC_SINGLEHTML_OUTPUT singlehtml/index.html) | |
| 62 | +set(DOC_PDF_OUTPUT latex/qpdf.pdf) | |
| 63 | +if(BUILD_DOC) | |
| 64 | + add_custom_command(OUTPUT ${DOC_HTML_OUTPUT} | |
| 65 | + COMMAND ${SPHINX} -M html ${MANUAL_SRC} ${CMAKE_CURRENT_BINARY_DIR} | |
| 66 | + COMMAND touch ${DOC_HTML_OUTPUT} | |
| 67 | + DEPENDS ${MANUAL_DEPS}) | |
| 68 | + add_custom_command(OUTPUT ${DOC_SINGLEHTML_OUTPUT} | |
| 69 | + COMMAND ${SPHINX} -M singlehtml ${MANUAL_SRC} ${CMAKE_CURRENT_BINARY_DIR} | |
| 70 | + COMMAND touch ${DOC_SINGLEHTML_OUTPUT} | |
| 71 | + DEPENDS ${MANUAL_DEPS}) | |
| 72 | + add_custom_command(OUTPUT ${DOC_PDF_OUTPUT} | |
| 73 | + COMMAND ${SPHINX} -M latexpdf ${MANUAL_SRC} ${CMAKE_CURRENT_BINARY_DIR} | |
| 74 | + COMMAND touch ${DOC_PDF_OUTPUT} | |
| 75 | + DEPENDS ${MANUAL_DEPS}) | |
| 76 | + add_custom_target(doc_html DEPENDS ${DOC_HTML_OUTPUT}) | |
| 77 | + add_custom_target(doc_singlehtml DEPENDS ${DOC_SINGLEHTML_OUTPUT}) | |
| 78 | + add_dependencies(doc_singlehtml doc_html) | |
| 79 | + add_custom_target(doc_pdf DEPENDS ${DOC_PDF_OUTPUT}) | |
| 80 | + add_custom_target(doc ALL) | |
| 81 | + if(BUILD_DOC_PDF) | |
| 82 | + add_dependencies(doc doc_pdf) | |
| 83 | + if(BUILD_DOC_HTML) | |
| 84 | + add_dependencies(doc_pdf doc_singlehtml) | |
| 85 | + endif() | |
| 86 | + elseif(BUILD_DOC_HTML) | |
| 87 | + add_dependencies(doc doc_singlehtml) | |
| 88 | + endif() | |
| 89 | + | |
| 90 | + if(BUILD_DOC_DIST) | |
| 91 | + set(DOC_DIST_HTML doc-dist/manual-html) | |
| 92 | + set(DOC_DIST_SINGLEHTML doc-dist/manual-single-page-html) | |
| 93 | + set(DOC_DIST_PDF doc-dist/qpdf-manual.pdf) | |
| 94 | + add_custom_command( | |
| 95 | + OUTPUT | |
| 96 | + ${DOC_DIST_HTML} | |
| 97 | + ${DOC_DIST_SINGLEHTML} | |
| 98 | + ${DOC_DIST_PDF} | |
| 99 | + COMMAND rm -rf doc-dist | |
| 100 | + COMMAND mkdir -p doc-dist | |
| 101 | + COMMAND cp -r html ${DOC_DIST_HTML} | |
| 102 | + COMMAND cp -r singlehtml ${DOC_DIST_SINGLEHTML} | |
| 103 | + COMMAND cp -r ${DOC_PDF_OUTPUT} ${DOC_DIST_PDF} | |
| 104 | + DEPENDS ${DOC_HTML_OUTPUT} ${DOC_SINGLEHTML_OUTPUT} ${DOC_PDF_OUTPUT}) | |
| 105 | + add_custom_target(doc_dist ALL | |
| 106 | + DEPENDS ${DOC_DIST_HTML} ${DOC_DIST_SINGLEHTML} ${DOC_DIST_PDF}) | |
| 107 | + add_dependencies(doc_dist doc) | |
| 108 | + endif() | |
| 109 | +endif() | |
| 110 | + | |
| 111 | +# INSTALL_MANUAL is not dependent on building doc -- we sometimes drop in | |
| 112 | +# pre-built doc when creating distributions. | |
| 113 | +if(INSTALL_MANUAL) | |
| 114 | + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-dist/ | |
| 115 | + TYPE DOC | |
| 116 | + COMPONENT ${COMPONENT_DOC}) | |
| 117 | +else() | |
| 118 | + install(FILES ${qpdf_SOURCE_DIR}/README-doc.txt | |
| 119 | + TYPE DOC | |
| 120 | + COMPONENT ${COMPONENT_DOC}) | |
| 121 | +endif() | |
| 122 | + | |
| 123 | +if(NOT WIN32) | |
| 124 | + # There's no reason to install manual pages in a Windows | |
| 125 | + # environment, especially when all they do is refer people to the | |
| 126 | + # manual. | |
| 127 | + install(FILES | |
| 128 | + ${CMAKE_CURRENT_BINARY_DIR}/qpdf.1 | |
| 129 | + ${CMAKE_CURRENT_BINARY_DIR}/fix-qdf.1 | |
| 130 | + ${CMAKE_CURRENT_BINARY_DIR}/zlib-flate.1 | |
| 131 | + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 | |
| 132 | + COMPONENT ${COMPONENT_DOC}) | |
| 133 | +endif() | ... | ... |
qpdf/CMakeLists.txt
0 → 100644
| 1 | +set(MAIN_CXX_PROGRAMS | |
| 2 | + qpdf | |
| 3 | + fix-qdf | |
| 4 | + pdf_from_scratch | |
| 5 | + test_driver | |
| 6 | + test_large_file | |
| 7 | + test_parsedoffset | |
| 8 | + test_pdf_doc_encoding | |
| 9 | + test_pdf_unicode | |
| 10 | + test_renumber | |
| 11 | + test_shell_glob | |
| 12 | + test_tokenizer | |
| 13 | + test_unicode_filenames | |
| 14 | + test_xref) | |
| 15 | +set(MAIN_C_PROGRAMS | |
| 16 | + qpdf-ctest | |
| 17 | + qpdfjob-ctest) | |
| 18 | + | |
| 19 | +foreach(PROG ${MAIN_CXX_PROGRAMS}) | |
| 20 | + add_executable(${PROG} ${PROG}.cc) | |
| 21 | + target_link_libraries(${PROG} libqpdf) | |
| 22 | +endforeach() | |
| 23 | +foreach(PROG ${MAIN_C_PROGRAMS}) | |
| 24 | + add_executable(${PROG} ${PROG}.c) | |
| 25 | + target_link_libraries(${PROG} libqpdf) | |
| 26 | + set_property(TARGET ${PROG} PROPERTY LINKER_LANGUAGE CXX) | |
| 27 | +endforeach() | |
| 28 | +target_include_directories(qpdf-ctest PRIVATE ${CMAKE_BINARY_DIR}/libqpdf) | |
| 29 | + | |
| 30 | +foreach(B qpdf test_unicode_filenames fix-qdf test_shell_glob) | |
| 31 | + if(WINDOWS_WMAIN_COMPILE) | |
| 32 | + target_compile_options(${B} PRIVATE ${WINDOWS_WMAIN_COMPILE}) | |
| 33 | + endif() | |
| 34 | + if(WINDOWS_WMAIN_LINK) | |
| 35 | + target_link_options(${B} PRIVATE ${WINDOWS_WMAIN_LINK}) | |
| 36 | + endif() | |
| 37 | +endforeach() | |
| 38 | + | |
| 39 | +add_test( | |
| 40 | + NAME qpdf | |
| 41 | + COMMAND ${RUN_QTEST} | |
| 42 | + --top ${qpdf_SOURCE_DIR} | |
| 43 | + --bin $<TARGET_FILE_DIR:qpdf> | |
| 44 | + --bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL | |
| 45 | + --code ${qpdf_SOURCE_DIR}/qpdf | |
| 46 | + --color ${QTEST_COLOR} | |
| 47 | + --show-on-failure ${SHOW_FAILED_TEST_OUTPUT} | |
| 48 | + --tc "${qpdf_SOURCE_DIR}/qpdf/*.cc" | |
| 49 | + --tc "${qpdf_SOURCE_DIR}/qpdf/*.c" | |
| 50 | + --tc "${qpdf_SOURCE_DIR}/libqpdf/*.cc") | |
| 51 | + | |
| 52 | +install(TARGETS qpdf fix-qdf | |
| 53 | + TYPE RUNTIME | |
| 54 | + COMPONENT ${COMPONENT_CLI}) | |
| 55 | + | |
| 56 | +if(MINGW) | |
| 57 | + # For MSVC, including InstallRequiredSystemLibraries in the | |
| 58 | + # top-level CMakeLists.txt is sufficient. For mingw, we have to copy | |
| 59 | + # mingw libraries in ourselves. | |
| 60 | + set(ONE_GNU_DLL extra-dlls/libstdc++-6.dll) | |
| 61 | + add_custom_command(OUTPUT ${ONE_GNU_DLL} | |
| 62 | + COMMAND | |
| 63 | + perl ${qpdf_SOURCE_DIR}/copy_dlls | |
| 64 | + qpdf.exe | |
| 65 | + ${CMAKE_BINARY_DIR}/libqpdf | |
| 66 | + extra-dlls) | |
| 67 | + add_custom_target(extra_dlls ALL DEPENDS ${ONE_GNU_DLL}) | |
| 68 | + add_dependencies(extra_dlls qpdf) | |
| 69 | + if(BUILD_SHARED_LIBS) | |
| 70 | + set(EXTRA_DLL_COMPONENT ${COMPONENT_LIB}) | |
| 71 | + else() | |
| 72 | + set(EXTRA_DLL_COMPONENT ${COMPONENT_CLI}) | |
| 73 | + endif() | |
| 74 | + # The trailing / prevents "extra-dlls" from being created in bin. | |
| 75 | + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/extra-dlls/ | |
| 76 | + TYPE BIN | |
| 77 | + COMPONENT ${EXTRA_DLL_COMPONENT}) | |
| 78 | +endif() | ... | ... |
qpdfConfig.cmake.in
0 → 100644
zlib-flate/CMakeLists.txt
0 → 100644
| 1 | +add_executable(zlib-flate zlib-flate.cc) | |
| 2 | +target_link_libraries(zlib-flate libqpdf) | |
| 3 | + | |
| 4 | +add_test( | |
| 5 | + NAME zlib-flate | |
| 6 | + COMMAND ${RUN_QTEST} | |
| 7 | + --top ${qpdf_SOURCE_DIR} | |
| 8 | + --bin $<TARGET_FILE_DIR:zlib-flate> | |
| 9 | + --bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL | |
| 10 | + --code ${qpdf_SOURCE_DIR}/zlib-flate | |
| 11 | + --color ${QTEST_COLOR} | |
| 12 | + --show-on-failure ${SHOW_FAILED_TEST_OUTPUT}) | |
| 13 | + | |
| 14 | +install(TARGETS zlib-flate | |
| 15 | + TYPE RUNTIME | |
| 16 | + COMPONENT ${COMPONENT_CLI}) | ... | ... |