From f58d2a60d57653071609a0a9ec0d693c6bda0024 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 12 Mar 2022 17:32:05 -0500 Subject: [PATCH] Update build-related documentation and comments --- README-maintainer | 150 ++++---- README-what-to-download.md | 12 +- README-windows.md | 83 +---- README.md | 91 +++-- TODO | 9 +- cSpell.json | 7 + manual/installation.rst | 719 ++++++++++++++++++++++++++++--------- manual/library.rst | 18 +- manual/packaging.rst | 71 ++-- qpdf/qtest/qpdf.test | 5 +- 10 files changed, 744 insertions(+), 421 deletions(-) diff --git a/README-maintainer b/README-maintainer index 9b5e4a89..2a84be3f 100644 --- a/README-maintainer +++ b/README-maintainer @@ -15,7 +15,8 @@ cmake -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 \ Profiling: CFLAGS=-pg LDFLAGS=-pg \ - cmake -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 -DCMAKE_BUILD_TYPE=Debug .. + cmake -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 \ + -DCMAKE_BUILD_TYPE=Debug .. Then run `gprof gmon.out`. Note that gmon.out is not cumulative. @@ -25,12 +26,17 @@ CFLAGS="-fsanitize=address -fsanitize=undefined" \ CXXFLAGS="-fsanitize=address -fsanitize=undefined" \ LDFLAGS="-fsanitize=address -fsanitize=undefined" \ CC=clang CXX=clang++ \ - cmake -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 -DCMAKE_BUILD_TYPE=Debug .. + cmake -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 \ + -DCMAKE_BUILD_TYPE=Debug .. Windows: ../cmake-win {mingw|msvc} maint +See ./build-scripts for other ways to run the build for different +configurations. + + VERSIONS * The version number on the main branch is whatever the version would @@ -249,53 +255,20 @@ RELEASE PREPARATION * Run a spelling checker over the source code to catch errors in variable names, strings, and comments. - make spell CLEAN=1 + ./spell-check This uses cspell. Install with `npm install -g cspell`. The output of cspell is suitable for use with `M-x grep` in emacs. Add exceptions to cSpell.json. -* If needed, run large file and image comparison tests. Configure - options: +* If needed, run large file and image comparison tests by setting + these environment variables: ---enable-test-compare-images --with-large-file-test-path=/path + QPDF_LARGE_FILE_TEST_PATH=/full/path + QPDF_TEST_COMPARE_IMAGES=1 For Windows, use a Windows style path, not an MSYS path for large files. -* Test with clang. Pass `CC=clang CXX=clang++` to `./configure`. (Done - in CI). - -* Test with newer version of gcc if available. - -* Test 32-bit. Pass `CC=i686-linux-gnu-gcc CXX=i686-linux-gnu-g++` to - `./configure`. (Done in CI.) - -* Test build on a mac. (Done in CI.) - -* Test with address sanitizer as described above. (Done in CI.) - -* A small handful of additional files have been taken from autotools - programs. These should probably be updated from time to time. - - * `config.guess`, `config.sub`, `ltmain.sh`, and the `m4` directory: - these were created by running `libtoolize -c`. To update, run - `libtoolize -f -c` or remove the files and rerun `libtoolize`. For - `config.guess` and `config.sub`, search for "latest" in the files, - and follow directions for updating them. - - * Other files copied as indicated: - ``` - cp /usr/share/automake-1.16/install-sh . - cp /usr/share/automake-1.16/mkinstalldirs . - cp /usr/share/aclocal/pkg.m4 m4 - ``` - - The entire contents of the `m4` directory came from `libtool.m4`. If - we had some additional local parts, we could also add those to the - `m4` directory. In order for this to work, it is necessary to run - `aclocal -I m4` before running `autoheader` and `autoconf`. The - `autogen.sh` script handles this. - * If any interfaces were added or changed, check C API to see whether changes are appropriate there as well. If necessary, review the casting policy in the manual, and ensure that integer types are @@ -306,17 +279,12 @@ RELEASE PREPARATION * Double check versions and shared library details. They should already be up to date in the code. - * Increment shared library version information as needed - (`LT_CURRENT` in `configure.ac`) - * Make sure version numbers are consistent in the following locations: - * configure.ac + * CMakeLists.txt * include/qpdf/DLL.h * manual/conf.py `make_dist` verifies this consistency. - * Run ./autogen.sh - * Update release notes in manual. Look at diffs and ChangeLog. Update release date in `manual/release-notes.rst`. @@ -330,15 +298,24 @@ RELEASE PREPARATION * Test for performance and binary compatibility: * Check out the last release - * ./configure --enable-werror && make -j$(nproc) + * cmake -S . -B build \ + -DMAINTAINER_MODE=1 -DBUILD_STATIC_LIBS=0 -DBUILD_DOC=0 \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo + * cmake --build build -j$(nproc) * Check out the current version * ./performance_check | tee -a /tmp/perf - * ./configure --enable-werror && make -j$(nproc) build_libqpdf + * cmake -S . -B build \ + -DMAINTAINER_MODE=1 -DBUILD_STATIC_LIBS=0 -DBUILD_DOC=0 \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo + * cmake --build build -j$(nproc) --target libqpdf * Checkout the last release - * make -k check NO_REBUILD=1 (some failures are normal -- looking - for binary compatibility) + * (cd build; ctest --verbose) + * (some failures are normal -- looking for binary compatibility) * Check out the current version - * make -j$(nproc) + * cmake -S . -B build \ + -DMAINTAINER_MODE=1 -DBUILD_STATIC_LIBS=0 -DBUILD_DOC=0 \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo + * cmake --build build -j$(nproc) * ./performance_check | tee -a /tmp/perf * Run pikepdf's test suite. Do this in a separate shell. @@ -363,7 +340,7 @@ CREATING A RELEASE * Push to main. This will create an artifact called distribution which will contain all the distribution files. Download these, verify the checksums from the job output, rename to remove -ci from - the names, and copy to the release archive area. + the names, and extract to the release archive area. * Sign the source distribution: @@ -375,9 +352,7 @@ gpg --detach-sign --armor qpdf-$version.tar.gz * Add a calendar reminder to check the status of the debian package to make sure it is transitioning properly and to resolve any issues. -* Sign the releases. The release archive area should contain the - Windows binaries, the AppImage, the source tarball, and the source - tarball signature. +* From the release archive area, sign the releases. \rm -f *.sha256 files=(*) @@ -467,40 +442,25 @@ Use -e SKIP_TESTS=1 to skip the test suite. Use -ti -e RUN_SHELL=1 to run a shell instead of the build script. -GENERAL BUILD STUFF - -QPDF uses autoconf and libtool but does not use automake. The only -files distributed with the qpdf source distribution that are not -controlled are `configure`, `libqpdf/qpdf/qpdf-config.h.in`, -`aclocal.m4`, and some documentation. See above for the steps required -to prepare a source distribution. - -If building or editing documentation, configure with -`--enable-doc-maintenance`. This will ensure that all tools or files -required to validate and build documentation are available. - -If you want to run `make maintainer-clean` or `make distclean` and you -haven't run `./configure`, you can pass `CLEAN=1` to make on the -command line to prevent it from complaining about configure not having -been run. - -If you want to run checks without rerunning the build, pass -`NO_REBUILD=1` to make. This can be useful for special testing -scenarios such as validation of memory fixes or binary compatibility. - - LOCAL WINDOWS TESTING PROCEDURE This is what I do for routine testing on Windows. -From Windows, git clone from my Linux clone, and unzip -`external-libs`. +* From Windows, git clone from my Linux clone, and unzip + `external-libs`. -Look at `make_windows_releases`. Set up path the same way and run -whichever `./config-*` is appropriate for whichever compiler I need to -test with. Start one of the Visual Studio native compiler shells, and -from there, run one of the msys shells. The Visual Studio step is not -necessary if just building with mingw. +* Start a command-line shell for x86_64 and x86 tools from Visual + studio. From there, start C:\msys64\mingw64 twice and + C:\msys64\mingw32 twice. + +* Create a build directory for each of the four permutations. Then, in + each build directory, run `../cmake-win maint`. + +* Run `cmake --build . -j4`. For MSVC, add `--config Release` + +* Test with with msvc: `ctest --verbose -C Release` + +* Test with mingw: `ctest --verbose -C RelWithDebInfo` DOCS ON readthedocs.org @@ -529,3 +489,25 @@ following branching strategy to support docs: The release process includes updating the approach branches and activating versions. + + +CMAKE notes + +To verify the various cmake options and their interactions, several +manual tests were done: + +* Break installed qpdf executables (qpdf, fix-qdf, zlib-flate), the + shared library, and DLL.h to ensure that other qpdf installations do + not interfere with building from source + +* Build static only and shared only + +* Install separate components separately + +* Build only HTML docs and only PDF docs + +* Try MAINTAINER_MODE without BUILD_DOC + +We are using RelWithDebInfo for mingw and other non-Windows builds but +Release for MSVC. There are linker warnings if MSVC is built with +RelWithDebInfo when using external-libs. diff --git a/README-what-to-download.md b/README-what-to-download.md index 767bdb88..c4abf6ac 100644 --- a/README-what-to-download.md +++ b/README-what-to-download.md @@ -4,13 +4,15 @@ Windows Binaries You can download Windows binaries that are statically linked with qpdf's external dependencies and use the OpenSSL crypto provider. There are several options: -* `qpdf--bin-mingw32.zip` - 32-bit executables that should work on basically any Windows system, including 64-bit systems. The 32-bit executables are capable of handling files larger than 2 GB. If you just want to use the qpdf command line program or use the qpdf DLL's C-language interface, you can download this file. You can also download this version if you are using MINGW's gcc and want to program using the C++ interface. +* For Windows installers, you can download the `.exe` file for a traditional installer that allows relocation, or you can download the `.zip` file which you can unzip to any location. -* `qpdf--bin-mingw64.zip` - A 64-bit version built with mingw. Use this for 64-bit Windows systems. The 32-bit version will also work on Windows 64-bit. Both the 32-bit and the 64-bit version support files over 2 GB in size, but you may find it easier to integrate this with your own software if you use the 64-bit version. +* `qpdf--bin-mingw32.exe` - 32-bit executables that should work on basically any Windows system, including 64-bit systems. The 32-bit executables are capable of handling files larger than 2 GB. If you just want to use the qpdf command line program or use the qpdf DLL's C-language interface, you can download this file. You can also download this version if you are using MINGW's gcc and want to program using the C++ interface. -* `qpdf--bin-msvc32.zip` - If you want to program using qpdf's C++ interface and you are using a recent version of Microsoft Visual C++ in 32-bit mode, you can download this file. +* `qpdf--bin-mingw64.exe` - A 64-bit version built with mingw. Use this for 64-bit Windows systems. The 32-bit version will also work on Windows 64-bit. Both the 32-bit and the 64-bit version support files over 2 GB in size, but you may find it easier to integrate this with your own software if you use the 64-bit version. -* `qpdf--bin-msvc64.zip` - If you want to program using qpdf's C++ interface and you are using a recent version of Microsoft Visual C++ in 64-bit mode, you can download this file. +* `qpdf--bin-msvc32.exe` - If you want to program using qpdf's C++ interface and you are using a recent version of Microsoft Visual C++ in 32-bit mode, you can download this file. + +* `qpdf--bin-msvc64.exe` - If you want to program using qpdf's C++ interface and you are using a recent version of Microsoft Visual C++ in 64-bit mode, you can download this file. Linux Binaries @@ -22,7 +24,7 @@ Virtually all Linux distributions include packages for qpdf. There is also a PPA Windows Build Support -If you are building on Windows and want to use pre-built external static libraries, you should obtain current versions from https://github.com/qpdf/external-libs/releases. The `external-libs` directory contains older versions that will not work with qpdf versions >= 10.0.2. Please see README-windows.md in the qpdf source distribution. +If you are building on Windows and want to use pre-built external static libraries, you should obtain current versions from https://github.com/qpdf/external-libs/releases. The `external-libs` directory contains older versions that will not work with qpdf versions >= 10.0.2. Please see README-windows.md in the qpdf source distribution. The libraries from this distribution will not work with a Debug build with MSVC. Documentation diff --git a/README-windows.md b/README-windows.md index 2b182123..06b474a8 100644 --- a/README-windows.md +++ b/README-windows.md @@ -3,7 +3,7 @@ Common Setup You may need to disable antivirus software to run qpdf's test suite. Running Windows Defender on Windows 10 does not interfere with building or running qpdf or its test suite. -To be able to build qpdf and run its test suite, you must have MSYS2 installed. This replaces the old process of having a mixture of msys, mingw-w64, and ActiveState perl. It is now possible to do everything with just MSYS2. +Starting with qpdf version 11, qpdf is built with cmake. You can build qpdf with Visual C++ in Release mode with the pre-built external-libraries distribution (described below) without having any additional tools installed. To run the test suite, you need MSYS2. Here's what I did on my system: @@ -11,20 +11,23 @@ Here's what I did on my system: * Run the installer. * Run msys2_shell.cmd by allowing the installer to start it. * From the prompt: - * Run `pacman -Syuu` and follow the instructions, which may tell you + * Run `pacman -Syu` and follow the instructions, which may tell you to close the window and rerun the command multiple times. + * Run `pacman -Su` to fully update. * `pacman -S make base-devel git zip unzip` * `pacman -S mingw-w64-x86_64-toolchain mingw-w64-i686-toolchain` -If you would like to build with Microsoft Visual C++, install a suitable Microsoft Visual Studio edition. In early 2016, 2015 community edition with C++ support is fine. It may crash a few times during installation, but repeating the installation will allow it to finish, and the resulting software is stable. +You need cmake. If you have Visual Studio installed, you can use the cmake that comes with it to build with both MSVC and mingw. You can also a install a native Windows cmake from cmake.org. -To build qpdf with Visual Studio, start the msys2 mingw32 or mingw64 shell from a command window started from one of the Visual Studio shell windows. You must use the mingw shell for the same word size (32 or 64 bit) as the Windows compiler since the MSVC build uses objdump from the msys distribution. You must also have it inherit the path. For example: +To build qpdf with Visual Studio from msys2 so you can run its test suite, start the msys2 mingw32 or mingw64 shell from a command window started from one of the Visual Studio shell windows. You must have it inherit the path. For example: * Start x64 native tools command prompt from msvc * `set MSYS2_PATH_TYPE=inherit` * `C:\msys64\mingw64` -Image comparison tests are disabled by default, but it is possible to run them on Windows. To do so, add `--enable-test-compare-images` from the configure statements given below and install some additional third-party dependencies. These may be provided in an environment such as MSYS or Cygwin or can be downloaded separately for other environments. You may extract or install the following software into separate folders each and add the `bin` folder to your `PATH` environment variable to make executables and DLLs available. If installers are provided, they might do that already by default. +For the test suite to work properly, your build directory must be on the same drive as your source directory. This is because there are parts of the test environment that create relative paths from one to the other. You can use a cross-drive symlink if needed. + +Image comparison tests are disabled by default, but it is possible to run them on Windows. To do so, set the `QPDF_TEST_COMPARE_IMAGES` environment variable to `1` and install the additional third-party dependencies described in the manual. These may be provided in an environment such as MSYS or Cygwin or can be downloaded separately for other environments. You may extract or install the following software into separate folders each and add the `bin` folder to your `PATH` environment variable to make executables and DLLs available. If installers are provided, they might do that already by default. * [LibJpeg](http://gnuwin32.sourceforge.net/packages/jpeg.htm): This archive provides some needed DLLs needed by LibTiff. * [LibTiff](http://gnuwin32.sourceforge.net/packages/tiff.htm): This archive provides some needed binaries and DLLs if you want to use the image comparison tests. It depends on some DLLs from LibJpeg. @@ -32,76 +35,16 @@ Image comparison tests are disabled by default, but it is possible to run them o # External Libraries -In order to build qpdf, you must have a copy of `zlib` and the `jpeg` library. You can download [prebuilt static external libraries from the qpdf/external-libs github repository](https://github.com/qpdf/external-libs/releases). These include `zlib`, `jpeg`, and `openssl` libraries. There are packages called `external-libs-bin.zip` and `external-libs-src.zip`. If you are building with a recent MSVC or MINGW with MSYS2, you can just extract the `qpdf-external-libs-bin.zip` zip file into the top-level qpdf source tree. Note that you need the 2020-10-24 version (at least) to build qpdf 10.0.2 or greater since this includes openssl. Passing `--enable-external-libs` to `./configure` (which is done automatically if you follow the instructions below) is sufficient to find them. +In order to build qpdf, you must have a copy of `zlib` and the `jpeg` library. You can download [prebuilt static external libraries from the qpdf/external-libs github repository](https://github.com/qpdf/external-libs/releases). These include `zlib`, `jpeg`, and `openssl` libraries. For MSVC, you must use a non-debugging build configuration. There are files called `external-libs-bin.zip` and `external-libs-src.zip`. If you are building with a recent MSVC or MINGW with MSYS2, you can just extract the `qpdf-external-libs-bin.zip` zip file into the top-level qpdf source tree. The qpdf build detects the presence of the `external-libs` directory automatically. You don't need to set any cmake options. -You can also obtain `zlib` and `jpeg` directly on your own and install them. If you are using mingw, you can just set `CPPFLAGS`, `LDFLAGS`, and `LIBS` when you run ./configure so that it can find the header files and libraries. If you are building with MSVC and you want to do this, it probably won't work because `./configure` doesn't know how to interpret `LDFLAGS` and `LIBS` properly for MSVC (though qpdf's own build system does). In this case, you can probably get away with cheating by passing `--enable-external-libs` to `./configure` and then just editing `CPPFLAGS`, `LDFLAGS`, `LIBS` in the generated autoconf.mk file. Note that you should use UNIX-like syntax (`-I`, `-L`, `-l`) even though this is not what cl takes on the command line. qpdf's build rules will fix it. +You can also obtain `zlib` and `jpeg` directly on your own and install them. Just make sure cmake can find them. External libraries are built using GitHub Actions from the [qpdf/external-libs](https://github.com/qpdf/external-libs) repository. -# Building from version control +# Running tools from the build area -If you check out qpdf from version control, documentation files will not be generated or installed. Documentation files are included in the source distribution, but they can only be built from Linux. - -# Building with MinGW - -QPDF is known to build and pass its test suite with MSYS2 using the 32-bit and 64-bit compilers. MSYS2 is required to build as well in order to get make and other related tools. See common setup at the top of this file for installation and configuration of MSYS2. Then, from the suitable 32-bit or 64-bit environment, run - -``` -./config-mingw -make -``` - -Note that `./config-mingw` just runs `./configure` with specific arguments, so you can look at it, make adjustments, and manually run configure instead. - -Add the absolute path to the `libqpdf/build` directory to your `PATH`. Make sure you can run the qpdf command by typing qpdf/build/qpdf and making sure you get a help message rather than an error loading the DLL or no output at all. Run the test suite by typing - -``` -make check -``` - -If all goes well, you should get a passing test suite. - -To create an installation directory, run `make install`. This will create `install-mingw/qpdf-VERSION` and populate it. The binary download of qpdf for Windows with mingw is created from this directory. - -You can also take a look at `make_windows_releases` for reference. This is how the distributed Windows executables are created. - -# Building with MSVC 2015 - -These instructions would likely work with newer versions of MSVC and are known to have worked with versions as old as 2008 Express. - -You should first set up your environment to be able to run MSVC from the command line. There is usually a batch file included with MSVC that does this. Make sure that you start a command line environment configured for whichever of 32-bit or 64-bit output that you intend to build for. - -From that cmd prompt, you can start your MSYS2 shell with path inheritance as described above. - -Configure and build as follows: - -``` -./config-msvc -make -``` - -Note that `./config-msvc` just runs `./configure` with specific arguments, so you can look at it, make adjustments, and manually run configure instead. - -NOTE: automated dependencies are not generated with the msvc build. If you're planning on making modifications, you should probably work with mingw. If there is a need, I can add dependency information to the msvc build, but since I only use it for generating release versions, I haven't bothered. - -Once built, add the full path to the `libqpdf/build` directory to your path and run - -``` -make check -``` - -to run the test suite. - -If you are building with MSVC and want to debug a crash in MSVC's debugger, first start an instance of Visual C++. Then run qpdf. When the abort/retry/ignore dialog pops up, first attach the process from within visual C++, and then click Retry in qpdf. - -A release version of qpdf is built by default. If you want to link against debugging libraries, you will have to change `/MD` to `/MDd` in `make/msvc.mk`. Note that you must redistribute the Microsoft runtime DLLs. Linking with static runtime (`/MT`) won't work; see "Static Runtime" below for details. +You can run qpdf's tests without modifying your PATH. If you want to manually run executables from the build tree on Windows, you need to add the `libqpdf` build directory to your path so it can find the qpdf DLL. This would typically be either `libqpdf` or `libqpdf/` (e.g., `libqpdf/Release`) depending on which cmake generator you are using. Alternatively, you can disable `BUILD_SHARED_LIBS` for your Windows build. This will cause the executables to use the static qpdf library and not build a qpdf DLL at all. # Runtime DLLs -Both build methods create executables and DLLs that are dependent on the compiler's runtime DLLs. When you run make install, the installation process will automatically detect the DLLs and copy them into the installation bin directory. Look at the `copy_dlls` script for details on how this is accomplished. - -Redistribution of the runtime DLL is unavoidable as of this writing; see "Static Runtime" below for details. - -# Static Runtime - -Building the DLL and executables with static runtime does not work with either Visual C++ .NET 2008 (a.k.a. vc9) using `/MT` or with mingw (at least as of 4.4.0) using `-static-libgcc`. The reason is that, in both cases, there is static data involved with exception handling, and when the runtime is linked in statically, exceptions cannot be thrown across the DLL to EXE boundary. Since qpdf uses exception handling extensively for error handling, we have no choice but to redistribute the C++ runtime DLLs. Maybe this will be addressed in a future version of the compilers. This has not been retested with the toolchain versions used to create qpdf >= 3.0 distributions. This has not been revisited since MSVC 2008, but redistributing runtime DLLs is extremely common and should not be a problem. +Both build methods create executables and DLLs that are dependent on the compiler's runtime DLLs. When you run `cmake --install` or `cpack`, the installation process will automatically detect the DLLs and copy them into the installation bin directory. For mingw, a perl script is used. For MSVC, `cmake`'s `InstallRequiredSystemLibraries` module is adequate. diff --git a/README.md b/README.md index 95281fcf..05aa8d00 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,7 @@ QPDF is a command-line tool and C++ library that performs content-preserving transformations on PDF files. It supports linearization, encryption, and numerous other features. It can also be used for splitting and merging files, creating PDF files (but you have to supply all the content yourself), and inspecting files for study or analysis. QPDF does not render PDFs or perform text extraction, and it does not contain higher-level interfaces for working with page contents. It is a low-level tool for working with the structure of PDF files and can be a valuable tool for anyone who wants to do programmatic or command-line-based manipulation of PDF files. -The [QPDF Manual](https://qpdf.readthedocs.io) is hosted online at https://qpdf.readthedocs.io. - -Additional information about it can be found at https://qpdf.sourceforge.io. The source code repository is hosted at GitHub: https://github.com/qpdf/qpdf. +The [QPDF Manual](https://qpdf.readthedocs.io) is hosted online at https://qpdf.readthedocs.io. The project website is https://qpdf.sourceforge.io. The source code repository is hosted at GitHub: https://github.com/qpdf/qpdf. # Verifying Distributions @@ -35,10 +33,22 @@ Versions of qpdf prior to version 7 were released under the terms of version 2.0 QPDF requires a C++ compiler that supports C++-14. +To compile and link something with qpdf, you can use `pkg-config` with package name `libqpdf` or `cmake` with package name `qpdf`. Here's an example of a `CMakeLists.txt` file that builds a program with the qpdf library: + +``` +cmake_minimum_required(VERSION 3.16) +project(some-application LANGUAGES CXX) +find_package(qpdf) +add_executable(some-application some-application.cc) +target_link_libraries(some-application qpdf::libqpdf) +``` + QPDF depends on the external libraries [zlib](https://www.zlib.net/) and [jpeg](https://www.ijg.org/files/). The [libjpeg-turbo](https://libjpeg-turbo.org/) library is also known to work since it is compatible with the regular jpeg library, and QPDF doesn't use any interfaces that aren't present in the straight jpeg8 API. These are part of every Linux distribution and are readily available. Download information appears in the documentation. For Windows, you can download pre-built binary versions of these libraries for some compilers; see [README-windows.md](README-windows.md) for additional details. Depending on which crypto providers are enabled, then [GnuTLS](https://www.gnutls.org/) and [OpenSSL](https://openssl.org) may also be required. This is discussed more in `Crypto providers` below. +Detailed information appears in the [manual](https://qpdf.readthedocs.io/en/latest/installation.html). + # Licensing terms of embedded software QPDF makes use of zlib and jpeg libraries for its functionality. These packages can be downloaded separately from their own download locations. If the optional GnuTLS or OpenSSL crypto providers are enabled, then GnuTLS and/or OpenSSL are also required. @@ -47,23 +57,14 @@ Please see the [NOTICE](NOTICE.md) file for information on licenses of embedded # Crypto providers -As of version 9.1.0, qpdf can use different crypto implementations. These can be selected at compile time or at runtime. The native crypto implementations that were used in all versions prior to 9.1.0 are still present and enabled by default. +qpdf can use different crypto implementations. These can be selected at compile time or at runtime. The native crypto implementations that were used in all versions prior to 9.1.0 are still present, but they are not built into qpdf by default if any external providers are available at build time. -Initially, the following providers are available: -* `native`: a native implementation where all the source is embedded in qpdf and no external dependencies are required -* `openssl`: an implementation that can use the OpenSSL (or BoringSSL) libraries to provide crypto; causes libqpdf to link with the OpenSSL library +The following providers are available: * `gnutls`: an implementation that uses the GnuTLS library to provide crypto; causes libqpdf to link with the GnuTLS library +* `openssl`: an implementation that can use the OpenSSL (or BoringSSL) libraries to provide crypto; causes libqpdf to link with the OpenSSL library +* `native`: a native implementation where all the source is embedded in qpdf and no external dependencies are required -The default behavior is for ./configure to discover which other crypto providers can be supported based on available external libraries, to build all available crypto providers, and to use an external provider as the default over the native one. This behavior can be changed with the following flags to ./configure: - -* `--enable-crypto-x` -- (where `x` is a supported crypto provider): enable the `x` crypto provider, requiring any external dependencies it needs -* `--disable-crypto-x` -- disable the `x` provider, and do not link against its dependencies even if they are available -* `--with-default-crypto=x` -- make `x` the default provider even if a higher priority one is available -* `--disable-implicit-crypto` -- only build crypto providers that are explicitly requested with an `--enable-crypto-x` option - -For example, if you want to guarantee that the GnuTLS crypto provider is used, you could run ./configure with `--enable-crypto-gnutls --disable-implicit-crypto`. - -Please see the section on crypto providers in the manual for more details. +The default behavior is for cmake to discover which other crypto providers can be supported based on available external libraries, to build all available external crypto providers, and to use an external provider as the default over the native one. By default, the native crypto provider will be used only if no external providers are available. This behavior can be changed with various cmake options as [described in the manual](https://qpdf.readthedocs.io/en/latest/installation.html#build-time-crypto-selection). ## Note about weak cryptographic algorithms @@ -71,62 +72,58 @@ The PDF file format used to rely on RC4 for encryption. Using 256-bit keys alway # Building from source distribution on UNIX/Linux -For UNIX and UNIX-like systems, you can usually get by with just +Starting with version 11, qpdf builds with cmake. The default configuration with cmake works on most systems. On Windows, you can build qpdf with Visual Studio using cmake without having any additional tools installed. However, to run the test suite, you need MSYS2, and you also need MSYS2 to build with mingw. +Example UNIX/Linux build: ``` -./configure -make -make install +cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo +cmake --build build ``` -Packagers may set DESTDIR, in which case make install will install inside of DESTDIR, as is customary with many packages. Please also see the "Notes for Packagers" section of the manual. +Example mingw build from an MSYS2 mingw shell: +``` +cmake -S . -B build -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=RelWithDebInfo +cmake --build build +``` -For more detailed general information, see the "INSTALL" file in this directory. If you are already accustomed to building and installing software that uses autoconf, there's nothing new for you in the INSTALL file. Note that qpdf uses `autoconf` but not `automake`. We have our own system of Makefiles that allows cross-directory dependencies, doesn't use recursive make, and works better on non-UNIX platforms. +Example MSVC build from an MSYS shell or from a Windows command shell with Visual Studio command-line tools in the path: +``` +cmake -S . -B build +cmake --build build --config Release +``` -# Building without wchar_t +Installation can be done with `cmake --install`. Packages can be made with `cpack`. -Executive summary: manually define -DQPDF_NO_WCHAR_T in your build if you are building on a system without wchar_t. For details, read the rest of this section. +The tests use `qtest`, and the test driver is invoked by `ctest`. To see the real underlying tests, run `ctest --verbose` so that you can see `qtest`'s output. If you need to turn off qtest's color output, pass `-DQTEST_COLOR=0` to cmake. -While wchar_t is part of the C++ standard library and should be present on virtually every system, there are some stripped down systems, such as those targeting certain embedded environments, that lack wchar_t. Internally, qpdf uses UTF-8 encoding for everything, so there is nothing important in qpdf's API that uses wchar_t. However, there is a helper method for converting between wchar_t* and char* that uses wchar_t. - -If you are building in an environment that does not support wchar_t, you can define the preprocessor symbol QPDF_NO_WCHAR_T in your build. This will work whether you are building qpdf and need to avoid compiling the code that uses wchar_t or whether you are building client code that uses qpdf. - -For example, to build qpdf on a system without wchar_t, be sure that -DQPDF_NO_WCHAR_T is part of your CXXFLAGS. Similar techniques will work in other places. - -Note that, when you build code with libqpdf, it is *not necessary* to have the definition of QPDF_NO_WCHAR_T in your build match what was defined when the library was built as long as you are not calling QUtil::call_main_from_wmain in your code. In other words, if your qpdf library was built on a system without wchar_t and you are using that system to build at some later time after wchar_t was available, as long as you don't call the function that uses it, you can just build normally. - -Note qpdf will never define QPDF_NO_WCHAR_T using autoconf or any other automated method in spite of the fact that it would be easy to do so. That is because there is a hard rule in qpdf that values determined by autoconf are not available in the public API. This is because there is never a guarantee or even expectation that those values will match between the system on which qpdf was build and the system on which a user is building code with libqpdf, and qpdf's include directory should look the same across all systems. +For additional information, please refer to the [manual](https://qpdf.readthedocs.io/en/latest/installation.html). # Building on Windows -QPDF is known to build and pass its test suite with mingw (latest version tested: gcc 7.2.0), mingw64 (latest version tested: 7.2.0) and Microsoft Visual C++ 2015, both 32-bit and 64-bit versions. MSYS2 is required to build as well in order to get make and other related tools. See [README-windows.md](README-windows.md) for details on how to build under Windows. +qpdf is known to build and pass its test suite with mingw and Microsoft Visual C++. Both 32-bit and 64-bit versions work. In addition to the manual, see [README-windows.md](README-windows.md) for more details on how to build under Windows. # Building Documentation -The QPDF manual is written in reStructured Text format and is build with [sphinx](https://www.sphinx-doc.org). The sources to the user manual can be found in the `manual` directory. For more detailed information, consult the [Building and Installing QPDF section of the manual](manual/installation.rst) or consult the [build-doc script](build-scripts/build-doc). +The QPDF manual is written in reStructured Text format and is build with [sphinx](https://www.sphinx-doc.org). The sources to the user manual can be found in the `manual` directory. For more detailed information, consult the [Building and Installing QPDF section of the manual](https://qpdf.readthedocs.io/en/latest/installation.html) or consult the [build-doc script](build-scripts/build-doc). # Additional Notes on Build -QPDF's build system can optionally use its own built-in rules rather than using libtool and obeying the compiler specified with configure. This can be enabled by passing `--with-buildrules=buildrules` where buildrules corresponds to one of the `.mk` files (other than `rules.mk`) in the make directory. This should never be necessary on a UNIX system, but may be necessary on a Windows system. See [README-windows.md](README-windows.md) for details. +qpdf provides cmake configuration files and pkg-config files. They support static and dynamic linking. In general, you do not need the header files from qpdf's dependencies to be available to builds that _use_ qpdf. The only exception to this is that, if you include `Pl_DCT.hh`, you need header files from `libjpeg`. Since this is a rare case, qpdf's cmake and pkg-config files do not automatically add a JPEG include path to the build. If you are using `Pl_DCT` explicitly, you probably already have that configured in your build. -The software library is just `libqpdf`, and all the header files are in the `qpdf` subdirectories of `include` and `libqpdf`. If you link statically with `-lqpdf`, then you will also need to link with `-lz` and `-ljpeg`. The shared qpdf library is linked with `-lz` and `-ljpeg`, none of qpdf's public header files directly include files from `libz`, and only `Pl_DCT.hh` includes files from `libjpeg`, so for most cases, qpdf's development files are self contained. If you need to use `Pl_DCT` in your application code, you will need to have the header files for some libjpeg distribution in your include path. - -To learn about using the library, please read comments in the header files in `include/qpdf`, especially `QPDF.hh`, `QPDFObjectHandle.hh`, and -`QPDFWriter.hh`. These are the best sources of documentation on the API. You can also study the code of `qpdf/qpdf.cc`, which exercises most of the public interface. There are additional example programs in the examples directory. Reading all the source files in the `qpdf` directory (including the qpdf command-line tool and some test drivers) along with the code in the examples directory will give you a complete picture of every aspect of the public interface. +To learn about using the library, please read comments in the header files in [include/qpdf](include/qpdf/), especially [QPDF.hh](include/qpdf/QPDF.hh), [QPDFObjectHandle.hh](include/qpdf/QPDFObjectHandle.hh), and +[QPDFWriter.hh](include/qpdf/QPDFWriter.hh). These are the best sources of documentation on the API. You can also study the code of [QPDFJob.cc](libqpdf/QPDFJob.cc), which exercises most of the public interface. There are additional example programs in the [examples](examples/) directory. # Additional Notes on Test Suite -By default, slow tests and tests that require dependencies beyond those needed to build qpdf are disabled. Slow tests include image comparison tests and large file tests. Image comparison tests can be enabled by passing `--enable-test-compare-images` to ./configure. This was on by default in qpdf versions prior to 3.0, but is now off by default. Large file tests can be enabled by passing `--with-large-file-test-path=path` to `./configure` or by setting the `QPDF_LARGE_FILE_TEST_PATH` environment variable. On Windows, this should be a Windows path. Run `./configure --help` for additional options. The test suite provides nearly full coverage even without these tests. Unless you are making deep changes to the library that would impact the contents of the generated PDF files or testing this on a new platform for the first time, there is no real reason to run these tests. If you're just running the test suite to make sure that qpdf works for your build, the default tests are adequate. The configure rules for these tests do nothing other than setting variables in `autoconf.mk`, so you can feel free to turn these on and off directly in `autoconf.mk` rather than rerunning configure. +By default, slow tests and tests that require dependencies beyond those needed to build qpdf are disabled. Slow tests include image comparison tests and large file tests. Image comparison tests can be enabled by setting the `QPDF_TEST_COMPARE_IMAGES` environment variable to `1`. Large file tests can be enabled setting the `QPDF_LARGE_FILE_TEST_PATH` environment variable to the absolute path of a directory with at least 11 GB of free space that can handle files over 4 GB in size. On Windows, this should be a Windows path (e.g. `C:\LargeFileTemp` even if the build is being run from an MSYS2 environment. The test suite provides nearly full coverage even without these tests. Unless you are making deep changes to the library that would impact the contents of the generated PDF files or testing this on a new platform for the first time, there is no real reason to run these tests. If you're just running the test suite to make sure that qpdf works for your build, the default tests are adequate. -If you are packaging qpdf for a distribution and preparing a build that is run by an autobuilder, you may want to add the `--enable-show-failed-test-output` to configure options. This way, if the test suite fails, test failure detail will be included in the build output. Otherwise, you will have to have access to the `qtest.log` file from the build to view test failures. The Debian packages for qpdf enable this option. +If you are packaging qpdf for a distribution and preparing a build that is run by an autobuilder, you may want to pass `-DSHOW_FAILED_TEST_OUTPUT=1` to `cmake` and run `ctest` with the `--verbose` or `--output-on-failure` option. This way, if the test suite fails, test failure detail will be included in the build output. Otherwise, you will have to have access to the `qtest.log` file from the build to view test failures. The Debian packages for qpdf enable this option. More notes for packagers can be found in [the manual](https://qpdf.readthedocs.io/en/latest/packaging.html). # Random Number Generation By default, qpdf uses the crypto provider for generating random numbers. The rest of this applies only if you are using the native crypto provider. If the native crypto provider is in use, then, when `qpdf` detects either the Windows cryptography API or the existence of `/dev/urandom`, `/dev/arandom`, or `/dev/random`, it uses them to generate cryptographically secure random numbers. If none of these conditions are true, the build will fail with an error. This behavior can be modified in several ways: -* If you configure with `--disable-os-secure-random` or define `SKIP_OS_SECURE_RANDOM`, qpdf will not attempt to use Windows cryptography or the random device. You must either supply your own random data provider or allow use of insecure random numbers. -* If you configure qpdf with the `--enable-insecure-random` option or define `USE_INSECURE_RANDOM`, qpdf will try insecure random numbers if OS-provided secure random numbers are disabled. This is not a fallback. In order for insecure random numbers to be used, you must also disable OS secure random numbers since, otherwise, failure to find OS secure random numbers is a compile error. The insecure random number source is stdlib's `random()` or `rand()` calls. These random numbers are not cryptography secure, but the qpdf library is fully functional using them. Using non-secure random numbers means that it's easier in some cases to guess encryption keys. If you're not generating encrypted files, there's no advantage to using secure random numbers. +* If you use the cmake option `SKIP_OS_SECURE_RANDOM` or define the `SKIP_OS_SECURE_RANDOM` preprocessor symbol, qpdf will not attempt to use Windows cryptography or the random device. You must either supply your own random data provider or allow use of insecure random numbers. +* If you turn on the cmake option `USE_INSECURE_RANDOM` or define the `USE_INSECURE_RANDOM` preprocessor symbol, qpdf will try insecure random numbers if OS-provided secure random numbers are disabled. This is not a fallback. In order for insecure random numbers to be used, you must also disable OS secure random numbers since, otherwise, failure to find OS secure random numbers is a compile error. The insecure random number source is stdlib's `random()` or `rand()` calls. These random numbers are not cryptography secure, but the qpdf library is fully functional using them. Using non-secure random numbers means that it's easier in some cases to guess encryption keys. * In all cases, you may supply your own random data provider. To do this, derive a class from `qpdf/RandomDataProvider` (since version 5.1.0) and call `QUtil::setRandomDataProvider` before you create any `QPDF` objects. If you supply your own random data provider, it will always be used even if support for one of the other random data providers is compiled in. If you wish to avoid any possibility of your build of qpdf from using anything but a user-supplied random data provider, you can define `SKIP_OS_SECURE_RANDOM` and not `USE_INSECURE_RANDOM`. In this case, qpdf will throw a runtime error if any attempt is made to generate random numbers and no random data provider has been supplied. - -If you are building qpdf on a platform that qpdf doesn't know how to generate secure random numbers on, a patch would be welcome. diff --git a/TODO b/TODO index 051c43c4..5515f3dc 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,9 @@ Misc --show-encryption could potentially retry with this option if the first time doesn't work. Then, with the file open, we can read the encryption dictionary normally. +* Go through README-maintainer "CODING RULES" and update -- + PointerHolder and other changes will make some of the rules + obsolete. Soon: Break ground on "Document-level work" @@ -1032,12 +1035,6 @@ Rejected Ideas * Investigate whether there is a way to automate the memory checker tests for Windows. -* Consider adding "uninstall" target to makefile. It should only - uninstall what it installed, which means that you must run - uninstall from the version you ran install with. It would only be - supported for the toolchains that support the install target - (libtool). - * Provide support in QPDFWriter for writing incremental updates. Provide support in qpdf for preserving incremental updates. The goal should be that QDF mode should be fully functional for files diff --git a/cSpell.json b/cSpell.json index 4b0b3612..a2cce4db 100644 --- a/cSpell.json +++ b/cSpell.json @@ -77,6 +77,8 @@ "cstr", "cxxflags", "cygwin", + "dbuild", + "dcmake", "dctdecode", "decltype", "decrypter", @@ -88,14 +90,19 @@ "devel", "didier", "diffutils", + "dinstall", "directpagerefcount", "distclean", "ditems", + "dmaintainer", "docbook", "docdir", "dohnal", "dqpdf", + "dqtest", "dquote", + "drequire", + "dshow", "dtdvalid", "ebra", "ecks", diff --git a/manual/installation.rst b/manual/installation.rst index e8773a65..28d4ccd9 100644 --- a/manual/installation.rst +++ b/manual/installation.rst @@ -3,125 +3,440 @@ Building and Installing QPDF ============================ -This chapter describes how to build and install qpdf. Please see also -the :file:`README.md` and -:file:`INSTALL` files in the source distribution. +This chapter describes how to build and install qpdf. .. _prerequisites: -System Requirements -------------------- +Dependencies +------------ -The qpdf package has few external dependencies. In order to build qpdf, -the following packages are required: +qpdf has few external dependencies. This section describes what you +need to build qpdf in various circumstances. -- A C++ compiler that supports C++-14. +Basic Dependencies +~~~~~~~~~~~~~~~~~~ -- zlib: http://www.zlib.net/ +- A C++ compiler that supports C++-14 -- jpeg: http://www.ijg.org/files/ or https://libjpeg-turbo.org/ +- `CMake `__ version 3.16 or later -- *Recommended but not required:* gnutls: https://www.gnutls.org/ to be - able to use the gnutls crypto provider, and/or openssl: - https://openssl.org/ to be able to use the openssl crypto provider. +- `zlib `__ or a compatible zlib implementation -- gnu make 3.81 or newer: http://www.gnu.org/software/make +- A libjpeg-compatible library such as `jpeg `__ or + `libjpeg-turbo `__ -- perl version 5.8 or newer: http://www.perl.org/; required for running - the test suite. Starting with qpdf version 9.1.1, perl is no longer - required at runtime. +- *Recommended but not required:* `gnutls `__ + to be able to use the gnutls crypto provider and/or `openssl + `__ to be able to use the openssl crypto + provider -- GNU diffutils (any version): http://www.gnu.org/software/diffutils/ - is required to run the test suite. Note that this is the version of - diff present on virtually all GNU/Linux systems. This is required - because the test suite uses :command:`diff -u`. +The qpdf source tree includes a few automatically generated files. The +code generator uses Python 3. Automatic code generation is off by +default. For a discussion, refer to :ref:`build-options`. -Part of qpdf's test suite does comparisons of the contents PDF files by -converting them images and comparing the images. The image comparison -tests are disabled by default. Those tests are not required for -determining correctness of a qpdf build if you have not modified the -code since the test suite also contains expected output files that are -compared literally. The image comparison tests provide an extra check to -make sure that any content transformations don't break the rendering of -pages. Transformations that affect the content streams themselves are -off by default and are only provided to help developers look into the -contents of PDF files. If you are making deep changes to the library -that cause changes in the contents of the files that qpdf generate, -then you should enable the image comparison tests. Enable them by -running :command:`configure` with the -:samp:`--enable-test-compare-images` flag. If you enable -this, the following additional requirements are required by the test -suite. Note that in no case are these items required to use qpdf. +Test Dependencies +~~~~~~~~~~~~~~~~~ -- libtiff: http://www.remotesensing.org/libtiff/ +qpdf's test suite is run by ``ctest``, which is part of CMake, but +the tests themselves are implemented using an embedded copy of `qtest +`__, which is implemented in perl. On +Windows, MSYS2's perl is known to work. -- GhostScript version 8.60 or newer: http://www.ghostscript.com +qtest requires `GNU diffutils +`__ or any other diff that +supports :command:`diff -u`. The default ``diff`` command works on +GNU/Linux and MacOS. -If you do not enable this, then you do not need to have tiff and -ghostscript. +Part of qpdf's test suite does comparisons of the contents PDF files +by converting them to images and comparing the images. The image +comparison tests are disabled by default. Those tests are not required +for determining correctness of a qpdf build since the test suite also +contains expected output files that are compared literally. The image +comparison tests provide an extra check to make sure that any content +transformations don't break the rendering of pages. Transformations +that affect the content streams themselves are off by default and are +only provided to help developers look into the contents of PDF files. +If you are making deep changes to the library that cause changes in +the contents of the files that qpdf generates, then you should enable +the image comparison tests. Enable them by setting the +``QPDF_TEST_COMPARE_IMAGES`` environment variable to ``1`` before +running tests. Image comparison tests add these additional +requirements: -For information on building the documentation, see :ref:`build-doc`. +- `libtiff `__ command-line + utilities + +- `GhostScript `__ version 8.60 or newer + +Note: prior to qpdf 11, image comparison tests were enabled within +:file:`qpdf.test`, and you had to *disable* them by setting +``QPDF_SKIP_TEST_COMPARE_IMAGES`` to ``1``. This was done +automatically by ``./configure``. Now you have to *enable* image +comparison tests by setting an environment variable. This change was +made because developers have to set the environment variable +themselves now rather than setting it through the build. Either way, +they are off by default. + +Additional Requirements on Windows +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- To build qpdf with Visual Studio, there are no additional + requirements when the default cmake options are used. You can build + qpdf from a Visual C++ command-line shell. + +- To build with mingw, MSYS2 is recommended with the mingw32 and/or + mingw64 tool chains. You can also build with MSVC from an MSYS2 + environment. + +- qpdf's test suite can run within the MSYS2 environment for both + mingw and MSVC-based builds. + +For additional notes, see :file:`README-windows.md` in the source +distribution. + +Requirements for Building Documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The qpdf manual is written in reStructured Text and built with `Sphinx +`__ using the `Read the Docs Sphinx Theme +`__. Versions of sphinx prior +to version 4.3.2 probably won't work. Sphinx requires Python 3. In +order to build the HTML documentation from source, you need to install +sphinx and the theme, which you can typically do with ``pip install +sphinx sphinx_rtd_theme``. To build the PDF version of the +documentation, you need ``pdflatex``, ``latexmk``, and a fairly +complete LaTeX installation. Detailed requirements can be found in the +Sphinx documentation. To see how the documentation is built for the +qpdf distribution, refer to the :file:`build-scripts/build-doc` file +in the qpdf source distribution. .. _building: Build Instructions ------------------ -Building qpdf on UNIX is generally just a matter of running +Starting with qpdf 11, qpdf is built with `CMake +`__. + +Basic Build Invocation +~~~~~~~~~~~~~~~~~~~~~~ + +qpdf uses cmake in an ordinary way, so refer to the CMake +documentation for details about how to run ``cmake``. Here is a +brief summary. + +You can usually just run :: - ./configure - make + cmake -S . -B build + cmake --build build -You can also run :command:`make check` to run the test -suite and :command:`make install` to install. Please run -:command:`./configure --help` for options on what can be -configured. You can also set the value of ``DESTDIR`` during -installation to install to a temporary location, as is common with many -open source packages. Please see also the -:file:`README.md` and -:file:`INSTALL` files in the source distribution. +If you are using a multi-configuration generator such as MSVC, you +should pass ``--config `` (where ```` is ``Release``, +``Debug``, ``RelWithDebInfo``, or ``MinSizeRel`` as discussed in the +CMake documentation) to the *build* command. If you are running a +single configuration generator such as the default Makefile generators +in Linux or MSYS, you may want to pass ``-DCMAKE_BUILD_TYPE=`` +to the original ``cmake`` command. -Building on Windows is a little bit more complicated. For details, -please see :file:`README-windows.md` in the source -distribution. You can also download a binary distribution for Windows. -There is a port of qpdf to Visual C++ version 6 in the -:file:`contrib` area generously contributed by Jian -Ma. This is also discussed in more detail in -:file:`README-windows.md`. +Run ``ctest`` to run the test suite. Since the real tests are +implemented with `qtest `__, you will +want to pass ``--verbose`` to ``cmake`` so you can see the individual +test outputs. Otherwise, you will see a small number of ``ctest`` +commands that take a very long to run. -While ``wchar_t`` is part of the C++ standard, qpdf uses it in only one -place in the public API, and it's just in a helper function. It is -possible to build qpdf on a system that doesn't have ``wchar_t``, and -it's also possible to compile a program that uses qpdf on a system -without ``wchar_t`` as long as you don't call that one method. This is a -very unusual situation. For a detailed discussion, please see the -top-level README.md file in qpdf's source distribution. +.. _installation: -There are some other things you can do with the build. Although qpdf -uses :command:`autoconf`, it does not use -:command:`automake` but instead uses a -hand-crafted non-recursive Makefile that requires gnu make. If you're -really interested, please read the comments in the top-level -:file:`Makefile`. +Installation and Packaging +~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. _build-doc: +Installation can be performed using ``cmake --install`` or ``cpack``. +For most normal use cases, ``cmake --install`` or ``cpack`` can be run +in the normal way as described in CMake documentation. qpdf follows +all normal installation conventions and uses CMake-defined variables +for standard behavior. -Building Documentation ----------------------- +There are several components that can be installed separately: -The qpdf manual is written in reStructured Text and built with `Sphinx -`__ using the `Read the Docs Sphinx Theme -`__. In order to build the -HTML documentation from source, you need to install sphinx and the -theme, which you can typically do with ``pip install sphinx -sphinx_rtd_theme``. To build the PDF version of the documentation, you -need ``pdflatex``, ``latexmk``, and a fairly complete LaTeX -installation. Detailed requirements can be found in the Sphinx -documentation. To see how the documentation is built for the qpdf -distribution, refer to the :file:`build-scripts/build-doc` file in the -qpdf source distribution. +.. list-table:: Installation Components + :widths: 5 80 + :header-rows: 0 + + - - cli + - Command-line tools + + - - lib + - The runtime libraries; required if you built with shared + libraries + + - - dev + - Static libraries, header files, and other files needed by + developers + + - - doc + - Documentation and, if selected for installation, the manual + + - - examples + - Example source files + +There are also separate options, discussed in :ref:`build-options`, +that control how certain specific parts of the software are installed. + +.. _build-options: + +Build Options +------------- + +.. last verified consistent with build: 2022-03-13. The top-level + CMakeLists.txt contains a comment that references this section. + +.. cSpell:ignore ccmake + +All available build options are defined in the the top-level +:file:`CMakeLists.txt` file and have help text. You can see them using +any standard cmake front-end (like ``cmake-gui`` or ``ccmake``). This +section describes options that apply to most users. If you are trying +to map autoconf options (from prior to qpdf 11) to cmake options, +please see :ref:`autoconf-to-cmake`. + +If you are packaging qpdf for a distribution, you should also read +:ref:`packaging`. + +Basic Build Options +~~~~~~~~~~~~~~~~~~~ + +BUILD_DOC + Whether to build documentation with sphinx. You must have the + required tools installed. + +BUILD_DOC_HTML + Visible when BUILD_DOC is selected. This option controls building + HTML documentation separately from PDF documentation since + the sphinx theme only needed for the HTML documentation. + +BUILD_DOC_PDF + Visible when BUILD_DOC is selected. This option controls building + PDF documentation separately from HTML documentation since + additional tools are required to build the PDF documentation. + +BUILD_SHARED_LIBS, BUILD_STATIC_LIBS + You can configure whether to build shared libraries, static + libraries, or both. You must select at least one of these options. + For rapid iteration, select only one as this cuts the build time in + half. + + On Windows, if you build with shared libraries, you must have the + output directory for libqpdf (e.g. :file:`libqpdf/Release` or + :file:`libqpdf` within the build directory) in your path so that the + compiled executables can find the DLL. Updating your path is not + necessary if you build with static libraries only. + +QTEST_COLOR + Turn this on or off to control whether qtest uses color in its + output. + +Options for Working on qpdf +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +GENERATE_AUTO_JOB + Some qpdf source files are automatically generated from + :file:`job.yml` and the CLI documentation. If you are adding new + command-line arguments to the qpdf CLI or updating + :file:`manual/cli.rst` in the qpdf sources, you should turn this on. + This option requires Python 3. + +WERROR + Make any compiler warnings into errors. We want qpdf to compile free + of warnings whenever possible, but there's always a chance that a + compiler upgrade or tool change may cause warnings to appear that + weren't there before. If you are testing qpdf with a new compiler, + you should turn this on. + +Environment-Specific Options +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SHOW_FAILED_TEST_OUTPUT + Ordinarily, qtest (which drives qpdf's test suite) writes detailed + information about its output to the file ``qtest.log`` in the build + output directory. If you are running a build in a continuous + integration or automated environment where you can't get to those + files, you should enable this option and also run ``ctest + --verbose`` or ``ctest --output-on-failure``. This will cause + detailed test failure output to be written into the build log. + +CI_MODE + Turning this on sets options used in qpdf's continuous integration + environment to ensure we catch as many problems as possible. + Specifically, this option enables ``SHOW_FAILED_TEST_OUTPUT`` and + ``WERROR`` and forces the native crypto provider to be built. + +MAINTAINER_MODE + Turning this option on sets options that should be on if you are + maintaining qpdf. In turns on the following: + + - ``BUILD_DOC`` + + - ``GENERATE_AUTO_JOB`` + + - ``WERROR`` + + - ``REQUIRE_NATIVE_CRYPTO`` + + It is possible to turn ``BUILD_DOC`` off in maintainer mode so that + the extra requirements for building documentation don't have to be + available. + +.. _crypto.build: + +Build-time Crypto Selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since version 9.1.0, qpdf can use external crypto providers in +addition to its native provider. For a general discussion, see +:ref:`crypto`. This section discusses how to configure which crypto +providers are compiled into qpdf. + +In nearly all cases, external crypto providers should be preferred +over the native one. However, if you are not concerned about working +with encrypted files and want to reduce the number of dependencies, +the native crypto provider is fully supported. + +By default, qpdf's build enables every external crypto providers whose +dependencies are available and only enables the native crypto provider +if no external providers are available. You can change this behavior +with the options described here. + +USE_IMPLICIT_CRYPTO + This is on by default. If turned off, only explicitly selected + crypto providers will be built. You must use at least one of the + ``REQUIRE`` options below. + +ALLOW_CRYPTO_NATIVE + This option is only available when USE_IMPLICIT_CRYPTO is selected, + in which case it is on by default. Turning it off prevents qpdf from + falling back to the native crypto provider when no external provider + is available. + +REQUIRE_CRYPTO_NATIVE + Build the native crypto provider even if other options are + available. + +REQUIRE_CRYPTO_GNUTLS + Require the gnutls crypto provider. Turning this on makes in an + error if the gnutls library is not available. + +REQUIRE_CRYPTO_OPENSSL + Require the openssl crypto provider. Turning this on makes in an + error if the openssl library is not available. + +DEFAULT_CRYPTO + Explicitly select which crypto provider is used by default. See + :ref:`crypto.runtime` for information about run-time selection of + the crypto provider. If not specified, qpdf will pick gnutls if + available, otherwise openssl if available, and finally native as a + last priority. + +Example: if you wanted to build with only the gnutls crypto provider, +you should run cmake with ``-DUSE_IMPLICIT_CRYPTO=0 +-DREQUIRE_CRYPTO_GNUTLS=1``. + +Advanced Build Options +~~~~~~~~~~~~~~~~~~~~~~ + +These options are used only for special purposes and are not relevant +to most users. + +AVOID_WINDOWS_HANDLE + Disable use of the ``HANDLE`` type in Windows. This can be useful if + you are building for certain embedded Windows environments. Some + functionality won't work, but you can still process PDF files from + memory in this configuration. + +BUILD_DOC_DIST, INSTALL_MANUAL + By default, installing qpdf does not include a pre-built copy of the + manual. Instead, it installs a README file that tells people where + to find the manual online. If you want to install the manual, you + must enable the ``INSTALL_MANUAL`` option, and you must have a + ``doc-dist`` directory in the manual directory of the build. The + ``doc-dist`` directory is created if ``BUILD_DOC_DIST`` is selected + and ``BUILD_DOC_PDF`` and ``BUILD_DOC_HTML`` are both on. + + The ``BUILD_DOC_DIST`` and ``INSTALL_MANUAL`` options are separate + and independent because of the additional tools required to build + documentation. In particular, for qpdf's official release + preparation, a ``doc-dist`` directory is built in Linux and then + extracted into the Windows builds so that it can be included in the + Windows installers. This prevents us from having to build the + documentation in a Windows environment. For additional discussion, + see :ref:`doc-packaging-rationale`. + +INSTALL_CMAKE_PACKAGE + Controls whether or not to install qpdf's cmake configuration file + (on by default). + +INSTALL_EXAMPLES + Controls whether or not to install qpdf's example source files with + documentation (on by default). + +INSTALL_PKGCONFIG + Controls whether or not to install qpdf's pkg-config configuration + file (on by default). + +OSS_FUZZ + Turning this option on changes the build of the fuzzers in a manner + specifically required by Google's oss-fuzz project. There is no + reason to turn this on for any other reason. It is enabled by the + build script that builds qpdf from that context. + +SKIP_OS_SECURE_RANDOM, USE_INSECURE_RANDOM + The native crypto implementation uses the operating systems's secure + random number source when available. It is not used when an external + crypto provider is in use. If you are building in a very specialized + environment where you are not using an external crypto provider but + can't use the OS-provided secure random number generator, you can + turn both of these options on. This will cause qpdf to fall back to + an insecure random number generator, which may generate guessable + random numbers. The resulting qpdf is still secure, but encrypted + files may be more subject to brute force attacks. Unless you know + you need these options for a specialized purpose, you don't need + them. These options were added to qpdf in response to a special + request from a user who needed to run a specialized PDF-related task + in an embedded environment that didn't have a secure random number + source. + +Building without wchar_t +~~~~~~~~~~~~~~~~~~~~~~~~ + +It is possible to build qpdf on a system that doesn't have +``wchar_t``. The resulting build of qpdf is not API-compatible with a +regular qpdf build, so this option cannot be selected from cmake. This +option was added to qpdf to support installation on a very stripped +down embedded environment that included only a partial implementation +of the standard C++ library. + +You can disable use of ``wchar_t`` in qpdf's code by defining the +``QPDF_NO_WCHAR_T`` preprocessor symbol in your build (e.g. by +including ``-DQPDF_NO_WCHAR_T`` in ``CFLAGS`` and ``CXXFLAGS``). + +While ``wchar_t`` is part of the C++ standard library and should be +present on virtually every system, there are some stripped down +systems, such as those targeting certain embedded environments, that +lack ``wchar_t``. Internally, qpdf uses UTF-8 encoding for everything, +so there is nothing important in qpdf's API that uses ``wchar_t``. +However, there are some helper methods for converting between +``wchar_t*`` and ``char*``. + +If you are building in an environment that does not support +``wchar_t``, you can define the preprocessor symbol +``QPDF_NO_WCHAR_T`` in your build. This will work whether you are +building qpdf and need to avoid compiling the code that uses wchar_t +or whether you are building client code that uses qpdf. + +Note that, when you build code with libqpdf, it is *not necessary* to +have the definition of ``QPDF_NO_WCHAR_T`` in your build match what +was defined when the library was built as long as you are not calling +any of the methods that use ``wchar_t``. .. _crypto: @@ -134,93 +449,36 @@ to as "crypto providers." At the time of writing, a crypto implementation must provide MD5 and SHA2 (256, 384, and 512-bit) hashes and RC4 and AES256 with and without CBC encryption. In the future, if digital signature is added to qpdf, there may be additional requirements -beyond this. +beyond this. Some of these are weak cryptographic algorithms. For a +discussion of why they're needed, see :ref:`weak-crypto`. -Starting with qpdf version 9.1.0, the available implementations are -``native`` and ``gnutls``. In qpdf 10.0.0, ``openssl`` was added. -Additional implementations may be added if needed. It is also possible -for a developer to provide their own implementation without modifying -the qpdf library. +The available crypto provider implementations are ``gnutls``, +``openssl``, and ``native``. OpenSSL support was added in qpdf 10.0.0 +with support for OpenSSL added in 10.4.0. GnuTLS support was +introduced in qpdf 9.1.0. Additional implementations can be added as +needed. It is also possible for a developer to provide their own +implementation without modifying the qpdf library. -.. _crypto.build: - -Build Support For Crypto Providers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When building with qpdf's build system, crypto providers can be enabled -at build time using various :command:`./configure` -options. The default behavior is for -:command:`./configure` to discover which crypto providers -can be supported based on available external libraries, to build all -available crypto providers, and to use an external provider as the -default over the native one. This behavior can be changed with the -following flags to :command:`./configure`: - -- :samp:`--enable-crypto-{x}` - (where :samp:`{x}` is a supported crypto - provider): enable the :samp:`{x}` crypto - provider, requiring any external dependencies it needs - -- :samp:`--disable-crypto-{x}`: - disable the :samp:`{x}` provider, and do not - link against its dependencies even if they are available - -- :samp:`--with-default-crypto={x}`: - make :samp:`{x}` the default provider even if - a higher priority one is available - -- :samp:`--disable-implicit-crypto`: only build crypto - providers that are explicitly requested with an - :samp:`--enable-crypto-{x}` - option - -For example, if you want to guarantee that the gnutls crypto provider is -used and that the native provider is not built, you could run -:command:`./configure --enable-crypto-gnutls ---disable-implicit-crypto`. - -If you build qpdf using your own build system, in order for qpdf to work -at all, you need to enable at least one crypto provider. The file -:file:`libqpdf/qpdf/qpdf-config.h.in` provides -macros ``DEFAULT_CRYPTO``, whose value must be a string naming the -default crypto provider, and various symbols starting with -``USE_CRYPTO_``, at least one of which has to be enabled. Additionally, -you must compile the source files that implement a crypto provider. To -get a list of those files, look at -:file:`libqpdf/build.mk`. If you want to omit a -particular crypto provider, as long as its ``USE_CRYPTO_`` symbol is -undefined, you can completely ignore the source files that belong to a -particular crypto provider. Additionally, crypto providers may have -their own external dependencies that can be omitted if the crypto -provider is not used. For example, if you are building qpdf yourself and -are using an environment that does not support gnutls or openssl, you -can ensure that ``USE_CRYPTO_NATIVE`` is defined, ``USE_CRYPTO_GNUTLS`` -is not defined, and ``DEFAULT_CRYPTO`` is defined to ``"native"``. Then -you must include the source files used in the native implementation, -some of which were added or renamed from earlier versions, to your -build, and you can ignore -:file:`QPDFCrypto_gnutls.cc`. Always consult -:file:`libqpdf/build.mk` to get the list of source -files you need to build. +For information about selecting which crypto providers are compiled +into qpdf, see :ref:`crypto.build`. .. _crypto.runtime: Runtime Crypto Provider Selection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can use the :qpdf:ref:`--show-crypto` option to -:command:`qpdf` to get a list of available crypto -providers. The default provider is always listed first, and the rest are -listed in lexical order. Each crypto provider is listed on a line by -itself with no other text, enabling the output of this command to be -used easily in scripts. +You can use the :qpdf:ref:`--show-crypto` option to :command:`qpdf` to +get a list of available crypto providers. The default provider is +always listed first, and the rest are listed in lexical order. Each +crypto provider is listed on a line by itself with no other text, +enabling the output of this command to be used easily in scripts. You can override which crypto provider is used by setting the -``QPDF_CRYPTO_PROVIDER`` environment variable. There are few reasons to -ever do this, but you might want to do it if you were explicitly trying -to compare behavior of two different crypto providers while testing -performance or reproducing a bug. It could also be useful for people who -are implementing their own crypto providers. +``QPDF_CRYPTO_PROVIDER`` environment variable. There are few reasons +to ever do this, but you might want to do it if you were explicitly +trying to compare behavior of two different crypto providers while +testing performance or reproducing a bug. It could also be useful for +people who are implementing their own crypto providers. .. _crypto.develop: @@ -229,11 +487,11 @@ Crypto Provider Information for Developers If you are writing code that uses libqpdf and you want to force a certain crypto provider to be used, you can call the method -``QPDFCryptoProvider::setDefaultProvider``. The argument is the name of -a built-in or developer-supplied provider. To add your own crypto -provider, you have to create a class derived from ``QPDFCryptoImpl`` and -register it with ``QPDFCryptoProvider``. For additional information, see -comments in :file:`include/qpdf/QPDFCryptoImpl.hh`. +``QPDFCryptoProvider::setDefaultProvider``. The argument is the name +of a built-in or developer-supplied provider. To add your own crypto +provider, you have to create a class derived from ``QPDFCryptoImpl`` +and register it with ``QPDFCryptoProvider``. For additional +information, see comments in :file:`include/qpdf/QPDFCryptoImpl.hh`. .. _crypto.design: @@ -308,3 +566,126 @@ provide their own implementations for basic filters like Implementing the registration functions and internal storage of registered providers was also easier using C++-11's functional interfaces, which was another reason to require C++-11 at this time. + +.. _autoconf-to-cmake: + +Converting From autoconf to cmake +--------------------------------- + +Versions of qpdf before qpdf 11 were built with ``autoconf`` and a +home-grown GNU Make-based build system. If you built qpdf with special +``./configure`` options, this section can help you switch them over to +``cmake``. + +In most cases, there is a one-to-one mapping between configure options +and cmake options. There are a few exceptions: + +- The cmake build behaves differently with respect to whether or not + to include support for the native crypto provider. Specifically, it + is not implicitly enabled unless explicitly requested if there are + other options available. You can force it to be included by enabling + ``REQUIRE_CRYPTO_NATIVE``. For details, see :ref:`crypto.build`. + +- The ``--enable-external-libs`` option is no longer available. The + cmake build detects the presence of ``external-libs`` automatically. + See :file:`README-windows.md` in the source distribution for a more + in-depth discussion. + +- The sense of the option representing use of the OS-provided secure + random number generator has been reversed: the + ``--enable-os-secure-random``, which was on by default, has been + replaced by the ``SKIP_OS_SECURE_RANDOM`` option, which is off by + default. The option's new name and behavior match the preprocessor + symbol that it turns on. + +- Non-default test configuration is selected with environment + variables rather than cmake. The old ``./configure`` options just + set environment variables. Note that the sense of the variable for + image comparison tests has been reversed. It used to be that you had + to set ``QPDF_SKIP_TEST_COMPARE_IMAGES`` to ``1`` to *disable* image + comparison tests. This was done by default. Now you have to set + ``QPDF_TEST_COMPARE_IMAGES`` to ``1`` to *enable* image comparison + tests. Either way, they are off by default. + +- A handful of options that were specific to autoconf or the old build + system have been dropped. + +- ``cmake --install`` installs example source code in + ``doc/qpdf/examples`` in the ``examples`` installation component. + Packagers are encouraged to package this with development files if + there is no separate doc package. This can be turned off by + disabling the ``INSTALL_EXAMPLES`` build option. + +There are some new options available in the cmake build that were not +available in the autoconf build. This table shows the old options and +their equivalents in cmake. + +.. list-table:: configure flags to cmake options + :widths: 40 60 + :header-rows: 0 + + - - enable-avoid-windows-handle + - AVOID_WINDOWS_HANDLE + + - - enable-check-autofiles + - none -- not relevant to cmake + + - - enable-crypto-gnutls + - REQUIRE_CRYPTO_GNUTLS + + - - enable-crypto-native + - REQUIRE_CRYPTO_NATIVE (but see above) + + - - enable-crypto-openssl + - REQUIRE_CRYPTO_OPENSSL + + - - enable-doc-maintenance + - BUILD_DOC + + - - enable-external-libs + - none -- detected automatically + + - - enable-html-doc + - BUILD_DOC_HTML + + - - enable-implicit-crypto + - USE_IMPLICIT_CRYPTO + + - - enable-insecure-random + - USE_INSECURE_RANDOM + + - - enable-ld-version-script + - none -- detected automatically + + - - enable-maintainer-mode + - MAINTAINER_MODE (slight differences) + + - - enable-os-secure-random (on by default) + - SKIP_OS_SECURE_RANDOM (off by default) + + - - enable-oss-fuzz + - OSS_FUZZ + + - - enable-pdf-doc + - BUILD_DOC_PDF + + - - enable-rpath + - none -- cmake handles rpath correctly + + - - enable-show-failed-test-output + - SHOW_FAILED_TEST_OUTPUT + + - - enable-test-compare-images + - set the ``QPDF_TEST_COMPARE_IMAGES`` environment variable + + - - enable-werror + - WERROR + + - - with-buildrules + - none -- not relevant to cmake + + - - with-default-crypto + - DEFAULT_CRYPTO + + - - large-file-test-path + - set the ``QPDF_LARGE_FILE_TEST_PATH`` environment variable diff --git a/manual/library.rst b/manual/library.rst index 33abdebe..32bb21c1 100644 --- a/manual/library.rst +++ b/manual/library.rst @@ -23,10 +23,20 @@ All header files are installed in the you use ``#include `` rather than adding :file:`include/qpdf` to your include path. -When linking against the qpdf static library, you may also need to -specify ``-lz -ljpeg`` on your link command. If your system understands -how to read libtool :file:`.la` files, this may not -be necessary. +qpdf installs a ``pkg-config`` configuration with package name +``libqpdf`` and a ``cmake`` configuration with package name ``qpdf``. +The ``libqpdf`` target is exported in the ``qpdf::`` namespace. The +following is an example of a :file:`CMakeLists.txt` file for a +single-file executable that links with qpdf: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.16) + project(some-application LANGUAGES CXX) + find_package(qpdf) + add_executable(some-application some-application.cc) + target_link_libraries(some-application qpdf::libqpdf) + The qpdf library is safe to use in a multithreaded program, but no individual ``QPDF`` object instance (including ``QPDF``, diff --git a/manual/packaging.rst b/manual/packaging.rst index 6ff77e51..50f8fc60 100644 --- a/manual/packaging.rst +++ b/manual/packaging.rst @@ -9,6 +9,10 @@ chapter is for you. Otherwise, feel free to skip. Build Options ------------- +For a detailed discussion of build options, please refer to +:ref:`build-options`. This section calls attention to options that are +particularly useful to packagers. + - Perl must be present at build time. Prior to qpdf version 9.1.1, there was a runtime dependency on perl, but this is no longer the case. @@ -16,31 +20,23 @@ Build Options - Make sure you are getting the intended behavior with regard to crypto providers. Read :ref:`crypto.build` for details. -- Passing :samp:`--enable-show-failed-test-output` to - :command:`./configure` will cause any failed test - output to be written to the console. This can be very useful for - seeing test failures generated by autobuilders where you can't access - qtest.log after the fact. +- Use of ``SHOW_FAILED_TEST_OUTPUT`` is recommended for building in + continuous integration or other automated environments as it makes + it possible to see test failures in build logs. This should be + combined with either ``ctest --verbose`` or ``ctest + --output-on-failure``. -- If qpdf's build environment detects the presence of autoconf and - related tools, it will check to ensure that automatically generated - files are up-to-date with recorded checksums and fail if it detects a - discrepancy. This feature is intended to prevent you from - accidentally forgetting to regenerate automatic files after modifying - their sources. If your packaging environment automatically refreshes - automatic files, it can cause this check to fail. Suppress qpdf's - checks by passing :samp:`--disable-check-autofiles` - to :command:`/.configure`. This is safe since qpdf's - :command:`autogen.sh` just runs autotools in the - normal way. +- qpdf's install targets do not install completion files by default + since there is no standard location for them. As a packager, it's + good if you install them wherever your distribution expects such + files to go. You can find completion files to install in the + :file:`completions` directory. See the :file:`completions/README.md` + file for more information. -- QPDF's :command:`make install` does not install completion files by - default, but as a packager, it's good if you install them wherever - your distribution expects such files to go. You can find completion - files to install in the :file:`completions` directory. - -- Packagers are encouraged to install the source files from the - :file:`examples` directory along with qpdf development packages. +- Starting with qpdf 11, qpdf's default installation installs source + files from the examples directory with documentation. Prior to qpdf + 11, this was a recommendation for packagers but was not done + automatically. .. _packaging-doc: @@ -54,27 +50,34 @@ you may want to consider for your packages: - **Do nothing** When you run ``make install``, the file :file:`README-doc.txt` is - installed in ``$(docdir)``. That file tells the reader where to find - the documentation online and where to go to download offline copies - of the documentation. This is the option selected by the debian - packages. + installed in the documentation directory. That file tells the reader + where to find the documentation online and where to go to download + offline copies of the documentation. This is the option selected by + the debian packages. - **Embed pre-built documentation** You can obtain pre-built documentation and extract its contents into your distribution. This is what the Windows binary distributions - available from the qpdf release site do. You can find the pre-build + available from the qpdf release site do. You can find the pre-built documentation in the release area in the file - :file:`qpdf-{version}-doc.zip`. + :file:`qpdf-{version}-doc.zip`. For an example of this approach, + look at qpdf's GitHub actions build scripts. The + :file:`build-scripts/build-doc` script builds with + ``-DBUILD_DOC_DIST=1`` to create the documentation distribution. The + :file:`build-scripts/build-windows` script extracts it into the + build tree and builds with ``-DINSTALL_MANUAL=1`` to include it in + the installer. - **Build the documentation yourself** You can build the documentation as part of your build process. Be - sure to pass ``--enable-doc-maintenance`` to ``./configure``, and - install it with ``make doc-dist DOC_DEST=...``. This is what the - AppImage build does. The latest version of Sphinx at the time of the - initial conversion a sphinx-based documentation was 4.3.2. Older - versions are not guaranteed to work. + sure to pass ``-DBUILD_DOC_DIST=1`` and ``-DINSTALL_MANUAL=1`` to + cmake. This is what the AppImage build does. The latest version of + Sphinx at the time of the initial conversion a sphinx-based + documentation was 4.3.2. Older versions are not guaranteed to work. + +.. _doc-packaging-rationale: Documentation Packaging Rationale ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index aba081b1..36f843f7 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -1185,8 +1185,9 @@ my @bug_tests = ( ["335a", "ozz-fuzz-12152", 2], ["335b", "ozz-fuzz-14845", 2], ["fuzz-16214", "stream in object stream", 3, "--preserve-unreferenced"], - # When adding to this list, consider adding to CORPUS_FROM_TEST - # in fuzz/build.mk and updating the count in fuzz/qtest/fuzz.test. + # When adding to this list, consider adding to CORPUS_FROM_TEST in + # fuzz/CMakeLists.txt and updating the count in + # fuzz/qtest/fuzz.test. ); $n_tests += scalar(@bug_tests); foreach my $d (@bug_tests)