3
3
Build systems
4
4
#############
5
5
6
+ For an overview of Python packaging including compiled packaging with a pybind11
7
+ example, along with a cookiecutter that includes several pybind11 options, see
8
+ the `Scientific Python Development Guide `_.
9
+
10
+ .. _Scientific Python Development Guide : https://learn.scientific-python.org/development/guides/packaging-compiled/
11
+
12
+ .. scikit-build-core:
13
+
14
+ Modules with CMake
15
+ ==================
16
+
17
+ A Python extension module can be created with just a few lines of code:
18
+
19
+ .. code-block :: cmake
20
+
21
+ cmake_minimum_required(VERSION 3.15...3.29)
22
+ project(example LANGUAGES CXX)
23
+
24
+ set(PYBIND11_FINDPYTHON ON)
25
+ find_package(pybind11 CONFIG REQUIRED)
26
+
27
+ pybind11_add_module(example example.cpp)
28
+ install(TARGET example DESTINATION .)
29
+
30
+ (You use the ``add_subdirectory `` instead, see the example in :ref: `cmake `.) In
31
+ this example, the code is located in a file named :file: `example.cpp `. Either
32
+ method will import the pybind11 project which provides the
33
+ ``pybind11_add_module `` function. It will take care of all the details needed
34
+ to build a Python extension module on any platform.
35
+
36
+ To build with pip, build, cibuildwheel, uv, or other Python tools, you can
37
+ add a ``pyproject.toml `` file like this:
38
+
39
+ .. code-block :: toml
40
+
41
+ [build-system]
42
+ requires = ["scikit-build-core", "pybind11"]
43
+ build-backend = "scikit_build_core.build"
44
+
45
+ [project]
46
+ name = "example"
47
+ version = "0.1.0"
48
+
49
+ You don't need setuptools files like ``MANIFEST.in ``, ``setup.py ``, or
50
+ ``setup.cfg ``, as this is not setuptools. See `scikit-build-core `_ for details.
51
+ For projects you plan to upload to PyPI, be sure to fill out the ``[project] ``
52
+ table with other important metadata as well (see `Writing pyproject.toml `_).
53
+
54
+ A working sample project can be found in the [scikit_build_example ]_
55
+ repository. An older and harder-to-maintain method is in [cmake_example ]_. More
56
+ details about our cmake support can be found below in :ref: `cmake `.
57
+
58
+ .. _scikit-build-core : https://scikit-build-core.readthedocs.io
59
+
60
+ .. [scikit_build_example ] https://github.com/pybind/scikit_build_example
61
+
62
+ .. [cmake_example ] https://github.com/pybind/cmake_example
63
+
64
+ .. _modules-meson-python :
65
+
66
+ Modules with meson-python
67
+ =========================
68
+
69
+ You can also build a package with `Meson `_ using `meson-python `_, if you prefer
70
+ that. Your ``meson.build `` file would look something like this:
71
+
72
+ .. _meson-example :
73
+
74
+ .. code-block :: meson
75
+
76
+ project(
77
+ 'example',
78
+ 'cpp',
79
+ version: '0.1.0',
80
+ default_options: [
81
+ 'cpp_std=c++11',
82
+ ],
83
+ )
84
+
85
+ py = import('python').find_installation(pure: false)
86
+ pybind11_dep = dependency('pybind11')
87
+
88
+ py.extension_module('example',
89
+ 'example.cpp',
90
+ install: true,
91
+ dependencies : [pybind11_dep],
92
+ )
93
+
94
+
95
+ And you would need a ``pyproject.toml `` file like this:
96
+
97
+ .. code-block :: toml
98
+
99
+ [build-system]
100
+ requires = ["meson-python", "pybind11"]
101
+ build-backend = "mesonpy"
102
+
103
+ Meson-python *requires * your project to be in git (or mercurial) as it uses it
104
+ for the SDist creation. For projects you plan to upload to PyPI, be sure to fill out the
105
+ ``[project] `` table as well (see `Writing pyproject.toml `_).
106
+
107
+
108
+ .. _Writing pyproject.toml : https://packaging.python.org/en/latest/guides/writing-pyproject-toml
109
+
110
+ .. _meson : https://mesonbuild.com
111
+
112
+ .. _meson-python : https://meson-python.readthedocs.io/en/latest
113
+
6
114
.. _build-setuptools :
7
115
8
- Building with setuptools
9
- ========================
116
+ Modules with setuptools
117
+ =======================
10
118
11
- For projects on PyPI, building with setuptools is the way to go . Sylvain Corlay
12
- has kindly provided an example project which shows how to set up everything,
13
- including automatic generation of documentation using Sphinx. Please refer to
14
- the [python_example ]_ repository.
119
+ For projects on PyPI, a historically popular option is setuptools . Sylvain
120
+ Corlay has kindly provided an example project which shows how to set up
121
+ everything, including automatic generation of documentation using Sphinx.
122
+ Please refer to the [python_example ]_ repository.
15
123
16
124
.. [python_example ] https://github.com/pybind/python_example
17
125
@@ -21,11 +129,11 @@ To use pybind11 inside your ``setup.py``, you have to have some system to
21
129
ensure that ``pybind11 `` is installed when you build your package. There are
22
130
four possible ways to do this, and pybind11 supports all four: You can ask all
23
131
users to install pybind11 beforehand (bad), you can use
24
- :ref: `setup_helpers-pep518 ` (good, but very new and requires Pip 10),
25
- :ref: `setup_helpers-setup_requires ` (discouraged by Python packagers now that
26
- PEP 518 is available, but it still works everywhere), or you can
27
- :ref: ` setup_helpers-copy-manually ` (always works but you have to manually sync
28
- your copy to get updates) .
132
+ :ref: `setup_helpers-pep518 ` (good), `` setup_requires= `` (discouraged), or you
133
+ can :ref: `setup_helpers-copy-manually ` (works but you have to manually sync
134
+ your copy to get updates). Third party packagers like conda-forge generally
135
+ strongly prefer the `` pyproject.toml `` method, as it gives them control over
136
+ the `` pybind11 `` version, and they may apply patches, etc .
29
137
30
138
An example of a ``setup.py `` using pybind11's helpers:
31
139
@@ -122,70 +230,41 @@ version number that includes the number of commits since your last tag and a
122
230
hash for a dirty directory. Another way to force a rebuild is purge your cache
123
231
or use Pip's ``--no-cache-dir `` option.
124
232
233
+ You also need a ``MANIFEST.in `` file to include all relevant files so that you
234
+ can make an SDist. If you use `pypa-build `_, that will build an SDist then a
235
+ wheel from that SDist by default, so you can look inside those files (wheels
236
+ are just zip files with a ``.whl `` extension) to make sure you aren't missing
237
+ files. `check-manifest `_ (setuptools specific) or `check-sdist `_ (general) are
238
+ CLI tools that can compare the SDist contents with your source control.
239
+
125
240
.. [Ccache ] https://ccache.dev
126
241
127
242
.. [setuptools_scm ] https://github.com/pypa/setuptools_scm
128
243
129
244
.. _setup_helpers-pep518 :
130
245
131
- PEP 518 requirements (Pip 10+ required)
132
- ---------------------------------------
246
+ Build requirements
247
+ ------------------
133
248
134
- If you use `PEP 518's <https://www.python.org/dev/peps/pep-0518/ >`_
135
- ``pyproject.toml `` file, you can ensure that ``pybind11 `` is available during
136
- the compilation of your project. When this file exists, Pip will make a new
137
- virtual environment, download just the packages listed here in ``requires= ``,
138
- and build a wheel (binary Python package). It will then throw away the
139
- environment, and install your wheel.
249
+ With a ``pyproject.toml `` file, you can ensure that ``pybind11 `` is available
250
+ during the compilation of your project. When this file exists, Pip will make a
251
+ new virtual environment, download just the packages listed here in
252
+ ``requires= ``, and build a wheel (binary Python package). It will then throw
253
+ away the environment, and install your wheel.
140
254
141
255
Your ``pyproject.toml `` file will likely look something like this:
142
256
143
257
.. code-block :: toml
144
258
145
259
[build-system]
146
- requires = ["setuptools>=42 ", "pybind11>=2.6.1 "]
260
+ requires = ["setuptools", "pybind11"]
147
261
build-backend = "setuptools.build_meta"
148
262
149
- .. note ::
150
-
151
- The main drawback to this method is that a `PEP 517 `_ compliant build tool,
152
- such as Pip 10+, is required for this approach to work; older versions of
153
- Pip completely ignore this file. If you distribute binaries (called wheels
154
- in Python) using something like `cibuildwheel `_, remember that ``setup.py ``
155
- and ``pyproject.toml `` are not even contained in the wheel, so this high
156
- Pip requirement is only for source builds, and will not affect users of
157
- your binary wheels. If you are building SDists and wheels, then
158
- `pypa-build `_ is the recommended official tool.
159
-
160
263
.. _PEP 517 : https://www.python.org/dev/peps/pep-0517/
161
- .. _cibuildwheel : https://cibuildwheel.readthedocs.io
162
- .. _pypa-build : https://pypa-build.readthedocs.io/en/latest/
163
-
164
- .. _setup_helpers-setup_requires :
165
-
166
- Classic ``setup_requires ``
167
- --------------------------
168
-
169
- If you want to support old versions of Pip with the classic
170
- ``setup_requires=["pybind11"] `` keyword argument to setup, which triggers a
171
- two-phase ``setup.py `` run, then you will need to use something like this to
172
- ensure the first pass works (which has not yet installed the ``setup_requires ``
173
- packages, since it can't install something it does not know about):
174
-
175
- .. code-block :: python
176
-
177
- try :
178
- from pybind11.setup_helpers import Pybind11Extension
179
- except ImportError :
180
- from setuptools import Extension as Pybind11Extension
181
-
182
-
183
- It doesn't matter that the Extension class is not the enhanced subclass for the
184
- first pass run; and the second pass will have the ``setup_requires ``
185
- requirements.
186
-
187
- This is obviously more of a hack than the PEP 518 method, but it supports
188
- ancient versions of Pip.
264
+ .. _cibuildwheel : https://cibuildwheel.pypa.io
265
+ .. _pypa-build : https://build.pypa.io/en/latest/
266
+ .. _check-manifest : https://pypi.io/project/check-manifest
267
+ .. _check-sdist : https://pypi.io/project/check-sdist
189
268
190
269
.. _setup_helpers-copy-manually :
191
270
@@ -231,39 +310,30 @@ the C++ source file. Python is then able to find the module and load it.
231
310
232
311
.. [cppimport ] https://github.com/tbenthompson/cppimport
233
312
313
+
314
+
234
315
.. _cmake :
235
316
236
317
Building with CMake
237
318
===================
238
319
239
320
For C++ codebases that have an existing CMake-based build system, a Python
240
- extension module can be created with just a few lines of code:
241
-
242
- .. code-block :: cmake
243
-
244
- cmake_minimum_required(VERSION 3.5...3.29)
245
- project(example LANGUAGES CXX)
321
+ extension module can be created with just a few lines of code, as seen above in
322
+ the module section. Pybind11 currently supports a lower minimum if you don't
323
+ use the modern FindPython, though be aware that CMake 3.27 removed the old
324
+ mechanism, so pybind11 will automatically switch if the old mechanism is not
325
+ available. Please opt into the new mechanism if at all possible. Our default
326
+ may change in future versions. This is the minimum required:
246
327
247
- add_subdirectory(pybind11)
248
- pybind11_add_module(example example.cpp)
249
-
250
- This assumes that the pybind11 repository is located in a subdirectory named
251
- :file: `pybind11 ` and that the code is located in a file named :file: `example.cpp `.
252
- The CMake command ``add_subdirectory `` will import the pybind11 project which
253
- provides the ``pybind11_add_module `` function. It will take care of all the
254
- details needed to build a Python extension module on any platform.
255
328
256
- A working sample project, including a way to invoke CMake from :file: `setup.py ` for
257
- PyPI integration, can be found in the [cmake_example ]_ repository.
258
-
259
- .. [cmake_example ] https://github.com/pybind/cmake_example
260
329
261
330
.. versionchanged :: 2.6
262
331
CMake 3.4+ is required.
263
332
264
333
.. versionchanged :: 2.11
265
334
CMake 3.5+ is required.
266
335
336
+
267
337
Further information can be found at :doc: `cmake/index `.
268
338
269
339
pybind11_add_module
@@ -616,6 +686,13 @@ Building with Bazel
616
686
You can build with the Bazel build system using the `pybind11_bazel
617
687
<https://github.com/pybind/pybind11_bazel> `_ repository.
618
688
689
+ Building with Meson
690
+ ===================
691
+
692
+ You can use Meson, which has support for ``pybind11 `` as a dependency (internally
693
+ relying on our ``pkg-config `` support). See the :ref: `module example above <meson-example >`.
694
+
695
+
619
696
Generating binding code automatically
620
697
=====================================
621
698
0 commit comments