mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add cmake configuration files
This commit is contained in:
parent
105862da3e
commit
b8aff90997
328
CMakeLists.txt
Normal file
328
CMakeLists.txt
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
# manual/installation.rst mentions the minimum cmake version.
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
# make_dist expects the version line to be on a line by itself after
|
||||||
|
# the project line.
|
||||||
|
project(qpdf
|
||||||
|
VERSION 10.6.3
|
||||||
|
LANGUAGES C CXX)
|
||||||
|
|
||||||
|
# Enable correct rpath handling for MacOSX
|
||||||
|
cmake_policy(SET CMP0042 NEW)
|
||||||
|
# Honor CMAKE_REQUIRED_LIBRARIES when checking for include files
|
||||||
|
cmake_policy(SET CMP0075 NEW)
|
||||||
|
|
||||||
|
# *** OPTIONS ***
|
||||||
|
|
||||||
|
# Keep all options here. It's easier to see the interdependencies this
|
||||||
|
# way than spreading them throughout the files.
|
||||||
|
#
|
||||||
|
# ***** Keep manual/installation.rst (_build-options) up to date. *****
|
||||||
|
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
|
# CMAKE_DEPENDENT_OPTION(
|
||||||
|
# OPTION "Description" default-value-if-visible
|
||||||
|
# "when-visible" value-if-not-visible)
|
||||||
|
|
||||||
|
# Don't write tests based on MAINTAINER_MODE or CI_MODE. Instead, use
|
||||||
|
# them as the basis for dependent options.
|
||||||
|
|
||||||
|
option(MAINTAINER_MODE "Set options for developing qpdf" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
CI_MODE "Set options for running in CI" OFF
|
||||||
|
"NOT MAINTAINER_MODE" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
WERROR "Treat compiler warnings as errors" OFF
|
||||||
|
"NOT MAINTAINER_MODE; NOT CI_MODE" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
GENERATE_AUTO_JOB "Automatically regenerate job files" OFF
|
||||||
|
"NOT MAINTAINER_MODE" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
SHOW_FAILED_TEST_OUTPUT "Show qtest output on failure" OFF
|
||||||
|
"NOT CI_MODE" ON)
|
||||||
|
|
||||||
|
# To allow building doc to be disabled in maintainer mode, handle the
|
||||||
|
# condition manually rather than using a dependent option.
|
||||||
|
if(MAINTAINER_MODE)
|
||||||
|
set(default_BUILD_DOC ON)
|
||||||
|
else()
|
||||||
|
set(default_BUILD_DOC OFF)
|
||||||
|
endif()
|
||||||
|
option(BUILD_DOC "Build documentation" ${default_BUILD_DOC})
|
||||||
|
# The values of BUILD_DOC_HTML and BUILD_DOC_PDF are ignored without
|
||||||
|
# BUILD_DOC, so setting them to ON when not visible forces them to be
|
||||||
|
# on in MAINTAINER_MODE and is harmless if BUILD_DOC is off.
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
BUILD_DOC_HTML "Build HTML documentation"
|
||||||
|
ON "BUILD_DOC;NOT MAINTAINER_MODE" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
BUILD_DOC_PDF "Build PDF documentation"
|
||||||
|
ON "BUILD_DOC;NOT MAINTAINER_MODE" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
BUILD_DOC_DIST "Create distribution of manual" ON
|
||||||
|
"BUILD_DOC_PDF;BUILD_DOC_HTML" OFF)
|
||||||
|
|
||||||
|
option(BUILD_SHARED_LIBS "Build qpdf shared libraries" ON)
|
||||||
|
option(BUILD_STATIC_LIBS "Build qpdf static libraries" ON)
|
||||||
|
option(QTEST_COLOR "Whether qtest's output should be in color" ON)
|
||||||
|
option(USE_INSECURE_RANDOM "Use insecure random numbers" OFF)
|
||||||
|
option(SKIP_OS_SECURE_RANDOM
|
||||||
|
"Suppress use of OS-provided secure random numbers" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
AVOID_WINDOWS_HANDLE "Avoid use of HANDLE in Windows" OFF
|
||||||
|
"WIN32" OFF)
|
||||||
|
|
||||||
|
option(OSS_FUZZ "Specific build configuration for the oss-fuzz project" OFF)
|
||||||
|
|
||||||
|
option(USE_IMPLICIT_CRYPTO "Enable any available external crypto provider" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
ALLOW_CRYPTO_NATIVE "Allow native crypto as as fallback" ON
|
||||||
|
"USE_IMPLICIT_CRYPTO" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(
|
||||||
|
REQUIRE_CRYPTO_NATIVE "Require native crypto provider" OFF
|
||||||
|
"NOT MAINTAINER_MODE; NOT CI_MODE" ON)
|
||||||
|
option(REQUIRE_CRYPTO_OPENSSL "Require openssl crypto" OFF)
|
||||||
|
option(REQUIRE_CRYPTO_GNUTLS "Require gnutls crypto" OFF)
|
||||||
|
set(DEFAULT_CRYPTO CACHE STRING "")
|
||||||
|
option(DEFAULT_CRYPTO
|
||||||
|
"Specify default crypto; otherwise chosen automatically" "")
|
||||||
|
|
||||||
|
# INSTALL_MANUAL is not dependent on building docs. When creating some
|
||||||
|
# distributions, we build the doc in one run, copy doc-dist in, and
|
||||||
|
# install it elsewhere.
|
||||||
|
option(INSTALL_MANUAL "Install documentation" OFF)
|
||||||
|
|
||||||
|
option(INSTALL_PKGCONFIG "Install pkgconfig file" ON)
|
||||||
|
option(INSTALL_CMAKE_PACKAGE "Install cmake package files" ON)
|
||||||
|
option(INSTALL_EXAMPLES "Install example files" ON)
|
||||||
|
|
||||||
|
# *** END OPTIONS ***
|
||||||
|
|
||||||
|
if(NOT (BUILD_STATIC_LIBS OR BUILD_SHARED_LIBS))
|
||||||
|
message(
|
||||||
|
FATAL_ERROR "At least one of static or shared libraries must be built")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_compile_definitions($<$<COMPILE_LANGUAGE:CXX>:POINTERHOLDER_TRANSITION=2>)
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
set(RUN_QTEST perl ${qpdf_SOURCE_DIR}/run-qtest)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
find_program(COPY_COMMAND NAMES cp copy)
|
||||||
|
if(COPY_COMMAND STREQUAL "COPY_COMMAND-NOTFOUND")
|
||||||
|
set(COPY_COMMAND "copy")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(COPY_COMMAND "cp")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# For a long time, qpdf used libtool's version system. We are no
|
||||||
|
# longer doing that, but to avoid potential conflict with older
|
||||||
|
# versions, continue to have the shared library symlink point to a
|
||||||
|
# file whose version shares minor and patch with the project version
|
||||||
|
# and major with the SOVERSION. Starting with the transition to cmake,
|
||||||
|
# increment SOVERSION every time we increment the project major
|
||||||
|
# version. This works because qpdf uses semantic versioning. qpdf 10.x
|
||||||
|
# was libqpdf28, so start from there.
|
||||||
|
math(EXPR qpdf_SOVERSION "${PROJECT_VERSION_MAJOR} + 18")
|
||||||
|
set(qpdf_LIBVERSION ${qpdf_SOVERSION}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||||
|
|
||||||
|
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||||
|
message(FATAL_ERROR "
|
||||||
|
Please build with cmake in a subdirectory, e.g.
|
||||||
|
mkdir build
|
||||||
|
cmake ..
|
||||||
|
cmake --build .
|
||||||
|
Please remove CMakeCache.txt and the CMakeFiles directories.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
if(WIN32 AND NOT SKIP_OS_SECURE_RANDOM)
|
||||||
|
list(APPEND CMAKE_REQUIRED_LIBRARIES Advapi32)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
function(check_atomic)
|
||||||
|
foreach(I 0 1)
|
||||||
|
if(I)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES atomic)
|
||||||
|
endif()
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"#include <atomic>
|
||||||
|
int main() {
|
||||||
|
static std::atomic<int> a{0};
|
||||||
|
a = a.fetch_add(1);
|
||||||
|
return 0;
|
||||||
|
}"
|
||||||
|
ATOMIC_WORKED${I})
|
||||||
|
if(ATOMIC_WORKED0)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(ATOMIC_WORKED1)
|
||||||
|
list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
check_atomic()
|
||||||
|
|
||||||
|
set(WINDOWS_WMAIN_COMPILE "")
|
||||||
|
set(WINDOWS_WMAIN_LINK "")
|
||||||
|
if(WIN32)
|
||||||
|
function(check_wmain)
|
||||||
|
foreach(I 0 1)
|
||||||
|
if(NOT WINDOWS_WMAIN_COMPILE)
|
||||||
|
if(I)
|
||||||
|
set(CMAKE_REQUIRED_LINK_OPTIONS -municode)
|
||||||
|
endif()
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
extern \"C\"
|
||||||
|
int wmain(int argc, wchar_t* argv[])
|
||||||
|
{
|
||||||
|
size_t x = wcslen(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
WMAIN_WORKED${I})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(WMAIN_WORKED1 OR WMAIN_WORKED1)
|
||||||
|
set(WINDOWS_WMAIN_COMPILE -DWINDOWS_WMAIN PARENT_SCOPE)
|
||||||
|
if(WMAIN_WORKED1 AND NOT WMAIN_WORKED0)
|
||||||
|
set(WINDOWS_WMAIN_LINK -municode PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
check_wmain()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS -link setargv.obj)
|
||||||
|
list(APPEND WINDOWS_WMAIN_LINK -link wsetargv.obj)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
#
|
||||||
|
# **NOTE** -- each flag must have its own cache variable.
|
||||||
|
|
||||||
|
include(qpdfCheckFlag)
|
||||||
|
if(WERROR)
|
||||||
|
if(MSVC)
|
||||||
|
add_compile_options(/WX)
|
||||||
|
else()
|
||||||
|
qpdf_maybe_add_flag(C -Werror flag_werror)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
# /Gy combines identical functions -- useful with C++ templates
|
||||||
|
add_compile_options(/Gy)
|
||||||
|
add_compile_options(/W3) # warning level 3
|
||||||
|
else()
|
||||||
|
qpdf_maybe_add_flag(C -Wall flag_wall)
|
||||||
|
qpdf_maybe_add_flag(C -Wconversion flag_conversion)
|
||||||
|
qpdf_maybe_add_flag(C -Wsign-conversion flag_sign-conversion)
|
||||||
|
qpdf_maybe_add_flag(C -Wshadow=local flag_shadow_local)
|
||||||
|
qpdf_maybe_add_flag(CXX -Wold-style-cast flag_old-style-cast)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# We don't include the jpeg library's include path in the PUBLIC
|
||||||
|
# interface for libqpdf since only Pl_DCT.hh requires it. This is
|
||||||
|
# documented. Some examples and tests use it though so we have to
|
||||||
|
# define it. CMakeLists.txt for libqpdf sets the value for
|
||||||
|
# JPEG_INCLUDE which can be selectively added to include paths other
|
||||||
|
# tools.
|
||||||
|
set(JPEG_INCLUDE)
|
||||||
|
|
||||||
|
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||||
|
set(WORDSIZE 64)
|
||||||
|
else()
|
||||||
|
set(WORDSIZE 32)
|
||||||
|
endif()
|
||||||
|
if(MSVC)
|
||||||
|
set(CPACK_SYSTEM_NAME "msvc${WORDSIZE}")
|
||||||
|
elseif(MINGW)
|
||||||
|
set(CPACK_SYSTEM_NAME "mingw${WORDSIZE}")
|
||||||
|
endif()
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE "${qpdf_SOURCE_DIR}/LICENSE.txt")
|
||||||
|
set(CPACK_PACKAGE_HOMEPAGE_URL "https://qpdf.sourceforge.io/")
|
||||||
|
set(CPACK_NSIS_MUI_ICON "${qpdf_SOURCE_DIR}/logo/qpdf.ico")
|
||||||
|
|
||||||
|
include(CPack)
|
||||||
|
|
||||||
|
# Install components -- documented in _installation in
|
||||||
|
# manual/installation.rst.
|
||||||
|
set(COMPONENT_DEV "dev")
|
||||||
|
set(COMPONENT_LIB "lib") # runtime library
|
||||||
|
set(COMPONENT_CLI "cli")
|
||||||
|
set(COMPONENT_DOC "doc")
|
||||||
|
set(COMPONENT_EXAMPLES "examples") # example sources
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
include(InstallRequiredSystemLibraries)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# add_subdirectory order affects test order
|
||||||
|
add_subdirectory(include)
|
||||||
|
add_subdirectory(libqpdf)
|
||||||
|
add_subdirectory(qpdf)
|
||||||
|
add_subdirectory(libtests)
|
||||||
|
add_subdirectory(examples)
|
||||||
|
add_subdirectory(zlib-flate)
|
||||||
|
add_subdirectory(manual)
|
||||||
|
add_subdirectory(fuzz)
|
||||||
|
|
||||||
|
# We don't need to show everything -- just the things that we really
|
||||||
|
# need to be sure are right or that are turned on or off with complex
|
||||||
|
# logic.
|
||||||
|
get_property(MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
message(STATUS "")
|
||||||
|
message(STATUS "*** Summary ***")
|
||||||
|
message(STATUS " qpdf version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||||
|
if(MULTI_CONFIG)
|
||||||
|
message(STATUS " build type: specify --config at build time")
|
||||||
|
elseif(CMAKE_BUILD_TYPE)
|
||||||
|
message(STATUS " build type: ${CMAKE_BUILD_TYPE}")
|
||||||
|
endif()
|
||||||
|
message(STATUS " build shared libraries: ${BUILD_SHARED_LIBS}")
|
||||||
|
message(STATUS " build static libraries: ${BUILD_STATIC_LIBS}")
|
||||||
|
message(STATUS " build manual: ${BUILD_DOC}")
|
||||||
|
message(STATUS " compiler warnings are errors: ${WERROR}")
|
||||||
|
message(STATUS " system: ${CPACK_SYSTEM_NAME}")
|
||||||
|
message(STATUS "")
|
||||||
|
message(STATUS "*** Options Summary ***")
|
||||||
|
foreach(PROP
|
||||||
|
COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS
|
||||||
|
COMPILE_DEFINITIONS INTERFACE_COMPILE_DEFINITIONS
|
||||||
|
INCLUDE_DIRECTORIES INTERFACE_INCLUDE_DIRECTORIES
|
||||||
|
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
|
||||||
|
LINK_OPTIONS INTERFACE_LINK_OPTIONS
|
||||||
|
LINK_LIBRARIES INTERFACE_LINK_LIBRARIES
|
||||||
|
LINK_DIRECTORIES INTERFACE_LINK_DIRECTORIES)
|
||||||
|
get_target_property(VAL libqpdf ${PROP})
|
||||||
|
if(NOT (VAL STREQUAL "VAL-NOTFOUND"))
|
||||||
|
message(STATUS " ${PROP}: ${VAL}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(APPLE)
|
||||||
|
message(STATUS " CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}")
|
||||||
|
endif()
|
||||||
|
message(STATUS "")
|
||||||
|
message(STATUS "See above for crypto summary.")
|
||||||
|
message(STATUS "")
|
||||||
|
if(NOT (MULTI_CONFIG OR CMAKE_BUILD_TYPE))
|
||||||
|
message(WARNING " CMAKE_BUILD_TYPE is not set; using default settings")
|
||||||
|
endif()
|
21
cmake/qpdfCheckFlag.cmake
Normal file
21
cmake/qpdfCheckFlag.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
|
||||||
|
function(qpdf_maybe_add_flag lang flag var)
|
||||||
|
if(${lang} STREQUAL "C")
|
||||||
|
check_c_compiler_flag(${flag} ${var})
|
||||||
|
elseif(${lang} STREQUAL "CXX")
|
||||||
|
check_cxx_compiler_flag(${flag} ${var})
|
||||||
|
endif()
|
||||||
|
if(${var})
|
||||||
|
message(STATUS "Using ${flag}: YES")
|
||||||
|
if(${lang} STREQUAL "C")
|
||||||
|
# Add for C and C++
|
||||||
|
add_compile_options(${flag})
|
||||||
|
else()
|
||||||
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${flag}>)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS "Using ${flag}: NO")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
52
examples/CMakeLists.txt
Normal file
52
examples/CMakeLists.txt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
set(EXAMPLE_CXX_PROGRAMS
|
||||||
|
pdf-attach-file
|
||||||
|
pdf-bookmarks
|
||||||
|
pdf-count-strings
|
||||||
|
pdf-create
|
||||||
|
pdf-custom-filter
|
||||||
|
pdf-double-page-size
|
||||||
|
pdf-filter-tokens
|
||||||
|
pdf-invert-images
|
||||||
|
pdf-mod-info
|
||||||
|
pdf-name-number-tree
|
||||||
|
pdf-npages
|
||||||
|
pdf-overlay-page
|
||||||
|
pdf-parse-content
|
||||||
|
pdf-set-form-values
|
||||||
|
pdf-split-pages
|
||||||
|
qpdf-job)
|
||||||
|
set(EXAMPLE_C_PROGRAMS
|
||||||
|
pdf-c-objects
|
||||||
|
pdf-linearize
|
||||||
|
qpdfjob-c)
|
||||||
|
|
||||||
|
foreach(PROG ${EXAMPLE_CXX_PROGRAMS})
|
||||||
|
add_executable(${PROG} ${PROG}.cc)
|
||||||
|
target_link_libraries(${PROG} libqpdf)
|
||||||
|
endforeach()
|
||||||
|
foreach(PROG ${EXAMPLE_C_PROGRAMS})
|
||||||
|
add_executable(${PROG} ${PROG}.c)
|
||||||
|
target_link_libraries(${PROG} libqpdf)
|
||||||
|
set_property(TARGET ${PROG} PROPERTY LINKER_LANGUAGE CXX)
|
||||||
|
endforeach()
|
||||||
|
target_include_directories(pdf-create PRIVATE ${JPEG_INCLUDE})
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME examples
|
||||||
|
COMMAND ${RUN_QTEST}
|
||||||
|
--top ${qpdf_SOURCE_DIR}
|
||||||
|
--bin $<TARGET_FILE_DIR:pdf-create>
|
||||||
|
--bin $<TARGET_FILE_DIR:qpdf>
|
||||||
|
--bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL
|
||||||
|
--code ${qpdf_SOURCE_DIR}/examples
|
||||||
|
--color ${QTEST_COLOR}
|
||||||
|
--show-on-failure ${SHOW_FAILED_TEST_OUTPUT}
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/examples/*.cc"
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/examples/*.c")
|
||||||
|
|
||||||
|
file(GLOB EXAMPLES_SRC "*.c" "*.cc")
|
||||||
|
if(INSTALL_EXAMPLES)
|
||||||
|
install(FILES ${EXAMPLES_SRC}
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples
|
||||||
|
COMPONENT ${COMPONENT_EXAMPLES})
|
||||||
|
endif()
|
178
fuzz/CMakeLists.txt
Normal file
178
fuzz/CMakeLists.txt
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
# This directory contains support for Google's oss-fuzz project. See
|
||||||
|
# https://github.com/google/oss-fuzz/tree/master/projects/qpdf
|
||||||
|
|
||||||
|
set(FUZZERS
|
||||||
|
qpdf_fuzzer
|
||||||
|
ascii85_fuzzer
|
||||||
|
dct_fuzzer
|
||||||
|
flate_fuzzer
|
||||||
|
hex_fuzzer
|
||||||
|
lzw_fuzzer
|
||||||
|
pngpredictor_fuzzer
|
||||||
|
runlength_fuzzer
|
||||||
|
tiffpredictor_fuzzer)
|
||||||
|
|
||||||
|
# The oss-fuzz project provides LIB_FUZZING_ENGINE and OUT environment
|
||||||
|
# variables. For local testing, provide values if not set.
|
||||||
|
set(LIB_FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE})
|
||||||
|
if(NOT LIB_FUZZING_ENGINE)
|
||||||
|
# When running from oss-fuzz, LIB_FUZZING_ENGINE points to a
|
||||||
|
# static library that contains main.
|
||||||
|
add_library(standalone_fuzzer STATIC standalone_fuzz_target_runner.cc)
|
||||||
|
target_include_directories(
|
||||||
|
standalone_fuzzer PRIVATE ${qpdf_SOURCE_DIR}/include)
|
||||||
|
set(LIB_FUZZING_ENGINE standalone_fuzzer)
|
||||||
|
endif()
|
||||||
|
set(FUZZ_OUT $ENV{OUT})
|
||||||
|
if(NOT FUZZ_OUT)
|
||||||
|
set(FUZZ_OUT ${CMAKE_CURRENT_BINARY_DIR}/fuzz-install)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(OSS_FUZZ)
|
||||||
|
# We need to link jpeg and zlib statically for oss-fuzz. Construct
|
||||||
|
# our own object library without the external dependencies and add
|
||||||
|
# what we need.
|
||||||
|
add_library(libqpdf_fuzz STATIC $<TARGET_OBJECTS:libqpdf_object>)
|
||||||
|
target_link_libraries(libqpdf_fuzz INTERFACE libjpeg.a libz.a)
|
||||||
|
target_include_directories(libqpdf_fuzz
|
||||||
|
PUBLIC
|
||||||
|
${JPEG_INCLUDE}
|
||||||
|
${qpdf_SOURCE_DIR}/include
|
||||||
|
${qpdf_SOURCE_DIR}/libqpdf)
|
||||||
|
else()
|
||||||
|
add_library(libqpdf_fuzz ALIAS libqpdf_object)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(PROG ${FUZZERS})
|
||||||
|
add_executable(${PROG} ${PROG}.cc)
|
||||||
|
target_link_libraries(${PROG} ${LIB_FUZZING_ENGINE})
|
||||||
|
target_link_libraries(${PROG} libqpdf_fuzz)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Files from the test suite that are good for seeding the fuzzer.
|
||||||
|
# Update count for qpdf in @fuzzers qtest/fuzz.test if you change this list.
|
||||||
|
set(CORPUS_FROM_TEST
|
||||||
|
stream-data.pdf
|
||||||
|
lin5.pdf
|
||||||
|
field-types.pdf
|
||||||
|
image-streams-small.pdf
|
||||||
|
need-appearances.pdf
|
||||||
|
outlines-with-actions.pdf
|
||||||
|
outlines-with-old-root-dests.pdf
|
||||||
|
page-labels-and-outlines.pdf
|
||||||
|
page-labels-num-tree.pdf
|
||||||
|
dr-with-indirect-item.pdf
|
||||||
|
fuzz-16214.pdf
|
||||||
|
issue-99b.pdf
|
||||||
|
issue-99.pdf
|
||||||
|
issue-100.pdf
|
||||||
|
issue-101.pdf
|
||||||
|
issue-106.pdf
|
||||||
|
issue-117.pdf
|
||||||
|
issue-119.pdf
|
||||||
|
issue-120.pdf
|
||||||
|
issue-141a.pdf
|
||||||
|
issue-141b.pdf
|
||||||
|
issue-143.pdf
|
||||||
|
issue-146.pdf
|
||||||
|
issue-147.pdf
|
||||||
|
issue-148.pdf
|
||||||
|
issue-149.pdf
|
||||||
|
issue-150.pdf
|
||||||
|
issue-202.pdf
|
||||||
|
issue-263.pdf
|
||||||
|
issue-335a.pdf
|
||||||
|
issue-335b.pdf)
|
||||||
|
|
||||||
|
# Any file that qpdf_fuzzer should be tested with can be named
|
||||||
|
# something.fuzz and dropped into qpdf_extra. Update count for qpdf in
|
||||||
|
# @fuzzers qtest/fuzz.test if you change this list.
|
||||||
|
set(CORPUS_OTHER
|
||||||
|
15316.fuzz
|
||||||
|
15387.fuzz
|
||||||
|
15390.fuzz
|
||||||
|
15442.fuzz
|
||||||
|
15445.fuzz
|
||||||
|
15983.fuzz
|
||||||
|
16172.fuzz
|
||||||
|
16301.fuzz
|
||||||
|
16953.fuzz
|
||||||
|
18241.fuzz
|
||||||
|
18247.fuzz
|
||||||
|
23172.fuzz
|
||||||
|
23599.fuzz
|
||||||
|
23642.fuzz
|
||||||
|
23642-mod.fuzz
|
||||||
|
26761.fuzz
|
||||||
|
26994.fuzz
|
||||||
|
27393.fuzz
|
||||||
|
28262.fuzz
|
||||||
|
30507.fuzz
|
||||||
|
37740.fuzz)
|
||||||
|
|
||||||
|
set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
|
||||||
|
file(MAKE_DIRECTORY ${CORPUS_DIR})
|
||||||
|
function(copy_fuzz FROM)
|
||||||
|
file(SHA1 ${FROM} SHA)
|
||||||
|
set(OUT ${CORPUS_DIR}/${SHA})
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${OUT}
|
||||||
|
COMMAND ${COPY_COMMAND} $<SHELL_PATH:${FROM}> $<SHELL_PATH:${OUT}>)
|
||||||
|
set(CORPUS_FILE ${OUT} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
list(APPEND CORPUS_FILES)
|
||||||
|
foreach(F ${CORPUS_FROM_TEST})
|
||||||
|
copy_fuzz(${qpdf_SOURCE_DIR}/qpdf/qtest/qpdf/${F})
|
||||||
|
list(APPEND CORPUS_FILES ${CORPUS_FILE})
|
||||||
|
endforeach()
|
||||||
|
foreach(F ${CORPUS_OTHER})
|
||||||
|
copy_fuzz(${CMAKE_CURRENT_SOURCE_DIR}/qpdf_extra/${F})
|
||||||
|
list(APPEND CORPUS_FILES ${CORPUS_FILE})
|
||||||
|
endforeach()
|
||||||
|
add_custom_target(qpdf_corpus ALL
|
||||||
|
DEPENDS ${CORPUS_FILES})
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME fuzz
|
||||||
|
COMMAND ${RUN_QTEST}
|
||||||
|
--env QPDF_FUZZ_CORPUS=${CORPUS_DIR}
|
||||||
|
--top ${qpdf_SOURCE_DIR}
|
||||||
|
--bin $<TARGET_FILE_DIR:qpdf_fuzzer>
|
||||||
|
--bin $<TARGET_FILE_DIR:qpdf>
|
||||||
|
--code ${qpdf_SOURCE_DIR}/fuzz
|
||||||
|
--color ${QTEST_COLOR}
|
||||||
|
--show-on-failure ${SHOW_FAILED_TEST_OUTPUT})
|
||||||
|
|
||||||
|
if(OSS_FUZZ)
|
||||||
|
list(APPEND SEED_CORPUS_ZIPS)
|
||||||
|
foreach(F ${FUZZERS})
|
||||||
|
if(F STREQUAL qpdf_fuzzer)
|
||||||
|
set(SEED_DIR ${CORPUS_DIR})
|
||||||
|
else()
|
||||||
|
set(SEED_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${F}_seed_corpus)
|
||||||
|
endif()
|
||||||
|
set(SEED_ZIP ${CMAKE_CURRENT_BINARY_DIR}/${F}_seed_corpus.zip)
|
||||||
|
add_custom_command(OUTPUT ${SEED_ZIP}
|
||||||
|
COMMAND zip -q -r ${SEED_ZIP} .
|
||||||
|
WORKING_DIRECTORY ${SEED_DIR})
|
||||||
|
list(APPEND SEED_CORPUS_ZIPS ${SEED_ZIP})
|
||||||
|
endforeach()
|
||||||
|
add_custom_target(seed_corpus_zips ALL DEPENDS ${SEED_CORPUS_ZIPS})
|
||||||
|
add_dependencies(seed_corpus_zips qpdf_corpus)
|
||||||
|
add_custom_target(fuzzers)
|
||||||
|
add_dependencies(fuzzers ${FUZZERS} seed_corpus_zips)
|
||||||
|
install(
|
||||||
|
TARGETS ${FUZZERS}
|
||||||
|
DESTINATION ${FUZZ_OUT}
|
||||||
|
EXCLUDE_FROM_ALL
|
||||||
|
COMPONENT fuzz)
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/pdf.dict
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/qpdf_fuzzer.options
|
||||||
|
${SEED_CORPUS_ZIPS}
|
||||||
|
DESTINATION ${FUZZ_OUT}
|
||||||
|
EXCLUDE_FROM_ALL
|
||||||
|
COMPONENT fuzz)
|
||||||
|
endif()
|
12
include/CMakeLists.txt
Normal file
12
include/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
set(qpdf_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
|
||||||
|
|
||||||
|
# While globs are not considered best practice, it makes sense for
|
||||||
|
# installation o header files. When compiling, you specify an entire
|
||||||
|
# directory, so not doing the same at installation time creates a high
|
||||||
|
# risk that forgetting to explicitly add a header to an installation
|
||||||
|
# list would not be detected in CI or at any time until an end user
|
||||||
|
# tries to build code.
|
||||||
|
install(DIRECTORY qpdf
|
||||||
|
TYPE INCLUDE
|
||||||
|
COMPONENT ${COMPONENT_DEV}
|
||||||
|
FILES_MATCHING PATTERN "*.h" PATTERN "*.hh")
|
581
libqpdf/CMakeLists.txt
Normal file
581
libqpdf/CMakeLists.txt
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
|
||||||
|
if(GENERATE_AUTO_JOB)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${qpdf_SOURCE_DIR}/generate_auto_job --generate
|
||||||
|
WORKING_DIRECTORY ${qpdf_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(libqpdf_crypto_native
|
||||||
|
AES_PDF_native.cc
|
||||||
|
MD5_native.cc
|
||||||
|
QPDFCrypto_native.cc
|
||||||
|
RC4_native.cc
|
||||||
|
SHA2_native.cc
|
||||||
|
rijndael.cc
|
||||||
|
sha2.c
|
||||||
|
sha2big.c)
|
||||||
|
|
||||||
|
set(libqpdf_crypto_openssl
|
||||||
|
QPDFCrypto_openssl.cc)
|
||||||
|
|
||||||
|
set(libqpdf_crypto_gnutls
|
||||||
|
QPDFCrypto_gnutls.cc)
|
||||||
|
|
||||||
|
set(libqpdf_SOURCES
|
||||||
|
BitStream.cc
|
||||||
|
BitWriter.cc
|
||||||
|
Buffer.cc
|
||||||
|
BufferInputSource.cc
|
||||||
|
ClosedFileInputSource.cc
|
||||||
|
ContentNormalizer.cc
|
||||||
|
CryptoRandomDataProvider.cc
|
||||||
|
FileInputSource.cc
|
||||||
|
InputSource.cc
|
||||||
|
InsecureRandomDataProvider.cc
|
||||||
|
JSON.cc
|
||||||
|
JSONHandler.cc
|
||||||
|
MD5.cc
|
||||||
|
NNTree.cc
|
||||||
|
OffsetInputSource.cc
|
||||||
|
PDFVersion.cc
|
||||||
|
Pipeline.cc
|
||||||
|
Pl_AES_PDF.cc
|
||||||
|
Pl_ASCII85Decoder.cc
|
||||||
|
Pl_ASCIIHexDecoder.cc
|
||||||
|
Pl_Buffer.cc
|
||||||
|
Pl_Concatenate.cc
|
||||||
|
Pl_Count.cc
|
||||||
|
Pl_DCT.cc
|
||||||
|
Pl_Discard.cc
|
||||||
|
Pl_Flate.cc
|
||||||
|
Pl_LZWDecoder.cc
|
||||||
|
Pl_MD5.cc
|
||||||
|
Pl_PNGFilter.cc
|
||||||
|
Pl_QPDFTokenizer.cc
|
||||||
|
Pl_RC4.cc
|
||||||
|
Pl_RunLength.cc
|
||||||
|
Pl_SHA2.cc
|
||||||
|
Pl_StdioFile.cc
|
||||||
|
Pl_TIFFPredictor.cc
|
||||||
|
QPDF.cc
|
||||||
|
QPDFAcroFormDocumentHelper.cc
|
||||||
|
QPDFAnnotationObjectHelper.cc
|
||||||
|
QPDFArgParser.cc
|
||||||
|
QPDFCryptoProvider.cc
|
||||||
|
QPDFEFStreamObjectHelper.cc
|
||||||
|
QPDFEmbeddedFileDocumentHelper.cc
|
||||||
|
QPDFExc.cc
|
||||||
|
QPDFFileSpecObjectHelper.cc
|
||||||
|
QPDFFormFieldObjectHelper.cc
|
||||||
|
QPDFJob.cc
|
||||||
|
QPDFJob_argv.cc
|
||||||
|
QPDFJob_config.cc
|
||||||
|
QPDFJob_json.cc
|
||||||
|
QPDFMatrix.cc
|
||||||
|
QPDFNameTreeObjectHelper.cc
|
||||||
|
QPDFNumberTreeObjectHelper.cc
|
||||||
|
QPDFObjGen.cc
|
||||||
|
QPDFObject.cc
|
||||||
|
QPDFObjectHandle.cc
|
||||||
|
QPDFOutlineDocumentHelper.cc
|
||||||
|
QPDFOutlineObjectHelper.cc
|
||||||
|
QPDFPageDocumentHelper.cc
|
||||||
|
QPDFPageLabelDocumentHelper.cc
|
||||||
|
QPDFPageObjectHelper.cc
|
||||||
|
QPDFStreamFilter.cc
|
||||||
|
QPDFSystemError.cc
|
||||||
|
QPDFTokenizer.cc
|
||||||
|
QPDFUsage.cc
|
||||||
|
QPDFWriter.cc
|
||||||
|
QPDFXRefEntry.cc
|
||||||
|
QPDF_Array.cc
|
||||||
|
QPDF_Bool.cc
|
||||||
|
QPDF_Dictionary.cc
|
||||||
|
QPDF_InlineImage.cc
|
||||||
|
QPDF_Integer.cc
|
||||||
|
QPDF_Name.cc
|
||||||
|
QPDF_Null.cc
|
||||||
|
QPDF_Operator.cc
|
||||||
|
QPDF_Real.cc
|
||||||
|
QPDF_Reserved.cc
|
||||||
|
QPDF_Stream.cc
|
||||||
|
QPDF_String.cc
|
||||||
|
QPDF_encryption.cc
|
||||||
|
QPDF_linearization.cc
|
||||||
|
QPDF_optimization.cc
|
||||||
|
QPDF_pages.cc
|
||||||
|
QTC.cc
|
||||||
|
QUtil.cc
|
||||||
|
RC4.cc
|
||||||
|
ResourceFinder.cc
|
||||||
|
SecureRandomDataProvider.cc
|
||||||
|
SF_FlateLzwDecode.cc
|
||||||
|
SparseOHArray.cc
|
||||||
|
qpdf-c.cc
|
||||||
|
qpdfjob-c.cc)
|
||||||
|
|
||||||
|
include(FindPkgConfig)
|
||||||
|
include(CheckTypeSize)
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
include(CheckCSourceCompiles)
|
||||||
|
include(CheckCSourceRuns)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
|
set(dep_include_directories)
|
||||||
|
set(dep_link_directories)
|
||||||
|
set(dep_link_libraries)
|
||||||
|
set(ANYTHING_MISSING 0)
|
||||||
|
|
||||||
|
if(WIN32 AND (EXISTS ${qpdf_SOURCE_DIR}/external-libs))
|
||||||
|
set(EXTERNAL_LIBS 1)
|
||||||
|
else()
|
||||||
|
set(EXTERNAL_LIBS 0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EXTERNAL_LIBS)
|
||||||
|
set(EXTLIBDIR ${qpdf_SOURCE_DIR}/external-libs)
|
||||||
|
list(APPEND dep_include_directories ${EXTLIBDIR}/include)
|
||||||
|
set(JPEG_INCLUDE ${EXTLIBDIR}/include)
|
||||||
|
list(APPEND dep_link_libraries
|
||||||
|
z jpeg ssl crypto msvcrt ws2_32 shell32 advapi32 gdi32 user32 crypt32)
|
||||||
|
if (MSVC)
|
||||||
|
list(APPEND dep_link_directories ${EXTLIBDIR}/lib-msvc${WORDSIZE})
|
||||||
|
else()
|
||||||
|
list(APPEND dep_link_directories ${EXTLIBDIR}/lib-mingw${WORDSIZE})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT EXTERNAL_LIBS)
|
||||||
|
pkg_check_modules(pc_zlib zlib)
|
||||||
|
if(pc_zlib_FOUND)
|
||||||
|
list(APPEND dep_include_directories ${pc_zlib_INCLUDEDIR})
|
||||||
|
list(APPEND dep_link_directories ${pc_zlib_LIBDIR})
|
||||||
|
list(APPEND dep_link_libraries ${pc_zlib_LIBRARIES})
|
||||||
|
else()
|
||||||
|
find_path(ZLIB_H_PATH zlib.h)
|
||||||
|
find_library(ZLIB_LIB_PATH z zlib)
|
||||||
|
if(ZLIB_H_PATH AND ZLIB_LIB_PATH)
|
||||||
|
list(APPEND dep_include_directories ${ZLIB_H_PATH})
|
||||||
|
list(APPEND dep_link_libraries ${ZLIB_LIB_PATH})
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "zlib not found")
|
||||||
|
set(ANYTHING_MISSING 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT EXTERNAL_LIBS)
|
||||||
|
pkg_check_modules(pc_libjpeg libjpeg)
|
||||||
|
if(pc_libjpeg_FOUND)
|
||||||
|
list(APPEND dep_include_directories ${pc_libjpeg_INCLUDEDIR})
|
||||||
|
list(APPEND dep_link_directories ${pc_libjpeg_LIBDIR})
|
||||||
|
list(APPEND dep_link_libraries ${pc_libjpeg_LIBRARIES})
|
||||||
|
set(JPEG_INCLUDE ${pc_libjpeg_INCLUDEDIR})
|
||||||
|
else()
|
||||||
|
find_path(LIBJPEG_H_PATH jpeglib.h)
|
||||||
|
find_library(LIBJPEG_LIB_PATH jpeg)
|
||||||
|
if(LIBJPEG_H_PATH AND LIBJPEG_LIB_PATH)
|
||||||
|
list(APPEND dep_include_directories ${LIBJPEG_H_PATH})
|
||||||
|
list(APPEND dep_link_libraries ${LIBJPEG_LIB_PATH})
|
||||||
|
set(JPEG_INCLUDE ${LIBJPEG_H_PATH})
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "libjpeg not found")
|
||||||
|
set(ANYTHING_MISSING 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Update JPEG_INCLUDE in PARENT_SCOPE after we have finished setting it.
|
||||||
|
set(JPEG_INCLUDE ${JPEG_INCLUDE} PARENT_SCOPE)
|
||||||
|
|
||||||
|
# Crypto provider selection. Prefer external crypto providers. If
|
||||||
|
# implicit selection is allowed, use native only when no other options
|
||||||
|
# are available or when explicitly requested. Allowing native as a
|
||||||
|
# fallback can be disabled using the ALLOW_CRYPTO_NATIVE option.
|
||||||
|
list(APPEND CRYPTO_PKG)
|
||||||
|
|
||||||
|
set(USE_CRYPTO_GNUTLS OFF)
|
||||||
|
set(USE_CRYPTO_OPENSSL OFF)
|
||||||
|
set(USE_CRYPTO_NATIVE OFF)
|
||||||
|
set(FOUND_CRYPTO OFF)
|
||||||
|
|
||||||
|
if(USE_IMPLICIT_CRYPTO OR REQUIRE_CRYPTO_OPENSSL)
|
||||||
|
if(EXTERNAL_LIBS)
|
||||||
|
set(USE_CRYPTO_OPENSSL ON)
|
||||||
|
else()
|
||||||
|
pkg_check_modules(pc_openssl openssl>=1.1.0)
|
||||||
|
if(pc_openssl_FOUND)
|
||||||
|
set(USE_CRYPTO_OPENSSL ON)
|
||||||
|
set(FOUND_CRYPTO ON)
|
||||||
|
set(CRYPTO_PKG "${CRYPTO_PKG}, openssl>=1.1.0")
|
||||||
|
else()
|
||||||
|
find_path(OPENSSL_H_PATH openssl/evp.h)
|
||||||
|
find_library(OPENSSL_LIB_PATH crypto)
|
||||||
|
if(OPENSSL_H_PATH AND OPENSSL_LIB_PATH)
|
||||||
|
list(APPEND dep_include_directories ${OPENSSL_H_PATH})
|
||||||
|
list(APPEND dep_link_libraries ${OPENSSL_LIB_PATH})
|
||||||
|
set(USE_CRYPTO_OPENSSL ON)
|
||||||
|
set(FOUND_CRYPTO ON)
|
||||||
|
elseif(REQUIRE_CRYPTO_OPENSSL)
|
||||||
|
message(SEND_ERROR "openssl not found")
|
||||||
|
set(ANYTHING_MISSING 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(USE_IMPLICIT_CRYPTO OR REQUIRE_CRYPTO_GNUTLS)
|
||||||
|
pkg_check_modules(pc_gnutls gnutls)
|
||||||
|
if(pc_gnutls_FOUND)
|
||||||
|
set(USE_CRYPTO_GNUTLS ON)
|
||||||
|
set(FOUND_CRYPTO ON)
|
||||||
|
set(CRYPTO_PKG "${CRYPTO_PKG}, gnutls")
|
||||||
|
else()
|
||||||
|
find_path(GNUTLS_H_PATH gnutls/gnutls.h)
|
||||||
|
find_library(GNUTLS_LIB_PATH gnutls)
|
||||||
|
if(GNUTLS_H_PATH AND GNUTLS_LIB_PATH)
|
||||||
|
list(APPEND dep_include_directories ${GNUTLS_H_PATH})
|
||||||
|
list(APPEND dep_link_libraries ${GNUTLS_LIB_PATH})
|
||||||
|
set(USE_CRYPTO_GNUTLS ON)
|
||||||
|
set(FOUND_CRYPTO ON)
|
||||||
|
elseif(REQUIRE_CRYPTO_GNUTLS)
|
||||||
|
message(SEND_ERROR "gnutls not found")
|
||||||
|
set(ANYTHING_MISSING 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(REQUIRE_CRYPTO_NATIVE)
|
||||||
|
set(USE_CRYPTO_NATIVE ON)
|
||||||
|
set(FOUND_CRYPTO ON)
|
||||||
|
elseif(USE_IMPLICIT_CRYPTO)
|
||||||
|
if(ALLOW_CRYPTO_NATIVE AND (NOT FOUND_CRYPTO))
|
||||||
|
set(USE_CRYPTO_NATIVE ON)
|
||||||
|
set(FOUND_CRYPTO ON)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(FOUND_CRYPTO)
|
||||||
|
if(NOT DEFAULT_CRYPTO)
|
||||||
|
# The preferred order of crypto providers is documented in
|
||||||
|
# manual/installation.rst in the crypto.build section.
|
||||||
|
if(USE_CRYPTO_GNUTLS)
|
||||||
|
set(DEFAULT_CRYPTO "gnutls")
|
||||||
|
elseif(USE_CRYPTO_OPENSSL)
|
||||||
|
set(DEFAULT_CRYPTO "openssl")
|
||||||
|
else()
|
||||||
|
set(DEFAULT_CRYPTO "native")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "no crypto provider is available")
|
||||||
|
set(ANYTHING_MISSING 1)
|
||||||
|
endif()
|
||||||
|
if(ANYTHING_MISSING)
|
||||||
|
message(FATAL_ERROR "Missing dependencies; unable to continue")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "")
|
||||||
|
message(STATUS "*** Crypto Summary ***")
|
||||||
|
message(STATUS " GNU TLS crypto enabled: " ${USE_CRYPTO_GNUTLS})
|
||||||
|
message(STATUS " OpenSSL crypto enabled: " ${USE_CRYPTO_OPENSSL})
|
||||||
|
message(STATUS " Native crypto enabled: " ${USE_CRYPTO_NATIVE})
|
||||||
|
message(STATUS " Default crypto: " ${DEFAULT_CRYPTO})
|
||||||
|
message(STATUS "")
|
||||||
|
|
||||||
|
if(USE_CRYPTO_OPENSSL)
|
||||||
|
list(APPEND libqpdf_SOURCES ${libqpdf_crypto_openssl})
|
||||||
|
if(NOT EXTERNAL_LIBS)
|
||||||
|
list(APPEND dep_include_directories ${pc_openssl_INCLUDEDIR})
|
||||||
|
list(APPEND dep_link_directories ${pc_openssl_LIBDIR})
|
||||||
|
list(APPEND dep_link_libraries ${pc_openssl_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(USE_CRYPTO_GNUTLS)
|
||||||
|
list(APPEND libqpdf_SOURCES ${libqpdf_crypto_gnutls})
|
||||||
|
list(APPEND dep_include_directories ${pc_gnutls_INCLUDEDIR})
|
||||||
|
list(APPEND dep_link_directories ${pc_gnutls_LIBDIR})
|
||||||
|
list(APPEND dep_link_libraries ${pc_gnutls_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
if(USE_CRYPTO_NATIVE)
|
||||||
|
list(APPEND libqpdf_SOURCES ${libqpdf_crypto_native})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
# 2022: in CI (GitHub actions), pkg-config for zlib was adding a
|
||||||
|
# broken directory to the include path. This effectively filters it
|
||||||
|
# out.
|
||||||
|
list(FILTER dep_include_directories EXCLUDE REGEX "^/Library/")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(REMOVE_DUPLICATES dep_include_directories)
|
||||||
|
list(REMOVE_DUPLICATES dep_link_directories)
|
||||||
|
list(REMOVE_DUPLICATES dep_link_libraries)
|
||||||
|
|
||||||
|
check_type_size(size_t SIZEOF_SIZE_T)
|
||||||
|
check_include_file("inttypes.h" HAVE_INTTYPES_H)
|
||||||
|
check_symbol_exists(fseeko "stdio.h" HAVE_FSEEKO)
|
||||||
|
check_symbol_exists(fseeko64 "stdio.h" HAVE_FSEEKO64)
|
||||||
|
check_symbol_exists(localtime_r "time.h" HAVE_LOCALTIME_R)
|
||||||
|
check_symbol_exists(random "stdlib.h" HAVE_RANDOM)
|
||||||
|
find_file(RANDOM_DEVICE
|
||||||
|
"urandom" "arandom" "arandom" PATHS "/dev" NO_DEFAULT_PATH)
|
||||||
|
|
||||||
|
check_c_source_compiles(
|
||||||
|
"#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
tzset();
|
||||||
|
printf(\"%ld\", timezone);
|
||||||
|
return 0;
|
||||||
|
}"
|
||||||
|
HAVE_EXTERN_LONG_TIMEZONE)
|
||||||
|
|
||||||
|
check_c_source_compiles(
|
||||||
|
"#include <time.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
struct tm tm;
|
||||||
|
tm.tm_gmtoff = 1;
|
||||||
|
return 0;
|
||||||
|
}"
|
||||||
|
HAVE_EXTERN_TM_GMTOFF)
|
||||||
|
|
||||||
|
check_c_source_compiles(
|
||||||
|
"#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
int a[sizeof(off_t) >= 8 ? 1 : -1];
|
||||||
|
}"
|
||||||
|
LFS_WITHOUT_MACROS)
|
||||||
|
|
||||||
|
check_c_source_compiles(
|
||||||
|
"#define _FILE_OFFSET_BITS 64
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
int a[sizeof(off_t) >= 8 ? 1 : -1];
|
||||||
|
}"
|
||||||
|
LFS_WITH_MACROS)
|
||||||
|
if(LFS_WITH_MACROS AND NOT LFS_WITHOUT_MACROS)
|
||||||
|
set(_FILE_OFFSET_BITS 64)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function(qpdf_check_ll_fmt fmt var)
|
||||||
|
if(NOT DEFINED LL_FMT)
|
||||||
|
check_c_source_runs(
|
||||||
|
"#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
long long int a = 123456789012345ll;
|
||||||
|
char s[30];
|
||||||
|
sprintf(s, \"${fmt}\", a);
|
||||||
|
return (strcmp(s, \"123456789012345\") == 0) ? 0 : 1;
|
||||||
|
}" ${var})
|
||||||
|
if(${var})
|
||||||
|
set(LL_FMT "${fmt}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
qpdf_check_ll_fmt("%lld" fmt_lld)
|
||||||
|
qpdf_check_ll_fmt("%I64d" fmt_i64d)
|
||||||
|
qpdf_check_ll_fmt("%I64lld" fmt_i64lld)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/qpdf/qpdf-config.h.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/qpdf/qpdf-config.h"
|
||||||
|
NEWLINE_STYLE UNIX)
|
||||||
|
|
||||||
|
if(NOT BUILD_STATIC_LIBS)
|
||||||
|
set(OBJECT_LIB_IS_PIC ON)
|
||||||
|
else()
|
||||||
|
set(OBJECT_LIB_IS_PIC OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build an "object library" for use in libtests so we don't have to
|
||||||
|
# export symbols that are not officially part of the public API. If we
|
||||||
|
# are building static libraries, the object library won't use
|
||||||
|
# position-independent code and will provided objects for the static
|
||||||
|
# library. If we are only building the shared library, go ahead and
|
||||||
|
# use PIC for the object library so we don't have to compile twice.
|
||||||
|
set(OBJECT_LIB libqpdf_object)
|
||||||
|
add_library(${OBJECT_LIB} OBJECT ${libqpdf_SOURCES})
|
||||||
|
set_target_properties(${OBJECT_LIB} PROPERTIES
|
||||||
|
POSITION_INDEPENDENT_CODE ${OBJECT_LIB_IS_PIC})
|
||||||
|
target_include_directories(${OBJECT_LIB}
|
||||||
|
SYSTEM PRIVATE ${dep_include_directories})
|
||||||
|
target_include_directories(${OBJECT_LIB}
|
||||||
|
PUBLIC
|
||||||
|
${JPEG_INCLUDE}
|
||||||
|
${qpdf_INCLUDE}
|
||||||
|
${qpdf_SOURCE_DIR}/libqpdf
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
target_link_directories(${OBJECT_LIB} INTERFACE ${dep_link_directories})
|
||||||
|
target_link_libraries(${OBJECT_LIB} INTERFACE ${dep_link_libraries})
|
||||||
|
|
||||||
|
set(LD_VERSION_FLAGS "")
|
||||||
|
function(ld_version_script)
|
||||||
|
# Check if the linker supports linker scripts, and use if it does.
|
||||||
|
# This functionality is currently constrained to compilers using GNU
|
||||||
|
# ld on ELF systems or systems that emulation this behavior.
|
||||||
|
set(ld_script
|
||||||
|
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/qpdf-tmp/conftest.map")
|
||||||
|
file(WRITE ${ld_script}
|
||||||
|
"VERS_1 {
|
||||||
|
global: sym;
|
||||||
|
};
|
||||||
|
|
||||||
|
VERS_2 {
|
||||||
|
global: sym;
|
||||||
|
} VERS_1;
|
||||||
|
")
|
||||||
|
set(CMAKE_REQUIRED_LINK_OPTIONS -Wl,--version-script=${ld_script})
|
||||||
|
check_c_source_compiles("int main() { return 0; }" HAVE_LD_SCRIPT)
|
||||||
|
if(HAVE_LD_SCRIPT)
|
||||||
|
set(LD_VERSION_FLAGS
|
||||||
|
-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libqpdf.map PARENT_SCOPE)
|
||||||
|
configure_file(
|
||||||
|
"${qpdf_SOURCE_DIR}/libqpdf.map.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/libqpdf.map"
|
||||||
|
NEWLINE_STYLE UNIX)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
if(NOT WIN32)
|
||||||
|
ld_version_script()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
add_compile_definitions(DLL_EXPORT)
|
||||||
|
|
||||||
|
set(SHARED_LIB libqpdf)
|
||||||
|
if(OBJECT_LIB_IS_PIC)
|
||||||
|
add_library(${SHARED_LIB} SHARED $<TARGET_OBJECTS:libqpdf_object>)
|
||||||
|
else()
|
||||||
|
add_library(${SHARED_LIB} SHARED ${libqpdf_SOURCES})
|
||||||
|
endif()
|
||||||
|
if(WIN32)
|
||||||
|
# Goal: the DLL import library should be libqpdf.a or qpdf.lib so
|
||||||
|
# that linking with -lqpdf gets you a shared library link on all
|
||||||
|
# platforms. The DLL should be qpdf${SONAME}.dll rather than just
|
||||||
|
# qpdf.dll. qpdf has always done this, and it gives us some
|
||||||
|
# protection against binary incompatible DLLs being installed.
|
||||||
|
set(SHARED_OUT qpdf${qpdf_SOVERSION}) # Put API version number in DLL
|
||||||
|
if(MINGW)
|
||||||
|
# Reference: Platform/Windows-GNU.cmake in the cmake installation
|
||||||
|
set(CMAKE_SHARED_LIBRARY_PREFIX "") # libqpdf$v.dll -> qpdf$v.dll
|
||||||
|
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a") # libqpdf.dll.a -> libqpdf.a
|
||||||
|
endif()
|
||||||
|
if(MSVC)
|
||||||
|
# Avoid linker warning from mixing libraries built with /MT and /MD.
|
||||||
|
set_target_properties(${SHARED_LIB}
|
||||||
|
PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(SHARED_OUT qpdf)
|
||||||
|
endif()
|
||||||
|
# Setting OUTPUT_NAME and ARCHIVE_OUTPUT_NAME separate enables us to
|
||||||
|
# have a versioned DLL and an unversioned import library, which
|
||||||
|
# gives us semantics similar to ELF shared libraries and makes
|
||||||
|
# linking against qpdf the same across all platforms.
|
||||||
|
set_target_properties(${SHARED_LIB} PROPERTIES
|
||||||
|
OUTPUT_NAME ${SHARED_OUT}
|
||||||
|
ARCHIVE_OUTPUT_NAME qpdf
|
||||||
|
VERSION ${qpdf_LIBVERSION}
|
||||||
|
SOVERSION ${qpdf_SOVERSION}
|
||||||
|
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})
|
||||||
|
|
||||||
|
target_include_directories(${SHARED_LIB}
|
||||||
|
SYSTEM PRIVATE ${dep_include_directories})
|
||||||
|
target_include_directories(${SHARED_LIB}
|
||||||
|
PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${qpdf_INCLUDE}>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
target_link_directories(${SHARED_LIB} PRIVATE ${dep_link_directories})
|
||||||
|
target_link_libraries(${SHARED_LIB} PRIVATE ${dep_link_libraries})
|
||||||
|
if(LD_VERSION_FLAGS)
|
||||||
|
target_link_options(${SHARED_LIB} PRIVATE ${LD_VERSION_FLAGS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(${SHARED_LIB}
|
||||||
|
PRIVATE ${qpdf_SOURCE_DIR}/libqpdf ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
install(TARGETS ${SHARED_LIB}
|
||||||
|
EXPORT libqpdfTargets
|
||||||
|
TYPE LIBRARY
|
||||||
|
COMPONENT ${COMPONENT_LIB}
|
||||||
|
NAMELINK_COMPONENT ${COMPONENT_DEV}
|
||||||
|
INCLUDES ${qpdf_INCLUDE})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_STATIC_LIBS)
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
set(STATIC_LIB libqpdf_static)
|
||||||
|
else()
|
||||||
|
set(STATIC_LIB libqpdf)
|
||||||
|
endif()
|
||||||
|
if(OBJECT_LIB_IS_PIC)
|
||||||
|
add_library(${STATIC_LIB} STATIC ${libqpdf_SOURCES})
|
||||||
|
else()
|
||||||
|
add_library(${STATIC_LIB} STATIC $<TARGET_OBJECTS:libqpdf_object>)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(${STATIC_LIB}
|
||||||
|
SYSTEM PRIVATE ${dep_include_directories})
|
||||||
|
target_include_directories(${STATIC_LIB}
|
||||||
|
PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${qpdf_INCLUDE}>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
target_link_directories(${STATIC_LIB}
|
||||||
|
INTERFACE $<BUILD_INTERFACE:${dep_link_directories}>
|
||||||
|
PRIVATE $<INSTALL_INTERFACE:${dep_link_directories}>)
|
||||||
|
target_link_libraries(${STATIC_LIB} INTERFACE ${dep_link_libraries})
|
||||||
|
|
||||||
|
# Avoid name clashes on Windows with the the DLL import library.
|
||||||
|
if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS)
|
||||||
|
if (WIN32)
|
||||||
|
set(STATIC_SUFFIX "_static")
|
||||||
|
else()
|
||||||
|
set(STATIC_SUFFIX "")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_target_properties(${STATIC_LIB} PROPERTIES
|
||||||
|
OUTPUT_NAME qpdf${STATIC_SUFFIX}
|
||||||
|
VERSION ${PROJECT_VERSION})
|
||||||
|
target_include_directories(${STATIC_LIB}
|
||||||
|
PRIVATE ${qpdf_SOURCE_DIR}/libqpdf ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
install(TARGETS ${STATIC_LIB}
|
||||||
|
EXPORT libqpdfTargets
|
||||||
|
TYPE ARCHIVE
|
||||||
|
COMPONENT ${COMPONENT_DEV}
|
||||||
|
INCLUDES ${qpdf_INCLUDE})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${qpdf_SOURCE_DIR}/libqpdf.pc.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/libqpdf.pc"
|
||||||
|
@ONLY NEWLINE_STYLE UNIX)
|
||||||
|
if(INSTALL_PKGCONFIG)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libqpdf.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||||
|
COMPONENT ${COMPONENT_DEV})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(INSTALL_CMAKE_PACKAGE)
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
configure_package_config_file(
|
||||||
|
${qpdf_SOURCE_DIR}/qpdfConfig.cmake.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/qpdfConfig.cmake
|
||||||
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpdf)
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/qpdfConfigVersion.cmake"
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
COMPATIBILITY SameMajorVersion)
|
||||||
|
install(EXPORT libqpdfTargets
|
||||||
|
NAMESPACE qpdf::
|
||||||
|
FILE libqpdfTargets.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpdf)
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/qpdfConfigVersion.cmake
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/qpdfConfig.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpdf)
|
||||||
|
endif()
|
53
libtests/CMakeLists.txt
Normal file
53
libtests/CMakeLists.txt
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
set(TEST_PROGRAMS
|
||||||
|
cxx11
|
||||||
|
aes
|
||||||
|
arg_parser
|
||||||
|
ascii85
|
||||||
|
bits
|
||||||
|
buffer
|
||||||
|
closed_file_input_source
|
||||||
|
concatenate
|
||||||
|
dct_compress
|
||||||
|
dct_uncompress
|
||||||
|
flate
|
||||||
|
hex
|
||||||
|
input_source
|
||||||
|
json
|
||||||
|
json_handler
|
||||||
|
json_parse
|
||||||
|
lzw
|
||||||
|
main_from_wmain
|
||||||
|
matrix
|
||||||
|
md5
|
||||||
|
nntree
|
||||||
|
numrange
|
||||||
|
pdf_version
|
||||||
|
pointer_holder
|
||||||
|
predictors
|
||||||
|
qintc
|
||||||
|
qutil
|
||||||
|
random
|
||||||
|
rc4
|
||||||
|
runlength
|
||||||
|
sha2
|
||||||
|
sparse_array)
|
||||||
|
foreach(PROG ${TEST_PROGRAMS})
|
||||||
|
add_executable(${PROG} ${PROG}.cc)
|
||||||
|
target_link_libraries(${PROG} libqpdf_object)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Since libtests link with the object library and don't use the DLL,
|
||||||
|
# we don't need to (and shouldn't) add the libqpdf target directory to
|
||||||
|
# the path for libtests.
|
||||||
|
add_test(
|
||||||
|
NAME libtests
|
||||||
|
COMMAND ${RUN_QTEST}
|
||||||
|
--top ${qpdf_SOURCE_DIR}
|
||||||
|
--bin $<TARGET_FILE_DIR:qutil>
|
||||||
|
--bin $<TARGET_FILE_DIR:qpdf>
|
||||||
|
--code ${qpdf_SOURCE_DIR}/libtests
|
||||||
|
--color ${QTEST_COLOR}
|
||||||
|
--show-on-failure ${SHOW_FAILED_TEST_OUTPUT}
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/libtests/*.cc"
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/libqpdf/*.cc"
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/libqpdf/qpdf/bits_functions.hh")
|
133
manual/CMakeLists.txt
Normal file
133
manual/CMakeLists.txt
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# There is a FindLATEX module, but it does some things we don't care
|
||||||
|
# about and doesn't do everything we need.
|
||||||
|
find_program(LATEX latex)
|
||||||
|
find_program(PDFLATEX pdflatex)
|
||||||
|
find_program(LATEXMK latexmk)
|
||||||
|
find_program(SPHINX sphinx-build)
|
||||||
|
|
||||||
|
# *** NOTE: Never check BUILD_DOC_PDF if BUILD_DOC is not set. See
|
||||||
|
# *** comments in top-level CMakeLists.txt.
|
||||||
|
|
||||||
|
if(BUILD_DOC)
|
||||||
|
if(SPHINX STREQUAL SPHINX-NOTFOUND)
|
||||||
|
message(FATAL_ERROR "sphinx-build is required for building documentation")
|
||||||
|
endif()
|
||||||
|
if(BUILD_DOC_PDF AND
|
||||||
|
((LATEX STREQUAL LATEX-NOTFOUND) OR
|
||||||
|
(LATEXMK STREQUAL LATEXMK-NOTFOUND) OR
|
||||||
|
(PDFLATEX STREQUAL PDFLATEX-NOTFOUND)))
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"latex, latexmk, and pdflatex are required to build PDF documentation")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(MANUAL_SRC ${qpdf_SOURCE_DIR}/manual)
|
||||||
|
foreach(F qpdf.1 fix-qdf.1 zlib-flate.1)
|
||||||
|
configure_file(
|
||||||
|
${MANUAL_SRC}/${F}.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/${F}
|
||||||
|
NEWLINE_STYLE UNIX)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
SET(MANUAL_DEPS
|
||||||
|
conf.py
|
||||||
|
_ext/qpdf.py
|
||||||
|
acknowledgement.rst
|
||||||
|
cli.rst
|
||||||
|
design.rst
|
||||||
|
download.rst
|
||||||
|
encryption.rst
|
||||||
|
index.rst
|
||||||
|
installation.rst
|
||||||
|
json.rst
|
||||||
|
library.rst
|
||||||
|
license.rst
|
||||||
|
linearization.rst
|
||||||
|
object-streams.rst
|
||||||
|
overview.rst
|
||||||
|
packaging.rst
|
||||||
|
qdf.rst
|
||||||
|
qpdf-job.rst
|
||||||
|
release-notes.rst
|
||||||
|
weak-crypto.rst)
|
||||||
|
|
||||||
|
# Prevent targets that run ${SPHINX} from running in parallel by using
|
||||||
|
# dependencies. This avoids clashes in temporary files that cause the
|
||||||
|
# build to fail with the error "_pickle.UnpicklingError: pickle data
|
||||||
|
# was truncated". It would be better if we could use order-only
|
||||||
|
# dependencies like gnu make to make it possible to build the targets
|
||||||
|
# independently.
|
||||||
|
set(DOC_HTML_OUTPUT html/index.html)
|
||||||
|
set(DOC_SINGLEHTML_OUTPUT singlehtml/index.html)
|
||||||
|
set(DOC_PDF_OUTPUT latex/qpdf.pdf)
|
||||||
|
if(BUILD_DOC)
|
||||||
|
add_custom_command(OUTPUT ${DOC_HTML_OUTPUT}
|
||||||
|
COMMAND ${SPHINX} -M html ${MANUAL_SRC} ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMAND touch ${DOC_HTML_OUTPUT}
|
||||||
|
DEPENDS ${MANUAL_DEPS})
|
||||||
|
add_custom_command(OUTPUT ${DOC_SINGLEHTML_OUTPUT}
|
||||||
|
COMMAND ${SPHINX} -M singlehtml ${MANUAL_SRC} ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMAND touch ${DOC_SINGLEHTML_OUTPUT}
|
||||||
|
DEPENDS ${MANUAL_DEPS})
|
||||||
|
add_custom_command(OUTPUT ${DOC_PDF_OUTPUT}
|
||||||
|
COMMAND ${SPHINX} -M latexpdf ${MANUAL_SRC} ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMAND touch ${DOC_PDF_OUTPUT}
|
||||||
|
DEPENDS ${MANUAL_DEPS})
|
||||||
|
add_custom_target(doc_html DEPENDS ${DOC_HTML_OUTPUT})
|
||||||
|
add_custom_target(doc_singlehtml DEPENDS ${DOC_SINGLEHTML_OUTPUT})
|
||||||
|
add_dependencies(doc_singlehtml doc_html)
|
||||||
|
add_custom_target(doc_pdf DEPENDS ${DOC_PDF_OUTPUT})
|
||||||
|
add_custom_target(doc ALL)
|
||||||
|
if(BUILD_DOC_PDF)
|
||||||
|
add_dependencies(doc doc_pdf)
|
||||||
|
if(BUILD_DOC_HTML)
|
||||||
|
add_dependencies(doc_pdf doc_singlehtml)
|
||||||
|
endif()
|
||||||
|
elseif(BUILD_DOC_HTML)
|
||||||
|
add_dependencies(doc doc_singlehtml)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_DOC_DIST)
|
||||||
|
set(DOC_DIST_HTML doc-dist/manual-html)
|
||||||
|
set(DOC_DIST_SINGLEHTML doc-dist/manual-single-page-html)
|
||||||
|
set(DOC_DIST_PDF doc-dist/qpdf-manual.pdf)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${DOC_DIST_HTML}
|
||||||
|
${DOC_DIST_SINGLEHTML}
|
||||||
|
${DOC_DIST_PDF}
|
||||||
|
COMMAND rm -rf doc-dist
|
||||||
|
COMMAND mkdir -p doc-dist
|
||||||
|
COMMAND cp -r html ${DOC_DIST_HTML}
|
||||||
|
COMMAND cp -r singlehtml ${DOC_DIST_SINGLEHTML}
|
||||||
|
COMMAND cp -r ${DOC_PDF_OUTPUT} ${DOC_DIST_PDF}
|
||||||
|
DEPENDS ${DOC_HTML_OUTPUT} ${DOC_SINGLEHTML_OUTPUT} ${DOC_PDF_OUTPUT})
|
||||||
|
add_custom_target(doc_dist ALL
|
||||||
|
DEPENDS ${DOC_DIST_HTML} ${DOC_DIST_SINGLEHTML} ${DOC_DIST_PDF})
|
||||||
|
add_dependencies(doc_dist doc)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# INSTALL_MANUAL is not dependent on building doc -- we sometimes drop in
|
||||||
|
# pre-built doc when creating distributions.
|
||||||
|
if(INSTALL_MANUAL)
|
||||||
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-dist/
|
||||||
|
TYPE DOC
|
||||||
|
COMPONENT ${COMPONENT_DOC})
|
||||||
|
else()
|
||||||
|
install(FILES ${qpdf_SOURCE_DIR}/README-doc.txt
|
||||||
|
TYPE DOC
|
||||||
|
COMPONENT ${COMPONENT_DOC})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
# There's no reason to install manual pages in a Windows
|
||||||
|
# environment, especially when all they do is refer people to the
|
||||||
|
# manual.
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/qpdf.1
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/fix-qdf.1
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/zlib-flate.1
|
||||||
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
|
||||||
|
COMPONENT ${COMPONENT_DOC})
|
||||||
|
endif()
|
78
qpdf/CMakeLists.txt
Normal file
78
qpdf/CMakeLists.txt
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
set(MAIN_CXX_PROGRAMS
|
||||||
|
qpdf
|
||||||
|
fix-qdf
|
||||||
|
pdf_from_scratch
|
||||||
|
test_driver
|
||||||
|
test_large_file
|
||||||
|
test_parsedoffset
|
||||||
|
test_pdf_doc_encoding
|
||||||
|
test_pdf_unicode
|
||||||
|
test_renumber
|
||||||
|
test_shell_glob
|
||||||
|
test_tokenizer
|
||||||
|
test_unicode_filenames
|
||||||
|
test_xref)
|
||||||
|
set(MAIN_C_PROGRAMS
|
||||||
|
qpdf-ctest
|
||||||
|
qpdfjob-ctest)
|
||||||
|
|
||||||
|
foreach(PROG ${MAIN_CXX_PROGRAMS})
|
||||||
|
add_executable(${PROG} ${PROG}.cc)
|
||||||
|
target_link_libraries(${PROG} libqpdf)
|
||||||
|
endforeach()
|
||||||
|
foreach(PROG ${MAIN_C_PROGRAMS})
|
||||||
|
add_executable(${PROG} ${PROG}.c)
|
||||||
|
target_link_libraries(${PROG} libqpdf)
|
||||||
|
set_property(TARGET ${PROG} PROPERTY LINKER_LANGUAGE CXX)
|
||||||
|
endforeach()
|
||||||
|
target_include_directories(qpdf-ctest PRIVATE ${CMAKE_BINARY_DIR}/libqpdf)
|
||||||
|
|
||||||
|
foreach(B qpdf test_unicode_filenames fix-qdf test_shell_glob)
|
||||||
|
if(WINDOWS_WMAIN_COMPILE)
|
||||||
|
target_compile_options(${B} PRIVATE ${WINDOWS_WMAIN_COMPILE})
|
||||||
|
endif()
|
||||||
|
if(WINDOWS_WMAIN_LINK)
|
||||||
|
target_link_options(${B} PRIVATE ${WINDOWS_WMAIN_LINK})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME qpdf
|
||||||
|
COMMAND ${RUN_QTEST}
|
||||||
|
--top ${qpdf_SOURCE_DIR}
|
||||||
|
--bin $<TARGET_FILE_DIR:qpdf>
|
||||||
|
--bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL
|
||||||
|
--code ${qpdf_SOURCE_DIR}/qpdf
|
||||||
|
--color ${QTEST_COLOR}
|
||||||
|
--show-on-failure ${SHOW_FAILED_TEST_OUTPUT}
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/qpdf/*.cc"
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/qpdf/*.c"
|
||||||
|
--tc "${qpdf_SOURCE_DIR}/libqpdf/*.cc")
|
||||||
|
|
||||||
|
install(TARGETS qpdf fix-qdf
|
||||||
|
TYPE RUNTIME
|
||||||
|
COMPONENT ${COMPONENT_CLI})
|
||||||
|
|
||||||
|
if(MINGW)
|
||||||
|
# For MSVC, including InstallRequiredSystemLibraries in the
|
||||||
|
# top-level CMakeLists.txt is sufficient. For mingw, we have to copy
|
||||||
|
# mingw libraries in ourselves.
|
||||||
|
set(ONE_GNU_DLL extra-dlls/libstdc++-6.dll)
|
||||||
|
add_custom_command(OUTPUT ${ONE_GNU_DLL}
|
||||||
|
COMMAND
|
||||||
|
perl ${qpdf_SOURCE_DIR}/copy_dlls
|
||||||
|
qpdf.exe
|
||||||
|
${CMAKE_BINARY_DIR}/libqpdf
|
||||||
|
extra-dlls)
|
||||||
|
add_custom_target(extra_dlls ALL DEPENDS ${ONE_GNU_DLL})
|
||||||
|
add_dependencies(extra_dlls qpdf)
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
set(EXTRA_DLL_COMPONENT ${COMPONENT_LIB})
|
||||||
|
else()
|
||||||
|
set(EXTRA_DLL_COMPONENT ${COMPONENT_CLI})
|
||||||
|
endif()
|
||||||
|
# The trailing / prevents "extra-dlls" from being created in bin.
|
||||||
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/extra-dlls/
|
||||||
|
TYPE BIN
|
||||||
|
COMPONENT ${EXTRA_DLL_COMPONENT})
|
||||||
|
endif()
|
2
qpdfConfig.cmake.in
Normal file
2
qpdfConfig.cmake.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@PACKAGE_INIT@
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/libqpdfTargets.cmake")
|
16
zlib-flate/CMakeLists.txt
Normal file
16
zlib-flate/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
add_executable(zlib-flate zlib-flate.cc)
|
||||||
|
target_link_libraries(zlib-flate libqpdf)
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME zlib-flate
|
||||||
|
COMMAND ${RUN_QTEST}
|
||||||
|
--top ${qpdf_SOURCE_DIR}
|
||||||
|
--bin $<TARGET_FILE_DIR:zlib-flate>
|
||||||
|
--bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL
|
||||||
|
--code ${qpdf_SOURCE_DIR}/zlib-flate
|
||||||
|
--color ${QTEST_COLOR}
|
||||||
|
--show-on-failure ${SHOW_FAILED_TEST_OUTPUT})
|
||||||
|
|
||||||
|
install(TARGETS zlib-flate
|
||||||
|
TYPE RUNTIME
|
||||||
|
COMPONENT ${COMPONENT_CLI})
|
Loading…
Reference in New Issue
Block a user