Skip to content

Commit 8a3b546

Browse files
committed
docs: document the opt-in precompiled mode
Assisted-by: ClaudeCode:claude-fable-5
1 parent 9b2f2fa commit 8a3b546

3 files changed

Lines changed: 85 additions & 2 deletions

File tree

docs/compiling.rst

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ function with the following signature:
348348
.. code-block:: cmake
349349
350350
pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
351-
[NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])
351+
[NO_EXTRAS] [THIN_LTO] [OPT_SIZE] [PRECOMPILE | NO_PRECOMPILE]
352+
source1 [source2 ...])
352353
353354
This function behaves very much like CMake's builtin ``add_library`` (in fact,
354355
it's a wrapper function around that command). It will add a library target
@@ -404,6 +405,64 @@ optimizations remain disabled.
404405

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

408+
.. _precompile-mode:
409+
410+
Pre-compiling part of pybind11
411+
------------------------------
412+
413+
pybind11 is header-only by default: every translation unit compiles its own
414+
copy of the non-template implementation. The opt-in *precompiled* mode
415+
compiles that implementation once, into a static library that is built inside
416+
your own project with your own flags, which reduces build time (especially
417+
for projects with many translation units or many modules in one build).
418+
419+
.. code-block:: cmake
420+
421+
pybind11_add_module(example PRECOMPILE example.cpp)
422+
423+
The first ``PRECOMPILE`` target creates the library target
424+
``pybind11::precompiled``; further targets reuse it. Set the CMake variable
425+
``PYBIND11_PRECOMPILE`` to make it the default for all
426+
``pybind11_add_module`` calls; use ``NO_PRECOMPILE`` on a target to opt back
427+
out. For targets you create yourself, call the ``pybind11_precompile()``
428+
function and link ``pybind11::precompiled`` PRIVATE; the target carries the
429+
required ``PYBIND11_PRECOMPILED`` compile definition PUBLIC, so your sources
430+
are compiled correctly automatically.
431+
432+
Requirements and caveats:
433+
434+
* The library and every module linking it must agree on the configuration
435+
macros ``PYBIND11_INTERNALS_VERSION``, ``Py_GIL_DISABLED``,
436+
``PYBIND11_SIMPLE_GIL_MANAGEMENT``, and
437+
``PYBIND11_DETAILED_ERROR_MESSAGES`` (the last one defaults on in debug
438+
builds). A mismatch produces one readable undefined symbol at link time
439+
referencing ``pybind11_precompiled_config``.
440+
* The library picks up your directory-level flags and C++ standard when it is
441+
first created, so set those before the first ``PRECOMPILE`` target.
442+
* The library is static and per-build-tree by design; it is never installed
443+
or shared between projects. Each extension module links its own copy,
444+
which preserves pybind11's per-module state exactly as in header-only
445+
mode.
446+
* Not available with ``PYBIND11_NOPYTHON`` (the library needs Python
447+
headers).
448+
449+
For build systems other than CMake, the same sources ship with the pybind11
450+
package: compile ``pybind11_combined.cpp`` from the directory reported by
451+
``python -m pybind11 --srcdir`` (also available as
452+
``pybind11.get_source_dir()`` and the ``srcdir`` pkg-config variable) into
453+
your extension and define ``PYBIND11_PRECOMPILED`` for every translation
454+
unit. With setuptools, ``Pybind11Extension(..., precompile=True)`` does this
455+
for you. With Meson:
456+
457+
.. code-block:: meson
458+
459+
pybind11_dep = dependency('pybind11')
460+
pybind11_src = pybind11_dep.get_variable('srcdir')
461+
py.extension_module('example',
462+
['example.cpp', pybind11_src / 'pybind11_combined.cpp'],
463+
cpp_args : ['-DPYBIND11_PRECOMPILED'],
464+
dependencies : [pybind11_dep])
465+
407466
Configuration variables
408467
-----------------------
409468

docs/faq.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ and the binding code
7979
How can I reduce the build time?
8080
================================
8181

82-
It's good practice to split binding code over multiple files, as in the
82+
First, consider the opt-in precompiled mode: building the non-template part
83+
of pybind11 once per project instead of once per translation unit is the
84+
cheapest large win. See :ref:`precompile-mode`.
85+
86+
It's also good practice to split binding code over multiple files, as in the
8387
following example:
8488

8589
:file:`example.cpp`:

tools/pybind11Config.cmake.in

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ This module sets the following variables in your project:
1818
Directories where pybind11 and python headers are located.
1919
``pybind11_INCLUDE_DIR``
2020
Directory where pybind11 headers are located.
21+
``pybind11_SRC_DIR``
22+
Directory where the library sources for the opt-in precompiled mode are
23+
located (used by ``pybind11_precompile``).
2124
``pybind11_DEFINITIONS``
2225
Definitions necessary to use pybind11, namely USING_pybind11.
2326
``pybind11_LIBRARIES``
@@ -147,6 +150,7 @@ This module defines the following commands to assist with creating Python module
147150
pybind11_add_module(<target>
148151
[STATIC|SHARED|MODULE]
149152
[THIN_LTO] [OPT_SIZE] [NO_EXTRAS] [WITHOUT_SOABI]
153+
[PRECOMPILE|NO_PRECOMPILE]
150154
<files>...
151155
)
152156
@@ -162,6 +166,22 @@ default is ``MODULE``. There are several options:
162166
Disable the SOABI component (``PYBIND11_FINDPYTHON`` mode only).
163167
``NO_EXTRAS``
164168
Disable all extras, exit immediately after making the module.
169+
``PRECOMPILE``
170+
Link the target against the ``pybind11::precompiled`` static library
171+
(created on first use); ``NO_PRECOMPILE`` opts a target out when the
172+
``PYBIND11_PRECOMPILE`` variable enables it globally.
173+
174+
pybind11_precompile
175+
^^^^^^^^^^^^^^^^^^^
176+
177+
.. code-block:: cmake
178+
179+
pybind11_precompile()
180+
181+
Create the ``pybind11::precompiled`` static library from the shipped sources
182+
(once per build tree). ``pybind11_add_module(... PRECOMPILE)`` calls this for
183+
you; call it directly to link ``pybind11::precompiled`` into your own
184+
targets.
165185
166186
pybind11_strip
167187
^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)