Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_build / docs.rst
1 .. _module-pw_build:
2
3 --------
4 pw_build
5 --------
6 Pigweed's modules aim to be easily integratable into both new and existing
7 embedded projects. To that goal, the ``pw_build`` module provides support for
8 multiple build systems. Our personal favorite is `GN`_/`Ninja`_, which is used
9 by upstream developers for its speed and flexibility. `CMake`_ and `Bazel`_
10 build files are also provided by all modules, allowing Pigweed to be added to a
11 project with minimal effort.
12
13 .. _GN: https://gn.googlesource.com/gn/
14 .. _Ninja: https://ninja-build.org/
15 .. _CMake: https://cmake.org/
16 .. _Bazel: https://bazel.build/
17
18 Beyond just compiling code, Pigweed’s GN build system can also:
19
20 * Generate HTML documentation, via our Sphinx integration (with ``pw_docgen``)
21 * Display memory usage report cards (with ``pw_bloat``)
22 * Incrementally run unit tests after code changes (with ``pw_target_runner``)
23 * And more!
24
25 These are only supported in the GN build, so we recommend using it if possible.
26
27 GN / Ninja
28 ==========
29 The GN / Ninja build system is the primary build system used for upstream
30 Pigweed development, and is the most tested and feature-rich build system
31 Pigweed offers.
32
33 This module's ``build.gn`` file contains a number of C/C++ ``config``
34 declarations that are used by upstream Pigweed to set some architecture-agnostic
35 compiler defaults. (See Pigweed's ``//BUILDCONFIG.gn``)
36
37 ``pw_build`` also provides several useful GN templates that are used throughout
38 Pigweed.
39
40 Templates
41 ---------
42
43 Target types
44 ^^^^^^^^^^^^
45 .. code-block::
46
47   import("$dir_pw_build/target_types.gni")
48
49   pw_source_set("my_library") {
50     sources = [ "lib.cc" ]
51   }
52
53 Pigweed defines wrappers around the four basic GN binary types ``source_set``,
54 ``executable``, ``static_library``, and ``shared_library``. These wrappers apply
55 default arguments to each target as specified in the ``default_configs`` and
56 ``default_public_deps`` build args. Additionally, they allow defaults to be
57 removed on a per-target basis using ``remove_configs`` and
58 ``remove_public_deps`` variables, respectively.
59
60 The ``pw_executable`` template provides additional functionality around building
61 complete binaries. As Pigweed is a collection of libraries, it does not know how
62 its final targets are built. ``pw_executable`` solves this by letting each user
63 of Pigweed specify a global executable template for their target, and have
64 Pigweed build against it. This is controlled by the build variable
65 ``pw_executable_config.target_type``, specifying the name of the executable
66 template for a project.
67
68 .. tip::
69
70   Prefer to use ``pw_executable`` over plain ``executable`` targets to allow
71   cleanly building the same code for multiple target configs.
72
73 **Arguments**
74
75 All of the ``pw_*`` target type overrides accept any arguments, as they simply
76 forward them through to the underlying target.
77
78 .. _module-pw_build-facade:
79
80 pw_facade
81 ^^^^^^^^^
82 In their simplest form, a :ref:`facade<docs-module-structure-facades>` is a GN
83 build arg used to change a dependency at compile time. Pigweed targets configure
84 these facades as needed.
85
86 The ``pw_facade`` template bundles a ``pw_source_set`` with a facade build arg.
87 This allows the facade to provide header files, compilation options or anything
88 else a GN ``source_set`` provides.
89
90 The ``pw_facade`` template declares two targets:
91
92 * ``$target_name``: the public-facing ``pw_source_set``, with a ``public_dep``
93   on the backend
94 * ``$target_name.facade``: target used by the backend to avoid circular
95   dependencies
96
97 .. code-block::
98
99   # Declares ":foo" and ":foo.facade" GN targets
100   pw_facade("foo") {
101     backend = pw_log_BACKEND
102     public_configs = [ ":public_include_path" ]
103     public = [ "public/pw_foo/foo.h" ]
104   }
105
106 .. _module-pw_build-python-action:
107
108 pw_python_action
109 ^^^^^^^^^^^^^^^^
110 The ``pw_python_action`` template is a convenience wrapper around ``action`` for
111 running Python scripts. The main benefit it provides is resolution of GN target
112 labels to compiled binary files. This allows Python scripts to be written
113 independently of GN, taking only filesystem paths as arguments.
114
115 Another convenience provided by the template is to allow running scripts without
116 any outputs. Sometimes scripts run in a build do not directly produce output
117 files, but GN requires that all actions have an output. ``pw_python_action``
118 solves this by accepting a boolean ``stamp`` argument which tells it to create a
119 dummy output file for the action.
120
121 **Arguments**
122
123 ``pw_python_action`` accepts all of the arguments of a regular ``action``
124 target. Additionally, it has some of its own arguments:
125
126 * ``module``: Run the specified Python module instead of a script. Either
127   ``script`` or ``module`` must be specified, but not both.
128 * ``capture_output``: Optional boolean. If true, script output is hidden unless
129   the script fails with an error. Defaults to true.
130 * ``stamp``: Optional variable indicating whether to automatically create a
131   dummy output file for the script. This allows running scripts without
132   specifying ``outputs``. If ``stamp`` is true, a generic output file is
133   used. If ``stamp`` is a file path, that file is used as a stamp file. Like any
134   output file, ``stamp`` must be in the build directory. Defaults to false.
135 * ``directory``: Optional path. Change to this directory before executing the
136   command. Paths in arguments may need to be adjusted.
137 * ``environment``: Optional list of strings. Environment variables to set,
138   passed as NAME=VALUE strings.
139
140 **Expressions**
141
142 ``pw_python_action`` evaluates expressions in ``args``, the arguments passed to
143 the script. These expressions function similarly to generator expressions in
144 CMake. Expressions may be passed as a standalone argument or as part of another
145 argument. A single argument may contain multiple expressions.
146
147 Generally, these expressions are used within templates rather than directly in
148 BUILD.gn files. This allows build code to use GN labels without having to worry
149 about converting them to files.
150
151 The following expressions are supported:
152
153 .. describe:: <TARGET_FILE(gn_target)>
154
155   Evaluates to the output file of the provided GN target. For example, the
156   expression
157
158   .. code-block::
159
160     "<TARGET_FILE(//foo/bar:static_lib)>"
161
162   might expand to
163
164   .. code-block::
165
166     "/home/User/project_root/out/obj/foo/bar/static_lib.a"
167
168   ``TARGET_FILE`` parses the ``.ninja`` file for the GN target, so it should
169   always find the correct output file, regardless of the toolchain's or target's
170   configuration. Some targets, such as ``source_set`` and ``group`` targets, do
171   not have an output file, and attempting to use ``TARGET_FILE`` with them
172   results in an error.
173
174   ``TARGET_FILE`` only resolves GN target labels to their outputs. To resolve
175   paths generally, use the standard GN approach of applying the
176   ``rebase_path(path)`` function. With default arguments, ``rebase_path``
177   converts the provided GN path or list of paths to be relative to the build
178   directory, from which all build commands and scripts are executed.
179
180 .. describe:: <TARGET_FILE_IF_EXISTS(gn_target)>
181
182   ``TARGET_FILE_IF_EXISTS`` evaluates to the output file of the provided GN
183   target, if the output file exists. If the output file does not exist, the
184   entire argument that includes this expression is omitted, even if there is
185   other text or another expression.
186
187   For example, consider this expression:
188
189   .. code-block::
190
191     "--database=<TARGET_FILE_IF_EXISTS(//alpha/bravo)>"
192
193   If the ``//alpha/bravo`` target file exists, this might expand to the
194   following:
195
196   .. code-block::
197
198     "--database=/home/User/project/out/obj/alpha/bravo/bravo.elf"
199
200   If the ``//alpha/bravo`` target file does not exist, the entire
201   ``--database=`` argument is omitted from the script arguments.
202
203 .. describe:: <TARGET_OBJECTS(gn_target)>
204
205   Evaluates to the object files of the provided GN target. Expands to a separate
206   argument for each object file. If the target has no object files, the argument
207   is omitted entirely. Because it does not expand to a single expression, the
208   ``<TARGET_OBJECTS(...)>`` expression may not have leading or trailing text.
209
210   For example, the expression
211
212   .. code-block::
213
214     "<TARGET_OBJECTS(//foo/bar:a_source_set)>"
215
216   might expand to multiple separate arguments:
217
218   .. code-block::
219
220     "/home/User/project_root/out/obj/foo/bar/a_source_set.file_a.cc.o"
221     "/home/User/project_root/out/obj/foo/bar/a_source_set.file_b.cc.o"
222     "/home/User/project_root/out/obj/foo/bar/a_source_set.file_c.cc.o"
223
224 **Example**
225
226 .. code-block::
227
228   import("$dir_pw_build/python_action.gni")
229
230   pw_python_action("postprocess_main_image") {
231     script = "py/postprocess_binary.py"
232     args = [
233       "--database",
234       rebase_path("my/database.csv"),
235       "--binary=<TARGET_FILE(//firmware/images:main)>",
236     ]
237     stamp = true
238   }
239
240 pw_input_group
241 ^^^^^^^^^^^^^^
242 ``pw_input_group`` defines a group of input files which are not directly
243 processed by the build but are still important dependencies of later build
244 steps. This is commonly used alongside metadata to propagate file dependencies
245 through the build graph and force rebuilds on file modifications.
246
247 For example ``pw_docgen`` defines a ``pw_doc_group`` template which outputs
248 metadata from a list of input files. The metadata file is not actually part of
249 the build, and so changes to any of the input files do not trigger a rebuild.
250 This is problematic, as targets that depend on the metadata should rebuild when
251 the inputs are modified but GN cannot express this dependency.
252
253 ``pw_input_group`` solves this problem by allowing a list of files to be listed
254 in a target that does not output any build artifacts, causing all dependent
255 targets to correctly rebuild.
256
257 **Arguments**
258
259 ``pw_input_group`` accepts all arguments that can be passed to a ``group``
260 target, as well as requiring one extra:
261
262 * ``inputs``: List of input files.
263
264 **Example**
265
266 .. code-block::
267
268   import("$dir_pw_build/input_group.gni")
269
270   pw_input_group("foo_metadata") {
271     metadata = {
272       files = [
273         "x.foo",
274         "y.foo",
275         "z.foo",
276       ]
277     }
278     inputs = metadata.files
279   }
280
281 Targets depending on ``foo_metadata`` will rebuild when any of the ``.foo``
282 files are modified.
283
284 pw_zip
285 ^^^^^^
286 ``pw_zip`` is a target that allows users to zip up a set of input files and
287 directories into a single output ``.zip`` file—a simple automation of a
288 potentially repetitive task.
289
290 **Arguments**
291
292 * ``inputs``: List of source files as well as the desired relative zip
293   destination. See below for the input syntax.
294 * ``dirs``: List of entire directories to be zipped as well as the desired
295   relative zip destination. See below for the input syntax.
296 * ``output``: Filename of output ``.zip`` file.
297 * ``deps``: List of dependencies for the target.
298
299 **Input Syntax**
300
301 Inputs all need to follow the correct syntax:
302
303 #. Path to source file or directory. Directories must end with a ``/``.
304 #. The delimiter (defaults to ``>``).
305 #. The desired destination of the contents within the ``.zip``. Must start
306    with ``/`` to indicate the zip root. Any number of subdirectories are
307    allowed. If the source is a file it can be put into any subdirectory of the
308    root. If the source is a file, the zip copy can also be renamed by ending
309    the zip destination with a filename (no trailing ``/``).
310
311 Thus, it should look like the following: ``"[source file or dir] > /"``.
312
313 **Example**
314
315 Let's say we have the following structure for a ``//source/`` directory:
316
317 .. code-block::
318
319   source/
320   ├── file1.txt
321   ├── file2.txt
322   ├── file3.txt
323   └── some_dir/
324       ├── file4.txt
325       └── some_other_dir/
326           └── file5.txt
327
328 And we create the following build target:
329
330 .. code-block::
331
332   import("$dir_pw_build/zip.gni")
333
334   pw_zip("target_name") {
335     inputs = [
336       "//source/file1.txt > /",             # Copied to the zip root dir.
337       "//source/file2.txt > /renamed.txt",  # File renamed.
338       "//source/file3.txt > /bar/",         # File moved to the /bar/ dir.
339     ]
340
341     dirs = [
342       "//source/some_dir/ > /bar/some_dir/",  # All /some_dir/ contents copied
343                                               # as /bar/some_dir/.
344     ]
345
346     # Note on output: if the specific output directory isn't defined
347     # (such as output = "zoo.zip") then the .zip will output to the
348     # same directory as the BUILD.gn file that called the target.
349     output = "//$target_out_dir/foo.zip"  # Where the foo.zip will end up
350   }
351
352 This will result in a ``.zip`` file called ``foo.zip`` stored in
353 ``//$target_out_dir`` with the following structure:
354
355 .. code-block::
356
357   foo.zip
358   ├── bar/
359   │   ├── file3.txt
360   │   └── some_dir/
361   │       ├── file4.txt
362   │       └── some_other_dir/
363   │           └── file5.txt
364   ├── file1.txt
365   └── renamed.txt
366
367 CMake / Ninja
368 =============
369 Pigweed's `CMake`_ support is provided primarily for projects that have an
370 existing CMake build and wish to integrate Pigweed without switching to a new
371 build system.
372
373 The following command generates Ninja build files for a host build in the
374 ``out/cmake_host`` directory:
375
376 .. code-block:: sh
377
378   cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake
379
380 The ``PW_ROOT`` environment variable must point to the root of the Pigweed
381 directory. This variable is set by Pigweed's environment setup.
382
383 Tests can be executed with the ``pw_run_tests.GROUP`` targets. To run Pigweed
384 module tests, execute ``pw_run_tests.modules``:
385
386 .. code-block:: sh
387
388   ninja -C out/cmake_host pw_run_tests.modules
389
390 :ref:`module-pw_watch` supports CMake, so you can also run
391
392 .. code-block:: sh
393
394   pw watch -C out/cmake_host pw_run_tests.modules
395
396 CMake functions
397 ---------------
398 CMake convenience functions are defined in ``pw_build/pigweed.cmake``.
399
400 * ``pw_auto_add_simple_module`` -- For modules with only one library,
401   automatically declare the library and its tests.
402 * ``pw_auto_add_module_tests`` -- Create test targets for all tests in a module.
403 * ``pw_add_facade`` -- Declare a module facade.
404 * ``pw_set_backend`` -- Set the backend library to use for a facade.
405 * ``pw_add_module_library`` -- Add a library that is part of a module.
406 * ``pw_add_test`` -- Declare a test target.
407
408 See ``pw_build/pigweed.cmake`` for the complete documentation of these
409 functions.
410
411 Special libraries that do not fit well with these functions are created with the
412 standard CMake functions, such as ``add_library`` and ``target_link_libraries``.
413
414 Facades and backends
415 --------------------
416 The CMake build uses CMake cache variables for configuring
417 :ref:`facades<docs-module-structure-facades>` and backends. Cache variables are
418 similar to GN's build args set with ``gn args``. Unlike GN, CMake does not
419 support multi-toolchain builds, so these variables have a single global value
420 per build directory.
421
422 The ``pw_add_facade`` function declares a cache variable named
423 ``<module_name>_BACKEND`` for each facade. Cache variables can be awkward to
424 work with, since their values only change when they're assigned, but then
425 persist accross CMake invocations. These variables should be set in one of the
426 following ways:
427
428 * Call ``pw_set_backend`` to set backends appropriate for the target in the
429   target's toolchain file. The toolchain file is provided to ``cmake`` with
430   ``-DCMAKE_TOOLCHAIN_FILE=<toolchain file>``.
431 * Call ``pw_set_backend`` in the top-level ``CMakeLists.txt`` before other
432   CMake code executes.
433 * Set the backend variable at the command line with the ``-D`` option.
434
435   .. code-block:: sh
436
437     cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
438         -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
439         -Dpw_log_BACKEND=pw_log_basic
440
441 * Temporarily override a backend by setting it interactively with ``ccmake`` or
442   ``cmake-gui``.
443
444 Toolchain setup
445 ---------------
446 In CMake, the toolchain is configured by setting CMake variables, as described
447 in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_.
448 These variables are typically set in a toolchain CMake file passed to ``cmake``
449 with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``).
450 For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string
451 (``""``).
452
453 Third party libraries
454 ---------------------
455 The CMake build includes third-party libraries similarly to the GN build. A
456 ``dir_pw_third_party_<library>`` cache variable is defined for each third-party
457 dependency. This variable can have one of three values:
458
459 * ``""`` (empty) -- the dependency is not available
460 * ``PRESENT`` -- the dependency is available and is already included in the
461   build
462 * ``</path/to/the/dependency>`` -- the dependency is available and will be
463   automatically imported from this path using ``add_subdirectory``.
464
465 If the variable is empty (``if("${dir_pw_third_party_<library>}" STREQUAL
466 "")``), the dependency is not available. Otherwise, it is available and
467 libraries declared by it can be referenced.
468
469 Third party variables are set like any other cache global variable in CMake. It
470 is recommended to set these in one of the following ways:
471
472 * Set with the CMake ``set`` function in the toolchain file or a
473   ``CMakeLists.txt`` before other CMake code executes.
474
475   .. code-block:: cmake
476
477     set(dir_pw_third_party_nanopb PRESENT CACHE STRING "" FORCE)
478
479 * Set the variable at the command line with the ``-D`` option.
480
481   .. code-block:: sh
482
483     cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
484         -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
485         -Ddir_pw_third_party_nanopb=/path/to/nanopb
486
487 * Set the variable interactively with ``ccmake`` or ``cmake-gui``.
488
489 Use Pigweed from an existing CMake project
490 ------------------------------------------
491 To use Pigweed libraries form a CMake-based project, simply include the Pigweed
492 repository from a ``CMakeLists.txt``.
493
494 .. code-block:: cmake
495
496   add_subdirectory(path/to/pigweed pigweed)
497
498 All module libraries will be available as ``module_name`` or
499 ``module_name.sublibrary``.
500
501 If desired, modules can be included individually.
502
503 .. code-block:: cmake
504
505   add_subdirectory(path/to/pigweed/pw_some_module pw_some_module)
506   add_subdirectory(path/to/pigweed/pw_another_module pw_another_module)
507
508 Bazel
509 =====
510 Bazel is currently very experimental, and only builds for host.
511
512 The common configuration for Bazel for all modules is in the ``pigweed.bzl``
513 file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test``
514 are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``.
515 These wrappers add parameters to calls to the compiler and linker.
516
517 The ``BUILD`` file is merely a placeholder and currently does nothing.