blob: 71e0eb1dc112fa7e8794c8e60d19d53a0b4ce3b4 [file] [log] [blame]
Wyatt Heplerb3ea9802021-02-23 09:46:09 -08001.. _module-pw_build-python:
2
3-------------------
4Python GN templates
5-------------------
6The Python build is implemented with GN templates defined in
Joe Ethierfbe66152021-03-31 16:02:36 -07007``pw_build/python.gni``. See the .gni file for complete usage documentation.
Wyatt Heplerb3ea9802021-02-23 09:46:09 -08008
9.. seealso:: :ref:`docs-python-build`
10
11pw_python_package
12=================
13The main Python template is ``pw_python_package``. Each ``pw_python_package``
14target represents a Python package. As described in
15:ref:`module-pw_build-python-target`, each ``pw_python_package`` expands to
16several subtargets. In summary, these are:
17
18- ``<name>`` - Represents the files themselves
19- ``<name>.lint`` - Runs static analysis
20- ``<name>.tests`` - Runs all tests for this package
21- ``<name>.install`` - Installs the package
22- ``<name>.wheel`` - Builds a Python wheel
23
Wyatt Heplerb85cda42021-04-07 13:13:15 -070024GN permits using abbreviated labels when the target name matches the directory
25name (e.g. ``//foo`` for ``//foo:foo``). For consistency with this, Python
26package subtargets are aliased to the directory when the target name is the
27same as the directory. For example, these two labels are equivalent:
28
29.. code-block::
30
31 //path/to/my_python_package:my_python_package.tests
32 //path/to/my_python_package:tests
33
Wyatt Heplerf6f74f42021-04-13 19:26:20 -070034The actions in a ``pw_python_package`` (e.g. installing packages and running
35Pylint) are done within a single GN toolchain to avoid duplication in
36multi-toolchain builds. This toolchain can be set with the
Joe Ethierfbe66152021-03-31 16:02:36 -070037``pw_build_PYTHON_TOOLCHAIN`` GN arg, which defaults to
38``$dir_pw_build/python_toolchain:python``.
Wyatt Heplerf6f74f42021-04-13 19:26:20 -070039
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080040Arguments
41---------
42- ``setup`` - List of setup file paths (setup.py or pyproject.toml & setup.cfg),
43 which must all be in the same directory.
Wyatt Heplerb85cda42021-04-07 13:13:15 -070044- ``generate_setup``: As an alternative to ``setup``, generate setup files with
45 the keywords in this scope. ``name`` is required. For example:
46
47 .. code-block::
48
49 generate_setup = {
50 name = "a_nifty_package"
51 version = "1.2a"
52 }
53
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080054- ``sources`` - Python sources files in the package.
55- ``tests`` - Test files for this Python package.
56- ``python_deps`` - Dependencies on other pw_python_packages in the GN build.
57- ``python_test_deps`` - Test-only pw_python_package dependencies.
58- ``other_deps`` - Dependencies on GN targets that are not pw_python_packages.
59- ``inputs`` - Other files to track, such as package_data.
Wyatt Heplerdcfcecf2021-03-01 08:36:19 -080060- ``proto_library`` - A pw_proto_library target to embed in this Python package.
Wyatt Heplerb85cda42021-04-07 13:13:15 -070061 ``generate_setup`` is required in place of setup if proto_library is used. See
Wyatt Heplerdcfcecf2021-03-01 08:36:19 -080062 :ref:`module-pw_protobuf_compiler-add-to-python-package`.
Wyatt Heplerc2ce5242021-03-17 08:42:14 -070063- ``static_analysis`` List of static analysis tools to run; ``"*"`` (default)
64 runs all tools. The supported tools are ``"mypy"`` and ``"pylint"``.
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080065- ``pylintrc`` - Optional path to a pylintrc configuration file to use. If not
66 provided, Pylint's default rcfile search is used. Pylint is executed
67 from the package's setup directory, so pylintrc files in that directory
68 will take precedence over others.
69- ``mypy_ini`` - Optional path to a mypy configuration file to use. If not
70 provided, mypy's default configuration file search is used. mypy is
71 executed from the package's setup directory, so mypy.ini files in that
72 directory will take precedence over others.
73
74Example
75-------
76This is an example Python package declaration for a ``pw_my_module`` module.
77
78.. code-block::
79
80 import("//build_overrides/pigweed.gni")
81
82 import("$dir_pw_build/python.gni")
83
84 pw_python_package("py") {
85 setup = [ "setup.py" ]
86 sources = [
87 "pw_my_module/__init__.py",
88 "pw_my_module/alfa.py",
89 "pw_my_module/bravo.py",
90 "pw_my_module/charlie.py",
91 ]
92 tests = [
93 "alfa_test.py",
94 "charlie_test.py",
95 ]
96 python_deps = [
97 "$dir_pw_status/py",
98 ":some_protos.python",
99 ]
100 python_test_deps = [ "$dir_pw_build/py" ]
101 pylintrc = "$dir_pigweed/.pylintrc"
102 }
103
104pw_python_script
105================
106A ``pw_python_script`` represents a set of standalone Python scripts and/or
107tests. These files support all of the arguments of ``pw_python_package`` except
108those ``setup``. These targets can be installed, but this only installs their
109dependencies.
110
Wyatt Hepler473efe02021-05-04 14:15:16 -0700111``pw_python_script`` allows creating a
112:ref:`pw_python_action <module-pw_build-python-action>` associated with the
113script. To create an action, pass an ``action`` scope to ``pw_python_script``.
114If there is only a single source file, it serves as the action's ``script`` by
115default.
116
117An action in ``pw_python_script`` can always be replaced with a standalone
118``pw_python_action``, but using the embedded action has some advantages:
119
120- The embedded action target bridges the gap between actions and Python targets.
121 A Python script can be expressed in a single, concise GN target, rather than
122 in two overlapping, dependent targets.
123- The action automatically depends on the ``pw_python_script``. This ensures
124 that the script's dependencies are installed and the action automatically
125 reruns when the script's sources change, without needing to specify a
126 dependency, a step which is easy to forget.
127- Using a ``pw_python_script`` with an embedded action is a simple way to check
128 an existing action's script with Pylint or Mypy or to add tests.
129
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800130pw_python_group
131===============
132Represents a group of ``pw_python_package`` and ``pw_python_script`` targets.
133These targets do not add any files. Their subtargets simply forward to those of
134their dependencies.
135
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800136pw_python_requirements
137======================
138Represents a set of local and PyPI requirements, with no associated source
139files. These targets serve the role of a ``requirements.txt`` file.
Joe Ethierfbe66152021-03-31 16:02:36 -0700140
141.. _module-pw_build-python-dist:
142
143---------------------
144Python distributables
145---------------------
146Pigweed also provides some templates to make it easier to bundle Python packages
147for deployment. These templates are found in ``pw_build/python_dist.gni``. See
148the .gni file for complete usage doclumentation.
149
150pw_python_wheels
151================
152Collects Python wheels for one or more ``pw_python_package`` targets, plus any
153additional ``pw_python_package`` targets they depend on, directly or indirectly.
154Note that this does not include Python dependencies that come from outside the
155GN build, like packages from PyPI, for example. Those should still be declared
156in the package's ``setup.py`` file as usual.
157
158Arguments
159---------
160- ``packages`` - List of ``pw_python_package`` targets whose wheels should be
161 included; their dependencies will be pulled in as wheels also.
162
163Wheel collection under the hood
164-------------------------------
165The ``.wheel`` subtarget of every ``pw_python_package`` generates a wheel
166(``.whl``) for the Python package. The ``pw_python_wheels`` template figures
167out which wheels to collect by traversing the ``pw_python_package_wheels``
168`GN metadata
Rob Mohr463700d2021-05-22 10:31:03 -0700169<https://gn.googlesource.com/gn/+/HEAD/docs/reference.md#var_metadata>`_ key,
Joe Ethierfbe66152021-03-31 16:02:36 -0700170which lists the output directory for each wheel.
171
172The ``pw_mirror_tree`` template is then used to collect wheels in an output
173directory:
174
175.. code-block::
176
177 import("$dir_pw_build/mirror_tree.gni")
178
179 pw_mirror_tree("my_wheels") {
180 path_data_keys = [ "pw_python_package_wheels" ]
181 deps = [ ":python_packages.wheel" ]
182 directory = "$root_out_dir/the_wheels"
183 }
184
185pw_python_zip_with_setup
186========================
187Generates a ``.zip`` archive suitable for deployment outside of the project's
188developer environment. The generated ``.zip`` contains Python wheels
189(``.whl`` files) for one or more ``pw_python_package`` targets, plus wheels for
190any additional ``pw_python_package`` targets in the GN build they depend on,
191directly or indirectly. Dependencies from outside the GN build, such as packages
192from PyPI, must be listed in packages' ``setup.py`` files as usual.
193
194The ``.zip`` also includes simple setup scripts for Linux,
195MacOS, and Windows. The setup scripts automatically create a Python virtual
196environment and install the whole collection of wheels into it using ``pip``.
197
198Optionally, additional files and directories can be included in the archive.
199
200Arguments
201---------
202- ``packages`` - A list of `pw_python_package` targets whose wheels should be
203 included; their dependencies will be pulled in as wheels also.
204- ``inputs`` - An optional list of extra files to include in the generated
205 ``.zip``, formatted the same way as the ``inputs`` argument to ``pw_zip``
206 targets.
207- ``dirs`` - An optional list of directories to include in the generated
208 ``.zip``, formatted the same was as the ``dirs`` argument to ``pw_zip``
209 targets.
210
211Example
212-------
213
214.. code-block::
215
216 import("//build_overrides/pigweed.gni")
217
218 import("$dir_pw_build/python_dist.gni")
219
220 pw_python_zip_with_setup("my_tools") {
221 packages = [ ":some_python_package" ]
222 inputs = [ "$dir_pw_build/python_dist/README.md > /${target_name}/" ]
223 }