aboutsummaryrefslogtreecommitdiffstats
path: root/manual/installation.rst
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-12-18 15:01:52 +0100
committerJay Berkenbilt <ejb@ql.org>2021-12-18 17:05:51 +0100
commit10fb619d3e0618528b7ac6c20cad6262020cf947 (patch)
treec893fedff351e809edead840376e8648f1cc28ff /manual/installation.rst
parentf3d1138b8ab64c6a26e1dd5f77a644b19016a30d (diff)
downloadqpdf-10fb619d3e0618528b7ac6c20cad6262020cf947.tar.zst
Split documentation into multiple pages, change theme
Diffstat (limited to 'manual/installation.rst')
-rw-r--r--manual/installation.rst342
1 files changed, 342 insertions, 0 deletions
diff --git a/manual/installation.rst b/manual/installation.rst
new file mode 100644
index 00000000..8862034d
--- /dev/null
+++ b/manual/installation.rst
@@ -0,0 +1,342 @@
+.. _ref.installing:
+
+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.
+
+.. _ref.prerequisites:
+
+System Requirements
+-------------------
+
+The qpdf package has few external dependencies. In order to build qpdf,
+the following packages are required:
+
+- A C++ compiler that supports C++-14.
+
+- zlib: http://www.zlib.net/
+
+- jpeg: http://www.ijg.org/files/ or https://libjpeg-turbo.org/
+
+- *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 make 3.81 or newer: http://www.gnu.org/software/make
+
+- 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.
+
+- 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`.
+
+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.
+
+- libtiff: http://www.remotesensing.org/libtiff/
+
+- GhostScript version 8.60 or newer: http://www.ghostscript.com
+
+If you do not enable this, then you do not need to have tiff and
+ghostscript.
+
+Pre-built documentation is distributed with qpdf, so you should
+generally not need to rebuild the documentation. In order to build the
+documentation from source, you need to install `Sphinx
+<https://sphinx-doc.org>`__. 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.
+
+.. _ref.building:
+
+Build Instructions
+------------------
+
+Building qpdf on UNIX is generally just a matter of running
+
+::
+
+ ./configure
+ make
+
+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.
+
+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`.
+
+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.
+
+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`.
+
+.. _ref.crypto:
+
+Crypto Providers
+----------------
+
+Starting with qpdf 9.1.0, the qpdf library can be built with multiple
+implementations of providers of cryptographic functions, which we refer
+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.
+
+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.
+
+.. _ref.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.
+
+.. _ref.crypto.runtime:
+
+Runtime Crypto Provider Selection
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can use the :samp:`--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.
+
+.. _ref.crypto.develop:
+
+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`.
+
+.. _ref.crypto.design:
+
+Crypto Provider Design Notes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section describes a few bits of rationale for why the crypto
+provider interface was set up the way it was. You don't need to know any
+of this information, but it's provided for the record and in case it's
+interesting.
+
+As a general rule, I want to avoid as much as possible including large
+blocks of code that are conditionally compiled such that, in most
+builds, some code is never built. This is dangerous because it makes it
+very easy for invalid code to creep in unnoticed. As such, I want it to
+be possible to build qpdf with all available crypto providers, and this
+is the way I build qpdf for local development. At the same time, if a
+particular packager feels that it is a security liability for qpdf to
+use crypto functionality from other than a library that gets
+considerable scrutiny for this specific purpose (such as gnutls,
+openssl, or nettle), then I want to give that packager the ability to
+completely disable qpdf's native implementation. Or if someone wants to
+avoid adding a dependency on one of the external crypto providers, I
+don't want the availability of the provider to impose additional
+external dependencies within that environment. Both of these are
+situations that I know to be true for some users of qpdf.
+
+I want registration and selection of crypto providers to be thread-safe,
+and I want it to work deterministically for a developer to provide their
+own crypto provider and be able to set it up as the default. This was
+the primary motivation behind requiring C++-11 as doing so enabled me to
+exploit the guaranteed thread safety of local block static
+initialization. The ``QPDFCryptoProvider`` class uses a singleton
+pattern with thread-safe initialization to create the singleton instance
+of ``QPDFCryptoProvider`` and exposes only static methods in its public
+interface. In this way, if a developer wants to call any
+``QPDFCryptoProvider`` methods, the library guarantees the
+``QPDFCryptoProvider`` is fully initialized and all built-in crypto
+providers are registered. Making ``QPDFCryptoProvider`` actually know
+about all the built-in providers may seem a bit sad at first, but this
+choice makes it extremely clear exactly what the initialization behavior
+is. There's no question about provider implementations automatically
+registering themselves in a nondeterministic order. It also means that
+implementations do not need to know anything about the provider
+interface, which makes them easier to test in isolation. Another
+advantage of this approach is that a developer who wants to develop
+their own crypto provider can do so in complete isolation from the qpdf
+library and, with just two calls, can make qpdf use their provider in
+their application. If they decided to contribute their code, plugging it
+into the qpdf library would require a very small change to qpdf's source
+code.
+
+The decision to make the crypto provider selectable at runtime was one I
+struggled with a little, but I decided to do it for various reasons.
+Allowing an end user to switch crypto providers easily could be very
+useful for reproducing a potential bug. If a user reports a bug that
+some cryptographic thing is broken, I can easily ask that person to try
+with the ``QPDF_CRYPTO_PROVIDER`` variable set to different values. The
+same could apply in the event of a performance problem. This also makes
+it easier for qpdf's own test suite to exercise code with different
+providers without having to make every program that links with qpdf
+aware of the possibility of multiple providers. In qpdf's continuous
+integration environment, the entire test suite is run for each supported
+crypto provider. This is made simple by being able to select the
+provider using an environment variable.
+
+Finally, making crypto providers selectable in this way establish a
+pattern that I may follow again in the future for stream filter
+providers. One could imagine a future enhancement where someone could
+provide their own implementations for basic filters like
+``/FlateDecode`` or for other filters that qpdf doesn't support.
+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.
+
+.. _ref.packaging:
+
+Notes for Packagers
+-------------------
+
+If you are packaging qpdf for an operating system distribution, here are
+some things you may want to keep in mind:
+
+- Starting in qpdf version 9.1.1, qpdf no longer has a runtime
+ dependency on perl. This is because fix-qdf was rewritten in C++.
+ However, qpdf still has a build-time dependency on perl.
+
+- Make sure you are getting the intended behavior with regard to crypto
+ providers. Read :ref:`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.
+
+- 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 :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.