blob: 9fa2944245df595282f13b09191c7a8f7e6c64f4 [file] [log] [blame]
Rob Mohr84f234e2019-12-06 09:16:50 -08001.. default-domain:: cpp
2
3.. highlight:: sh
4
Alexei Frolovf6753902020-07-08 11:01:45 -07005.. _chapter-pw-build:
Alexei Frolov9d169d52020-03-03 17:20:06 -08006
Rob Mohr84f234e2019-12-06 09:16:50 -08007--------
8pw_build
9--------
Alexei Frolov9d169d52020-03-03 17:20:06 -080010Pigweed's modules aim to be easily integratable into both new and existing
11embedded projects. To that goal, the ``pw_build`` module provides support for
12multiple build systems. Our personal favorite is `GN`_/`Ninja`_, which is used
13by upstream developers for its speed and flexibility. `CMake`_ and `Bazel`_
14build files are also provided by all modules, allowing Pigweed to be added to a
15project with minimal effort.
Rob Mohr84f234e2019-12-06 09:16:50 -080016
17.. _GN: https://gn.googlesource.com/gn/
18.. _Ninja: https://ninja-build.org/
Alexei Frolov9d169d52020-03-03 17:20:06 -080019.. _CMake: https://cmake.org/
Rob Mohr84f234e2019-12-06 09:16:50 -080020.. _Bazel: https://bazel.build/
21
Alexei Frolov9d169d52020-03-03 17:20:06 -080022Beyond just compiling code, Pigweed’s GN build system can also:
23
24* Generate HTML documentation, via our Sphinx integration (with ``pw_docgen``)
Armando Montanez0054a9b2020-03-13 13:06:24 -070025* Display memory usage report cards (with ``pw_bloat``)
Alexei Frolov9d169d52020-03-03 17:20:06 -080026* Incrementally run unit tests after code changes (with ``pw_target_runner``)
27* And more!
28
29These are only supported in the GN build, so we recommend using it if possible.
30
Rob Mohr84f234e2019-12-06 09:16:50 -080031GN / Ninja
32==========
Armando Montanezbcc194b2020-03-10 10:23:18 -070033The GN / Ninja build system is the primary build system used for upstream
34Pigweed development, and is the most tested and feature-rich build system
35Pigweed offers.
Rob Mohr84f234e2019-12-06 09:16:50 -080036
Armando Montanezbcc194b2020-03-10 10:23:18 -070037This module's ``build.gn`` file contains a number of C/C++ ``config``
38declarations that are used by upstream Pigweed to set some architecture-agnostic
39compiler defaults. (See Pigweed's ``//BUILDCONFIG.gn``)
40
Armando Montanez0054a9b2020-03-13 13:06:24 -070041``pw_build`` also provides several useful GN templates that are used throughout
Armando Montanezbcc194b2020-03-10 10:23:18 -070042Pigweed.
Alexei Frolov69ad1922019-12-13 13:11:32 -080043
44Templates
45---------
46
Alexei Frolovedd2f142020-06-09 19:11:27 -070047Target types
48^^^^^^^^^^^^
Alexei Frolov69ad1922019-12-13 13:11:32 -080049.. code::
50
Alexei Frolovedd2f142020-06-09 19:11:27 -070051 import("$dir_pw_build/target_types.gni")
Alexei Frolov69ad1922019-12-13 13:11:32 -080052
Alexei Frolovedd2f142020-06-09 19:11:27 -070053 pw_source_set("my_library") {
54 sources = [ "lib.cc" ]
55 }
56
57Pigweed defines wrappers around the four basic GN binary types ``source_set``,
58``executable``, ``static_library``, and ``shared_library``. These wrappers apply
59default arguments to each target as specified in the ``default_configs`` and
60``default_public_deps`` build args. Additionally, they allow defaults to be
61removed on a per-target basis using ``remove_configs`` and
62``remove_public_deps`` variables, respectively.
63
64The ``pw_executable`` template provides additional functionality around building
65complete binaries. As Pigweed is a collection of libraries, it does not know how
66its final targets are built. ``pw_executable`` solves this by letting each user
67of Pigweed specify a global executable template for their target, and have
68Pigweed build against it. This is controlled by the build variable
69``pw_executable_config.target_type``, specifying the name of the executable
70template for a project.
Alexei Frolov69ad1922019-12-13 13:11:32 -080071
72.. tip::
73
74 Prefer to use ``pw_executable`` over plain ``executable`` targets to allow
75 cleanly building the same code for multiple target configs.
76
77**Arguments**
78
Alexei Frolovedd2f142020-06-09 19:11:27 -070079All of the ``pw_*`` target type overrides accept any arguments, as they simply
80forward them through to the underlying target.
Alexei Frolov69ad1922019-12-13 13:11:32 -080081
Alexei Frolov199045a2020-08-28 13:02:30 -070082.. _pw-build-python-script:
83
Alexei Frolov69ad1922019-12-13 13:11:32 -080084pw_python_script
85^^^^^^^^^^^^^^^^
86The ``pw_python_script`` template is a convenience wrapper around ``action`` for
Wyatt Hepler8224a642020-07-29 08:55:56 -070087running Python scripts. The main benefit it provides is resolution of GN target
88labels to compiled binary files. This allows Python scripts to be written
89independently of GN, taking only filesystem paths as arguments.
Alexei Frolov69ad1922019-12-13 13:11:32 -080090
91Another convenience provided by the template is to allow running scripts without
92any outputs. Sometimes scripts run in a build do not directly produce output
93files, but GN requires that all actions have an output. ``pw_python_script``
94solves this by accepting a boolean ``stamp`` argument which tells it to create a
95dummy output file for the action.
96
97**Arguments**
98
99``pw_python_script`` accepts all of the arguments of a regular ``action``
100target. Additionally, it has some of its own arguments:
101
Wyatt Heplera74f7b02020-07-23 14:10:56 -0700102* ``capture_output``: Optional boolean. If true, script output is hidden unless
103 the script fails with an error. Defaults to true.
104* ``stamp``: Optional variable indicating whether to automatically create a
105 dummy output file for the script. This allows running scripts without
106 specifying ``outputs``. If ``stamp`` is true, a generic output file is
107 used. If ``stamp`` is a file path, that file is used as a stamp file. Like any
108 output file, ``stamp`` must be in the build directory. Defaults to false.
Alexei Frolov69ad1922019-12-13 13:11:32 -0800109
Wyatt Hepler8224a642020-07-29 08:55:56 -0700110**Expressions**
111
112``pw_python_script`` evaluates expressions in ``args``, the arguments passed to
113the script. These expressions function similarly to generator expressions in
114CMake. Expressions may be passed as a standalone argument or as part of another
115argument. A single argument may contain multiple expressions.
116
117Generally, these expressions are used within templates rather than directly in
118BUILD.gn files. This allows build code to use GN labels without having to worry
119about converting them to files.
120
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700121The following expressions are supported:
Wyatt Hepler8224a642020-07-29 08:55:56 -0700122
123.. describe:: <TARGET_FILE(gn_target)>
124
125 Evaluates to the output file of the provided GN target. For example, the
126 expression
127
128 .. code::
129
130 "<TARGET_FILE(//foo/bar:static_lib)>"
131
132 might expand to
133
134 .. code::
135
136 "/home/User/project_root/out/obj/foo/bar/static_lib.a"
137
138 ``TARGET_FILE`` parses the ``.ninja`` file for the GN target, so it should
139 always find the correct output file, regardless of the toolchain's or target's
140 configuration. Some targets, such as ``source_set`` and ``group`` targets, do
141 not have an output file, and attempting to use ``TARGET_FILE`` with them
142 results in an error.
143
144 ``TARGET_FILE`` only resolves GN target labels to their outputs. To resolve
145 paths generally, use the standard GN approach of applying the
146 ``rebase_path(path)`` function. With default arguments, ``rebase_path``
147 converts the provided GN path or list of paths to be relative to the build
148 directory, from which all build commands and scripts are executed.
149
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700150.. describe:: <TARGET_FILE_IF_EXISTS(gn_target)>
151
152 ``TARGET_FILE_IF_EXISTS`` evaluates to the output file of the provided GN
153 target, if the output file exists. If the output file does not exist, the
154 entire argument that includes this expression is omitted, even if there is
155 other text or another expression.
156
157 For example, consider this expression:
158
159 .. code::
160
161 "--database=<TARGET_FILE_IF_EXISTS(//alpha/bravo)>"
162
163 If the ``//alpha/bravo`` target file exists, this might expand to the
164 following:
165
166 .. code::
167
168 "--database=/home/User/project/out/obj/alpha/bravo/bravo.elf"
169
170 If the ``//alpha/bravo`` target file does not exist, the entire
171 ``--database=`` argument is omitted from the script arguments.
172
173.. describe:: <TARGET_OBJECTS(gn_target)>
174
175 Evaluates to the object files of the provided GN target. Expands to a separate
176 argument for each object file. If the target has no object files, the argument
177 is omitted entirely. Because it does not expand to a single expression, the
178 ``<TARGET_OBJECTS(...)>`` expression may not have leading or trailing text.
179
180 For example, the expression
181
182 .. code::
183
184 "<TARGET_OBJECTS(//foo/bar:a_source_set)>"
185
186 might expand to multiple separate arguments:
187
188 .. code::
189
190 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_a.cc.o"
191 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_b.cc.o"
192 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_c.cc.o"
193
Alexei Frolov69ad1922019-12-13 13:11:32 -0800194**Example**
195
196.. code::
197
198 import("$dir_pw_build/python_script.gni")
199
Wyatt Hepler8224a642020-07-29 08:55:56 -0700200 pw_python_script("postprocess_main_image") {
201 script = "py/postprocess_binary.py"
202 args = [
203 "--database",
204 rebase_path("my/database.csv"),
205 "--binary=<TARGET_FILE(//firmware/images:main)>",
206 ]
Alexei Frolov69ad1922019-12-13 13:11:32 -0800207 stamp = true
208 }
209
210pw_input_group
211^^^^^^^^^^^^^^
212``pw_input_group`` defines a group of input files which are not directly
213processed by the build but are still important dependencies of later build
214steps. This is commonly used alongside metadata to propagate file dependencies
215through the build graph and force rebuilds on file modifications.
216
217For example ``pw_docgen`` defines a ``pw_doc_group`` template which outputs
218metadata from a list of input files. The metadata file is not actually part of
219the build, and so changes to any of the input files do not trigger a rebuild.
220This is problematic, as targets that depend on the metadata should rebuild when
221the inputs are modified but GN cannot express this dependency.
222
223``pw_input_group`` solves this problem by allowing a list of files to be listed
224in a target that does not output any build artifacts, causing all dependent
225targets to correctly rebuild.
226
227**Arguments**
228
229``pw_input_group`` accepts all arguments that can be passed to a ``group``
230target, as well as requiring one extra:
231
232* ``inputs``: List of input files.
233
234**Example**
235
236.. code::
237
238 import("$dir_pw_build/input_group.gni")
239
240 pw_input_group("foo_metadata") {
241 metadata = {
242 files = [
243 "x.foo",
244 "y.foo",
245 "z.foo",
246 ]
247 }
248 inputs = metadata.files
249 }
250
251Targets depending on ``foo_metadata`` will rebuild when any of the ``.foo``
252files are modified.
Rob Mohr84f234e2019-12-06 09:16:50 -0800253
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800254CMake / Ninja
255=============
Armando Montanezbcc194b2020-03-10 10:23:18 -0700256
257Pigweed's CMake support is provided primarily for projects that have an existing
258CMake build and wish to integrate Pigweed without switching to a new build
259system.
260
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800261The following command generates Ninja build files in the out/cmake directory.
262
263.. code:: sh
264
265 cmake -B out/cmake -S /path/to/pigweed -G Ninja
266
267Tests can be executed with the ``pw_run_tests_GROUP`` targets. To run the basic
268Pigweed tests, run ``ninja -C out/cmake pw_run_tests_modules``.
269
270CMake functions
271---------------
272CMake convenience functions are defined in ``pw_build/pigweed.cmake``.
273
274* ``pw_auto_add_simple_module`` -- For modules with only one library,
275 automatically declare the library and its tests.
276* ``pw_add_facade`` -- Declare a module facade.
277* ``pw_add_module_library`` -- Add a library that is part of a module.
278* ``pw_add_test`` -- Declare a test target.
279
280See ``pw_build/pigweed.cmake`` for the complete documentation of these
281functions.
282
283Special libraries that do not fit well with these functions are created with the
284standard CMake functions, such as ``add_library`` and ``target_link_libraries``.
285
286Use Pigweed from an existing CMake project
287------------------------------------------
288To use Pigweed libraries form a CMake-based project, simply include the Pigweed
289repository from a ``CMakeLists.txt``.
290
291.. code:: cmake
292
293 add_subdirectory(path/to/pigweed pigweed)
294
295All module libraries will be available as ``module_name`` or
296``module_name.sublibrary``.
297
298If desired, modules can be included individually.
299
300.. code:: cmake
301
302 include(path/to/pigweed/pw_build/pigweed.cmake)
303
304 add_subdirectory(path/to/pigweed/pw_some_module pw_some_module)
305 add_subdirectory(path/to/pigweed/pw_another_module pw_another_module)
306
Rob Mohr84f234e2019-12-06 09:16:50 -0800307Bazel
308=====
Armando Montanezbcc194b2020-03-10 10:23:18 -0700309
310Bazel is currently very experimental, and only builds for host.
311
Rob Mohr84f234e2019-12-06 09:16:50 -0800312The common configuration for Bazel for all modules is in the ``pigweed.bzl``
313file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test``
314are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``.
315These wrappers add parameters to calls to the compiler and linker.
316
317The ``BUILD`` file is merely a placeholder and currently does nothing.