Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 94 additions & 1 deletion docs/compiling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@ function with the following signature:
.. code-block:: cmake

pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
[NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])
[NO_EXTRAS] [THIN_LTO] [OPT_SIZE] [PRECOMPILE | NO_PRECOMPILE]
source1 [source2 ...])

This function behaves very much like CMake's builtin ``add_library`` (in fact,
it's a wrapper function around that command). It will add a library target
Expand Down Expand Up @@ -404,6 +405,98 @@ optimizations remain disabled.

.. _ThinLTO: http://clang.llvm.org/docs/ThinLTO.html

.. _precompile-mode:

Pre-compiling part of pybind11
------------------------------

pybind11 is header-only by default: every translation unit compiles its own
copy of the non-template implementation. The opt-in *precompiled* mode
compiles that implementation once, into a static library built inside your
own project with your own flags. This reduces the build time, most of all for
projects with many translation units or many modules in one build.

.. code-block:: cmake

pybind11_add_module(example PRECOMPILE example.cpp)

The first ``PRECOMPILE`` target creates the library target
``pybind11::precompiled``; further targets reuse it. Set the CMake variable
``PYBIND11_PRECOMPILE`` to make it the default for all
``pybind11_add_module`` calls; use ``NO_PRECOMPILE`` on a target to opt back
out. For targets you create yourself, call the ``pybind11_precompile()``
function and link ``pybind11::precompiled`` PRIVATE; the target carries the
required ``PYBIND11_PRECOMPILED`` compile definition PUBLIC, so your sources
also get it.

Requirements and caveats:

* The library and every module linking it must agree on the configuration
macros ``PYBIND11_INTERNALS_VERSION``, ``Py_GIL_DISABLED``,
``PYBIND11_SIMPLE_GIL_MANAGEMENT``,
``PYBIND11_DETAILED_ERROR_MESSAGES`` (defaults on in debug builds),
``PYBIND11_HAS_SUBINTERPRETER_SUPPORT``, and
``PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET``. A mismatch produces one
readable undefined symbol at link time referencing
``pybind11_precompiled_config``.
* Configuration macros that only change code inside the library (for example
``PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING``) must be defined when the
library is compiled; a definition only on your module has no effect.
* The library picks up your directory-level flags and C++ standard when it is
first created, so set those before the first ``PRECOMPILE`` target. A
status message reports the directory that created the library.
* The library is not compiled with link-time optimization, and the per-target
``THIN_LTO`` and ``OPT_SIZE`` options of ``pybind11_add_module`` do not
apply to it. To change this, call ``pybind11_precompile()`` yourself and
set the properties on the created target, ``pybind11_precompiled`` (the
real target behind the ``pybind11::precompiled`` alias; CMake does not let
you set properties through an alias):

.. code-block:: cmake

pybind11_precompile()
set_target_properties(pybind11_precompiled PROPERTIES
INTERPROCEDURAL_OPTIMIZATION ON)

* The library is static and per-build-tree; it is never installed or shared
between projects. Each extension module links its own copy, which keeps
pybind11's per-module state the same as in header-only mode.
* Not available with ``PYBIND11_NOPYTHON`` (the library needs Python
headers).

For build systems other than CMake, the same sources ship with the pybind11
package: compile ``pybind11_combined.cpp`` from the directory reported by
``python -m pybind11 --srcdir`` (also available as
``pybind11.get_source_dir()`` and the ``srcdir`` pkg-config variable) into
a static library or into your extension, and define
``PYBIND11_PRECOMPILED`` for every translation unit.

With Meson, build the library once per build tree and link it into each
extension module, the same as the CMake path:

.. code-block:: meson

pybind11_dep = dependency('pybind11')
pybind11_src = run_command(py, ['-m', 'pybind11', '--srcdir'],
check : true).stdout().strip()

pybind11_precompiled = static_library('pybind11_precompiled',
pybind11_src / 'pybind11_combined.cpp',
cpp_args : ['-DPYBIND11_PRECOMPILED'],
gnu_symbol_visibility : 'hidden',
dependencies : [pybind11_dep, py.dependency()])

py.extension_module('example', 'example.cpp',
cpp_args : ['-DPYBIND11_PRECOMPILED'],
link_with : pybind11_precompiled,
dependencies : [pybind11_dep])

The configuration-macro rules above apply here too: the static library and
every module that links it must be compiled with the same configuration
macros, and ``-DPYBIND11_PRECOMPILED`` must appear in both ``cpp_args``
lists. (``pybind11_dep.get_variable('srcdir')`` also reports the source
directory when Meson finds pybind11 through pkg-config.)

Configuration variables
-----------------------

Expand Down
7 changes: 6 additions & 1 deletion docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,12 @@ and the binding code
How can I reduce the build time?
================================

It's good practice to split binding code over multiple files, as in the
First, consider the opt-in precompiled mode: it compiles the non-template
part of pybind11 once per project instead of once for each translation unit.
In CMake, this is one keyword on ``pybind11_add_module``. See
:ref:`precompile-mode`.

It's also good practice to split binding code over multiple files, as in the
following example:

:file:`example.cpp`:
Expand Down
20 changes: 20 additions & 0 deletions tools/pybind11Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ This module sets the following variables in your project:
Directories where pybind11 and python headers are located.
``pybind11_INCLUDE_DIR``
Directory where pybind11 headers are located.
``pybind11_SRC_DIR``
Directory where the library sources for the opt-in precompiled mode are
located (used by ``pybind11_precompile``).
``pybind11_DEFINITIONS``
Definitions necessary to use pybind11, namely USING_pybind11.
``pybind11_LIBRARIES``
Expand Down Expand Up @@ -147,6 +150,7 @@ This module defines the following commands to assist with creating Python module
pybind11_add_module(<target>
[STATIC|SHARED|MODULE]
[THIN_LTO] [OPT_SIZE] [NO_EXTRAS] [WITHOUT_SOABI]
[PRECOMPILE|NO_PRECOMPILE]
<files>...
)

Expand All @@ -162,6 +166,22 @@ default is ``MODULE``. There are several options:
Disable the SOABI component (``PYBIND11_FINDPYTHON`` mode only).
``NO_EXTRAS``
Disable all extras, exit immediately after making the module.
``PRECOMPILE``
Link the target against the ``pybind11::precompiled`` static library
(created on first use); ``NO_PRECOMPILE`` opts a target out when the
``PYBIND11_PRECOMPILE`` variable enables it globally.

pybind11_precompile
^^^^^^^^^^^^^^^^^^^

.. code-block:: cmake

pybind11_precompile()

Create the ``pybind11::precompiled`` static library from the shipped sources
(once per build tree). ``pybind11_add_module(... PRECOMPILE)`` calls this for
you; call it directly to link ``pybind11::precompiled`` into your own
targets.

pybind11_strip
^^^^^^^^^^^^^^
Expand Down
Loading