Skip to content

Commit 989ec21

Browse files
authored
Merge pull request #10497 from pradyunsg/docs/build-system-reference
Add a dedicated "Build system interface" reference section
2 parents cecad34 + 4d7d38a commit 989ec21

File tree

10 files changed

+427
-299
lines changed

10 files changed

+427
-299
lines changed

docs/html/cli/pip.rst

+1-168
Original file line numberDiff line numberDiff line change
@@ -74,178 +74,11 @@ when decision is needed.
7474
*(a)abort*
7575
Abort pip and return non-zero exit status.
7676

77-
.. _`build-interface`:
78-
7977

8078
Build System Interface
8179
======================
8280

83-
pip builds packages by invoking the build system. By default, builds will use
84-
``setuptools``, but if a project specifies a different build system using a
85-
``pyproject.toml`` file, as per :pep:`517`, pip will use that instead. As well
86-
as package building, the build system is also invoked to install packages
87-
direct from source. This is handled by invoking the build system to build a
88-
wheel, and then installing from that wheel. The built wheel is cached locally
89-
by pip to avoid repeated identical builds.
90-
91-
The current interface to the build system is via the ``setup.py`` command line
92-
script - all build actions are defined in terms of the specific ``setup.py``
93-
command line that will be run to invoke the required action.
94-
95-
Setuptools Injection
96-
~~~~~~~~~~~~~~~~~~~~
97-
98-
When :pep:`517` is not used, the supported build system is ``setuptools``.
99-
However, not all packages use ``setuptools`` in their build scripts. To support
100-
projects that use "pure ``distutils``", pip injects ``setuptools`` into
101-
``sys.modules`` before invoking ``setup.py``. The injection should be
102-
transparent to ``distutils``-based projects, but 3rd party build tools wishing
103-
to provide a ``setup.py`` emulating the commands pip requires may need to be
104-
aware that it takes place.
105-
106-
Projects using :pep:`517` *must* explicitly use setuptools - pip does not do
107-
the above injection process in this case.
108-
109-
Build System Output
110-
~~~~~~~~~~~~~~~~~~~
111-
112-
Any output produced by the build system will be read by pip (for display to the
113-
user if requested). In order to correctly read the build system output, pip
114-
requires that the output is written in a well-defined encoding, specifically
115-
the encoding the user has configured for text output (which can be obtained in
116-
Python using ``locale.getpreferredencoding``). If the configured encoding is
117-
ASCII, pip assumes UTF-8 (to account for the behaviour of some Unix systems).
118-
119-
Build systems should ensure that any tools they invoke (compilers, etc) produce
120-
output in the correct encoding. In practice - and in particular on Windows,
121-
where tools are inconsistent in their use of the "OEM" and "ANSI" codepages -
122-
this may not always be possible. pip will therefore attempt to recover cleanly
123-
if presented with incorrectly encoded build tool output, by translating
124-
unexpected byte sequences to Python-style hexadecimal escape sequences
125-
(``"\x80\xff"``, etc). However, it is still possible for output to be displayed
126-
using an incorrect encoding (mojibake).
127-
128-
Under :pep:`517`, handling of build tool output is the backend's responsibility,
129-
and pip simply displays the output produced by the backend. (Backends, however,
130-
will likely still have to address the issues described above).
131-
132-
PEP 517 and 518 Support
133-
~~~~~~~~~~~~~~~~~~~~~~~
134-
135-
As of version 10.0, pip supports projects declaring dependencies that are
136-
required at install time using a ``pyproject.toml`` file, in the form described
137-
in :pep:`518`. When building a project, pip will install the required
138-
dependencies locally, and make them available to the build process.
139-
Furthermore, from version 19.0 onwards, pip supports projects specifying the
140-
build backend they use in ``pyproject.toml``, in the form described in
141-
:pep:`517`.
142-
143-
When making build requirements available, pip does so in an *isolated
144-
environment*. That is, pip does not install those requirements into the user's
145-
``site-packages``, but rather installs them in a temporary directory which it
146-
adds to the user's ``sys.path`` for the duration of the build. This ensures
147-
that build requirements are handled independently of the user's runtime
148-
environment. For example, a project that needs a recent version of setuptools
149-
to build can still be installed, even if the user has an older version
150-
installed (and without silently replacing that version).
151-
152-
In certain cases, projects (or redistributors) may have workflows that
153-
explicitly manage the build environment. For such workflows, build isolation
154-
can be problematic. If this is the case, pip provides a
155-
``--no-build-isolation`` flag to disable build isolation. Users supplying this
156-
flag are responsible for ensuring the build environment is managed
157-
appropriately (including ensuring that all required build dependencies are
158-
installed).
159-
160-
By default, pip will continue to use the legacy (direct ``setup.py`` execution
161-
based) build processing for projects that do not have a ``pyproject.toml`` file.
162-
Projects with a ``pyproject.toml`` file will use a :pep:`517` backend. Projects
163-
with a ``pyproject.toml`` file, but which don't have a ``build-system`` section,
164-
will be assumed to have the following backend settings::
165-
166-
[build-system]
167-
requires = ["setuptools>=40.8.0", "wheel"]
168-
build-backend = "setuptools.build_meta:__legacy__"
169-
170-
.. note::
171-
172-
``setuptools`` 40.8.0 is the first version of setuptools that offers a
173-
:pep:`517` backend that closely mimics directly executing ``setup.py``.
174-
175-
If a project has ``[build-system]``, but no ``build-backend``, pip will also use
176-
``setuptools.build_meta:__legacy__``, but will expect the project requirements
177-
to include ``setuptools`` and ``wheel`` (and will report an error if the
178-
installed version of ``setuptools`` is not recent enough).
179-
180-
If a user wants to explicitly request :pep:`517` handling even though a project
181-
doesn't have a ``pyproject.toml`` file, this can be done using the
182-
``--use-pep517`` command line option. Similarly, to request legacy processing
183-
even though ``pyproject.toml`` is present, the ``--no-use-pep517`` option is
184-
available (although obviously it is an error to choose ``--no-use-pep517`` if
185-
the project has no ``setup.py``, or explicitly requests a build backend). As
186-
with other command line flags, pip recognises the ``PIP_USE_PEP517``
187-
environment veriable and a ``use-pep517`` config file option (set to true or
188-
false) to set this option globally. Note that overriding pip's choice of
189-
whether to use :pep:`517` processing in this way does *not* affect whether pip
190-
will use an isolated build environment (which is controlled via
191-
``--no-build-isolation`` as noted above).
192-
193-
Except in the case noted above (projects with no :pep:`518` ``[build-system]``
194-
section in ``pyproject.toml``), pip will never implicitly install a build
195-
system. Projects **must** ensure that the correct build system is listed in
196-
their ``requires`` list (this applies even if pip assumes that the
197-
``setuptools`` backend is being used, as noted above).
198-
199-
.. _pep-518-limitations:
200-
201-
**Historical Limitations**:
202-
203-
* ``pip<18.0``: only supports installing build requirements from wheels, and
204-
does not support the use of environment markers and extras (only version
205-
specifiers are respected).
206-
207-
* ``pip<18.1``: build dependencies using .pth files are not properly supported;
208-
as a result namespace packages do not work under Python 3.2 and earlier.
209-
210-
Future Developments
211-
~~~~~~~~~~~~~~~~~~~
212-
213-
:pep:`426` notes that the intention is to add hooks to project metadata in
214-
version 2.1 of the metadata spec, to explicitly define how to build a project
215-
from its source. Once this version of the metadata spec is final, pip will
216-
migrate to using that interface. At that point, the ``setup.py`` interface
217-
documented here will be retained solely for legacy purposes, until projects
218-
have migrated.
219-
220-
Specifically, applications should *not* expect to rely on there being any form
221-
of backward compatibility guarantees around the ``setup.py`` interface.
222-
223-
224-
Build Options
225-
~~~~~~~~~~~~~
226-
227-
The ``--global-option`` and ``--build-option`` arguments to the ``pip install``
228-
and ``pip wheel`` inject additional arguments into the ``setup.py`` command
229-
(``--build-option`` is only available in ``pip wheel``). These arguments are
230-
included in the command as follows:
231-
232-
.. tab:: Unix/macOS
233-
234-
.. code-block:: console
235-
236-
python setup.py <global_options> BUILD COMMAND <build_options>
237-
238-
.. tab:: Windows
239-
240-
.. code-block:: shell
241-
242-
py setup.py <global_options> BUILD COMMAND <build_options>
243-
244-
The options are passed unmodified, and presently offer direct access to the
245-
distutils command line. Use of ``--global-option`` and ``--build-option``
246-
should be considered as build system dependent, and may not be supported in the
247-
current form if support for alternative build systems is added to pip.
248-
81+
This is now covered in :doc:`../reference/build-system/index`.
24982

25083
.. _`General Options`:
25184

docs/html/cli/pip_install.rst

+5-75
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ with other repeatability strategies.
419419
(rare) packages that use it will cause those dependencies to be downloaded
420420
by setuptools directly, skipping pip's hash-checking. If you need to use
421421
such a package, see :ref:`Controlling
422-
setup_requires<controlling-setup-requires>`.
422+
setup_requires <controlling-setup_requires>`.
423423

424424
.. warning::
425425

@@ -537,83 +537,10 @@ the project path. This is one advantage over just using ``setup.py develop``,
537537
which creates the "egg-info" directly relative the current working directory.
538538

539539

540-
.. _`controlling-setup-requires`:
541-
542-
Controlling setup_requires
543-
--------------------------
544-
545-
Setuptools offers the ``setup_requires`` `setup() keyword
546-
<https://setuptools.readthedocs.io/en/latest/userguide/keywords.html>`_
547-
for specifying dependencies that need to be present in order for the
548-
``setup.py`` script to run. Internally, Setuptools uses ``easy_install``
549-
to fulfill these dependencies.
550-
551-
pip has no way to control how these dependencies are located. None of the
552-
package index options have an effect.
553-
554-
The solution is to configure a "system" or "personal" `Distutils configuration
555-
file
556-
<https://docs.python.org/3/install/index.html#distutils-configuration-files>`_ to
557-
manage the fulfillment.
558-
559-
For example, to have the dependency located at an alternate index, add this:
560-
561-
::
562-
563-
[easy_install]
564-
index_url = https://my.index-mirror.com
565-
566-
To have the dependency located from a local directory and not crawl PyPI, add this:
567-
568-
::
569-
570-
[easy_install]
571-
allow_hosts = ''
572-
find_links = file:///path/to/local/archives/
573-
574-
575540
Build System Interface
576541
----------------------
577542

578-
In order for pip to install a package from source, ``setup.py`` must implement
579-
the following commands::
580-
581-
setup.py egg_info [--egg-base XXX]
582-
setup.py install --record XXX [--single-version-externally-managed] [--root XXX] [--compile|--no-compile] [--install-headers XXX]
583-
584-
The ``egg_info`` command should create egg metadata for the package, as
585-
described in the setuptools documentation at
586-
https://setuptools.readthedocs.io/en/latest/userguide/commands.html#egg-info-create-egg-metadata-and-set-build-tags
587-
588-
The ``install`` command should implement the complete process of installing the
589-
package to the target directory XXX.
590-
591-
To install a package in "editable" mode (``pip install -e``), ``setup.py`` must
592-
implement the following command::
593-
594-
setup.py develop --no-deps
595-
596-
This should implement the complete process of installing the package in
597-
"editable" mode.
598-
599-
All packages will be attempted to built into wheels::
600-
601-
setup.py bdist_wheel -d XXX
602-
603-
One further ``setup.py`` command is invoked by ``pip install``::
604-
605-
setup.py clean
606-
607-
This command is invoked to clean up temporary commands from the build. (TODO:
608-
Investigate in more detail when this command is required).
609-
610-
No other build system commands are invoked by the ``pip install`` command.
611-
612-
Installing a package from a wheel does not invoke the build system at all.
613-
614-
.. _PyPI: https://pypi.org/
615-
.. _setuptools extras: https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#optional-dependencies
616-
543+
This is now covered in :doc:`../reference/build-system/index`.
617544

618545

619546
.. _`pip install Options`:
@@ -906,3 +833,6 @@ Examples
906833

907834
.. [1] This is true with the exception that pip v7.0 and v7.0.1 required quotes
908835
around specifiers containing environment markers in requirement files.
836+
837+
.. _setuptools extras: https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#optional-dependencies
838+
.. _PyPI: https://pypi.org/

docs/html/cli/pip_wheel.rst

+1-54
Original file line numberDiff line numberDiff line change
@@ -28,60 +28,7 @@ Description
2828
Build System Interface
2929
----------------------
3030

31-
In order for pip to build a wheel, ``setup.py`` must implement the
32-
``bdist_wheel`` command with the following syntax:
33-
34-
.. tab:: Unix/macOS
35-
36-
.. code-block:: shell
37-
38-
python setup.py bdist_wheel -d TARGET
39-
40-
.. tab:: Windows
41-
42-
.. code-block:: shell
43-
44-
py setup.py bdist_wheel -d TARGET
45-
46-
47-
This command must create a wheel compatible with the invoking Python
48-
interpreter, and save that wheel in the directory TARGET.
49-
50-
No other build system commands are invoked by the ``pip wheel`` command.
51-
52-
Customising the build
53-
^^^^^^^^^^^^^^^^^^^^^
54-
55-
It is possible using ``--global-option`` to include additional build commands
56-
with their arguments in the ``setup.py`` command. This is currently the only
57-
way to influence the building of C extensions from the command line. For
58-
example:
59-
60-
.. tab:: Unix/macOS
61-
62-
.. code-block:: shell
63-
64-
python -m pip wheel --global-option bdist_ext --global-option -DFOO wheel
65-
66-
.. tab:: Windows
67-
68-
.. code-block:: shell
69-
70-
py -m pip wheel --global-option bdist_ext --global-option -DFOO wheel
71-
72-
73-
will result in a build command of
74-
75-
::
76-
77-
setup.py bdist_ext -DFOO bdist_wheel -d TARGET
78-
79-
which passes a preprocessor symbol to the extension build.
80-
81-
Such usage is considered highly build-system specific and more an accident of
82-
the current implementation than a supported interface.
83-
84-
31+
This is now covered in :doc:`../reference/build-system/index`.
8532

8633
Options
8734
=======

0 commit comments

Comments
 (0)