Update build-related documentation and comments

This commit is contained in:
Jay Berkenbilt 2022-03-12 17:32:05 -05:00 committed by Jay Berkenbilt
parent 70d0d0889b
commit f58d2a60d5
10 changed files with 744 additions and 421 deletions

View File

@ -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 <tool> 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.

View File

@ -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-<version>-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-<version>-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-<version>-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-<version>-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-<version>-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-<version>-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-<version>-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-<version>-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

View File

@ -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/<CONFIG>` (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.

View File

@ -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.

9
TODO
View File

@ -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

View File

@ -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",

View File

@ -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 <https://www.cmake.org>`__ 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 <https://www.zlib.net/>`__ or a compatible zlib implementation
- gnu make 3.81 or newer: http://www.gnu.org/software/make
- A libjpeg-compatible library such as `jpeg <https://ijg.org/>`__ or
`libjpeg-turbo <https://libjpeg-turbo.org/>`__
- 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 <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
- 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
<https://qtest.sourceforge.io>`__, 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
<http://www.gnu.org/software/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 <http://www.simplesystems.org/libtiff/>`__ command-line
utilities
- `GhostScript <https://www.ghostscript.com/>`__ 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
<https://www.sphinx-doc.org>`__ using the `Read the Docs Sphinx Theme
<https://sphinx-rtd-theme.readthedocs.io>`__. 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
<https://www.cmake.org>`__.
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 <Config>`` (where ``<Config>`` 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=<Config>``
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 <https://qtest.sourceforge.io/>`__, 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
<https://www.sphinx-doc.org>`__ using the `Read the Docs Sphinx Theme
<https://sphinx-rtd-theme.readthedocs.io>`__. 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

View File

@ -23,10 +23,20 @@ All header files are installed in the
you use ``#include <qpdf/QPDF.hh>`` 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``,

View File

@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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)