1.. _module-pw_build-gn: 2 3GN / Ninja 4========== 5.. pigweed-module-subpage:: 6 :name: pw_build 7 8The GN / Ninja build system is the primary build system used for upstream 9Pigweed development, and is the most tested and feature-rich build system 10Pigweed offers. 11 12This module's ``build.gn`` file contains a number of C/C++ ``config`` 13declarations that are used by upstream Pigweed to set some architecture-agnostic 14compiler defaults. (See Pigweed's ``//BUILDCONFIG.gn``) 15 16``pw_build`` also provides several useful GN templates that are used throughout 17Pigweed. 18 19Building upstream Pigweed 20------------------------- 21See Pigweed's :ref:`docs-get-started-upstream` guide for a high-level introduction 22to using the GN build. 23 24Pigweed's root ``BUILD.gn`` file contains a variety of groups to help you 25control what parts of the project you'd like to build. 26 27* ``default``: Same as just calling ``ninja -C out``. Builds Pigweed's 28 documentation, recommended tests, and python linting, and static analysis. 29* ``extended_default``: Everything in ``default``, plus some other useful 30 configurations that are tested in CQ. 31* ``all``: Attempts to build everything in Pigweed. Note that ``pw package`` may 32 need to be used to enable some branches of the build. 33* ``docs``: Only build Pigweed's documentation. 34* ``stm32f429i``: Only build for the STMicroelectronics STM32F429I-DISC1 board. 35* ``host``: Only build for the host. 36 37There are a variety of other groups in the root ``BUILD.gn`` file that may be 38helpful for covering more areas of the build, or for reducing iteration time 39by only building a subset of the default build. 40 41Some currently broken groups are gated behind the ``pw_BUILD_BROKEN_GROUPS`` 42build argument. You can set this to ``true`` using ``gn args out`` to try to 43build and debug known broken build configurations. 44 45Build system philosophies 46------------------------- 47While Pigweed's GN build is not hermetic, it strives to adhere to principles of 48`hermeticity <https://bazel.build/concepts/hermeticity>`_. Some guidelines to 49move towards the ideal of hermeticity include: 50 51* Only rely on pre-compiled tools provided by CIPD (or some other versioned, 52 pre-compiled binary distribution mechanism). This eliminates build artifact 53 differences caused by different tool versions or variations (e.g. same tool 54 version built with slightly different compilation flags). 55* Do not use absolute paths in Ninja commands. Typically, these appear when 56 using ``rebase_path("//path/to/my_script.py")``. Most of the time, Ninja 57 steps should be passed paths rebased relative to the build directory (i.e. 58 ``rebase_path("//path/to/my_script.py", root_build_dir)``). This ensures build 59 commands are the same across different machines. 60* Prevent produced artifacts from relying on or referencing system state. This 61 includes time stamps, writing absolute paths to generated artifacts, or 62 producing artifacts that reference system state in a way that prevents them 63 from working the same way on a different machine. 64* Isolate build actions to the build directory. In general, the build system 65 should not add or modify files outside of the build directory. This can cause 66 confusion to users, and makes the concept of a clean build more ambiguous. 67 68Target types 69------------ 70.. code-block:: 71 72 import("$dir_pw_build/target_types.gni") 73 74 pw_source_set("my_library") { 75 sources = [ "lib.cc" ] 76 } 77 78Pigweed defines wrappers around the four basic GN binary types ``source_set``, 79``executable``, ``static_library``, and ``shared_library``. These templates 80do several things: 81 82#. **Add default configs/deps** 83 84 Rather than binding the majority of compiler flags related to C++ standard, 85 cross-compilation, warning/error policy, etc. directly to toolchain 86 invocations, these flags are applied as configs to all ``pw_*`` C/C++ target 87 types. The primary motivations for this are to allow some targets to modify 88 the default set of flags when needed by specifying ``remove_configs``, and to 89 reduce the complexity of building novel toolchains. 90 91 Pigweed's global default configs are set in ``pw_build/default.gni``, and 92 individual platform-specific toolchains extend the list by appending to the 93 ``default_configs`` build argument. 94 95 Default deps were added to support polyfill, which has since been deprecated. 96 Default dependency functionality continues to exist for backwards 97 compatibility. 98 99#. **Optionally add link-time binding** 100 101 Some libraries like pw_assert and pw_log are borderline impossible to 102 implement well without introducing circular dependencies. One solution for 103 addressing this is to break apart the libraries into an interface with 104 minimal dependencies, and an implementation with the bulk of the 105 dependencies that would typically create dependency cycles. In order for the 106 implementation to be linked in, it must be added to the dependency tree of 107 linked artifacts (e.g. ``pw_executable``, ``pw_static_library``). Since 108 there's no way for the libraries themselves to just happily pull in the 109 implementation if someone depends on the interface, the implementation is 110 instead late-bound by adding it as a direct dependency of the final linked 111 artifact. This is all managed through ``pw_build_LINK_DEPS``, which is global 112 for each toolchain and applied to every ``pw_executable``, 113 ``pw_static_library``, and ``pw_shared_library``. 114 115#. **Apply a default visibility policy** 116 117 Projects can globally control the default visibility of pw_* target types by 118 specifying ``pw_build_DEFAULT_VISIBILITY``. This template applies that as the 119 default visibility for any pw_* targets that do not explicitly specify a 120 visibility. 121 122#. **Add source file names as metadata** 123 124 All source file names are collected as 125 `GN metadata <https://gn.googlesource.com/gn/+/main/docs/reference.md#metadata_collection>`_. 126 This list can be writen to a file at build time using ``generated_file``. The 127 primary use case for this is to generate a token database containing all the 128 source files. This allows :c:macro:`PW_ASSERT` to emit filename tokens even 129 though it can't add them to the elf file because of the reasons described at 130 :ref:`module-pw_assert-assert-api`. 131 132 .. note:: 133 ``pw_source_files``, if not rebased will default to outputing module 134 relative paths from a ``generated_file`` target. This is likely not 135 useful. Adding a ``rebase`` argument to ``generated_file`` such as 136 ``rebase = root_build_dir`` will result in usable paths. For an example, 137 see ``//pw_tokenizer/database.gni``'s ``pw_tokenizer_filename_database`` 138 template. 139 140The ``pw_executable`` template provides additional functionality around building 141complete binaries. As Pigweed is a collection of libraries, it does not know how 142its final targets are built. ``pw_executable`` solves this by letting each user 143of Pigweed specify a global executable template for their target, and have 144Pigweed build against it. This is controlled by the build variable 145``pw_executable_config.target_type``, specifying the name of the executable 146template for a project. 147 148In some uncommon cases, a project's ``pw_executable`` template definition may 149need to stamp out some ``pw_source_set``\s. Since a pw_executable template can't 150import ``$dir_pw_build/target_types.gni`` due to circular imports, it should 151import ``$dir_pw_build/cc_library.gni`` instead. 152 153.. tip:: 154 155 Prefer to use ``pw_executable`` over plain ``executable`` targets to allow 156 cleanly building the same code for multiple target configs. 157 158Arguments 159^^^^^^^^^ 160All of the ``pw_*`` target type overrides accept any arguments supported by 161the underlying native types, as they simply forward them through to the 162underlying target. 163 164Additionally, the following arguments are also supported: 165 166* **remove_configs**: (optional) A list of configs / config patterns to remove 167 from the set of default configs specified by the current toolchain 168 configuration. 169* **remove_public_deps**: (optional) A list of targets to remove from the set of 170 default public_deps specified by the current toolchain configuration. 171 172.. _module-pw_build-link-deps: 173 174Link-only deps 175-------------- 176It may be necessary to specify additional link-time dependencies that may not be 177explicitly depended on elsewhere in the build. One example of this is a 178``pw_assert`` backend, which may need to leave out dependencies to avoid 179circular dependencies. Its dependencies need to be linked for executables and 180libraries, even if they aren't pulled in elsewhere. 181 182The ``pw_build_LINK_DEPS`` build arg is a list of dependencies to add to all 183``pw_executable``, ``pw_static_library``, and ``pw_shared_library`` targets. 184This should only be used as a last resort when dependencies cannot be properly 185expressed in the build. 186 187.. _module-pw_build-third-party: 188 189Third party libraries 190--------------------- 191Pigweed includes build files for a selection of third-party libraries. For a 192given library, these include: 193 194* ``third_party/<library>/library.gni``: Declares build arguments like 195 ``dir_pw_third_party_<library>`` that default to ``""`` but can be set to the 196 absolute path of the library in order to use it. 197* ``third_party/<library>/BUILD.gn``: Describes how to build the library. This 198 should import ``third_party/<library>/library.gni`` and refer to source paths 199 relative to ``dir_pw_third_party_<library>``. 200 201To add or update GN build files for libraries that only offer Bazel build files, 202the Python script at ``pw_build/py/pw_build/generate_3p_gn.py`` may be used. 203 204.. note:: 205 The ``generate_3p_gn.py`` script is experimental, and may not work on an 206 arbitrary Bazel library. 207 208To generate or update the GN offered by Pigweed from an Bazel upstream project, 209first create a ``third_party/<library>/repo.json`` file. This file should 210describe a single JSON object, with the following fields: 211 212* ``name``: String containg the project name. 213 214 .. code-block:: 215 216 "name": "FuzzTest" 217 218* ``repos``: Object mapping Bazel repositories to library names. 219 220 .. code-block:: 221 222 "repos": { "com_google_absl": "abseil-cpp" } 223 224* ``aliases``: Object mapping GN labels to other GN labels. In some cases, a 225 third party library may have a dependency on another library already supported 226 by Pigweed, but with a label that differs from what the script would generate. 227 This field allows those labels to be rewritten. 228 229 .. code-block:: 230 231 "aliases": { 232 "$dir_pw_third_party/googletest:gtest": "$dir_pw_third_party/googletest" 233 } 234 235* ``add``: List of labels to existing GN configs. These will be added to every 236 target in the library. 237 238 .. code-block:: 239 240 "add": [ "$dir_pw_third_party/re2/configs:disabled_warnings" ] 241 242* ``remove``: List of labels to default GN configs. These will be removed from 243 every target. 244 245 .. code-block:: 246 247 "remove" = [ "$dir_pw_fuzzer:instrumentation" ] 248 249* ``allow_testonly``: Boolean indicating whether to generate GN for Bazel 250 targets marked test-only. Defaults to false. 251 252 .. code-block:: 253 254 "allow_testonly": true 255 256* ``no_gn_check``: List of Bazel targets that violate ``gn check``'s 257 `rules`__. Third-party targets that do not conform can be excluded. 258 259 .. code-block:: 260 261 "no_gn_check": [ "//fuzztest:regexp_dfa" ] 262 263* ``extra_files``: Object mapping additional files to create to Bazel targets 264 that create them. These targets will be passed to ``bazel run`` and their 265 output saved to the named file within ``third_party/<library>``. For example: 266 267 .. code-block:: 268 269 "extra_files": { 270 "fuzztest.bazelrc": "@com_google_fuzztest//bazel:setup_configs" 271 } 272 273.. __: https://gn.googlesource.com/gn/+/main/docs/reference.md#cmd_check 274 275Python packages 276--------------- 277GN templates for :ref:`Python build automation <docs-python-build>` are 278described in :ref:`module-pw_build-python`. 279 280.. toctree:: 281 :hidden: 282 283 python 284 285 286.. _module-pw_build-cc_blob_library: 287 288pw_cc_blob_library 289------------------ 290The ``pw_cc_blob_library`` template is useful for embedding binary data into a 291program. The template takes in a mapping of symbol names to file paths, and 292generates a set of C++ source and header files that embed the contents of the 293passed-in files as arrays of ``std::byte``. 294 295The blob byte arrays are constant initialized and are safe to access at any 296time, including before ``main()``. 297 298``pw_cc_blob_library`` is also available in the CMake build. It is provided by 299``pw_build/cc_blob_library.cmake``. 300 301Arguments 302^^^^^^^^^ 303* ``blobs``: A list of GN scopes, where each scope corresponds to a binary blob 304 to be transformed from file to byte array. This is a required field. Blob 305 fields include: 306 307 * ``symbol_name``: The C++ symbol for the byte array. 308 * ``file_path``: The file path for the binary blob. 309 * ``linker_section``: If present, places the byte array in the specified 310 linker section. 311 * ``alignas``: If present, uses the specified string or integer verbatim in 312 the ``alignas()`` specifier for the byte array. 313 314* ``out_header``: The header file to generate. Users will include this file 315 exactly as it is written here to reference the byte arrays. 316* ``namespace``: An optional (but highly recommended!) C++ namespace to place 317 the generated blobs within. 318 319Example 320^^^^^^^ 321**BUILD.gn** 322 323.. code-block:: 324 325 pw_cc_blob_library("foo_bar_blobs") { 326 blobs: [ 327 { 328 symbol_name: "kFooBlob" 329 file_path: "${target_out_dir}/stuff/bin/foo.bin" 330 }, 331 { 332 symbol_name: "kBarBlob" 333 file_path: "//stuff/bin/bar.bin" 334 linker_section: ".bar_section" 335 }, 336 ] 337 out_header: "my/stuff/foo_bar_blobs.h" 338 namespace: "my::stuff" 339 deps = [ ":generate_foo_bin" ] 340 } 341 342.. note:: If the binary blobs are generated as part of the build, be sure to 343 list them as deps to the pw_cc_blob_library target. 344 345**Generated Header** 346 347.. code-block:: 348 349 #pragma once 350 351 #include <array> 352 #include <cstddef> 353 354 namespace my::stuff { 355 356 extern const std::array<std::byte, 100> kFooBlob; 357 358 extern const std::array<std::byte, 50> kBarBlob; 359 360 } // namespace my::stuff 361 362**Generated Source** 363 364.. code-block:: 365 366 #include "my/stuff/foo_bar_blobs.h" 367 368 #include <array> 369 #include <cstddef> 370 371 #include "pw_preprocessor/compiler.h" 372 373 namespace my::stuff { 374 375 const std::array<std::byte, 100> kFooBlob = { ... }; 376 377 PW_PLACE_IN_SECTION(".bar_section") 378 const std::array<std::byte, 50> kBarBlob = { ... }; 379 380 } // namespace my::stuff 381 382.. _module-pw_build-facade: 383 384pw_facade 385--------- 386In their simplest form, a :ref:`facade<docs-module-structure-facades>` is a GN 387build arg used to change a dependency at compile time. Pigweed targets configure 388these facades as needed. 389 390The ``pw_facade`` template bundles a ``pw_source_set`` with a facade build arg. 391This allows the facade to provide header files, compilation options or anything 392else a GN ``source_set`` provides. 393 394The ``pw_facade`` template declares two targets: 395 396* ``$target_name``: the public-facing ``pw_source_set``, with a ``public_dep`` 397 on the backend 398* ``$target_name.facade``: target used by the backend to avoid circular 399 dependencies 400 401.. code-block:: 402 403 # Declares ":foo" and ":foo.facade" GN targets 404 pw_facade("foo") { 405 backend = pw_log_BACKEND 406 public_configs = [ ":public_include_path" ] 407 public = [ "public/pw_foo/foo.h" ] 408 } 409 410Low-level facades like ``pw_assert`` cannot express all of their dependencies 411due to the potential for dependency cycles. Facades with this issue may require 412backends to place their implementations in a separate build target to be listed 413in ``pw_build_LINK_DEPS`` (see :ref:`module-pw_build-link-deps`). The 414``require_link_deps`` variable in ``pw_facade`` asserts that all specified build 415targets are present in ``pw_build_LINK_DEPS`` if the facade's backend variable 416is set. 417 418.. _module-pw_build-python-action: 419 420pw_python_action 421---------------- 422.. seealso:: 423 - :ref:`module-pw_build-python` for all of Pigweed's Python build GN templates. 424 - :ref:`docs-python-build` for details on how the GN Python build works. 425 426The ``pw_python_action`` template is a convenience wrapper around GN's `action 427function <https://gn.googlesource.com/gn/+/main/docs/reference.md#func_action>`_ 428for running Python scripts. The main benefit it provides is resolution of GN 429target labels to compiled binary files. This allows Python scripts to be written 430independently of GN, taking only filesystem paths as arguments. 431 432Another convenience provided by the template is to allow running scripts without 433any outputs. Sometimes scripts run in a build do not directly produce output 434files, but GN requires that all actions have an output. ``pw_python_action`` 435solves this by accepting a boolean ``stamp`` argument which tells it to create a 436placeholder output file for the action. 437 438Arguments 439^^^^^^^^^ 440``pw_python_action`` accepts all of the arguments of a regular ``action`` 441target. Additionally, it has some of its own arguments: 442 443* ``module``: Run the specified Python module instead of a script. Either 444 ``script`` or ``module`` must be specified, but not both. 445* ``capture_output``: Optional boolean. If true, script output is hidden unless 446 the script fails with an error. Defaults to true. 447* ``stamp``: Optional variable indicating whether to automatically create a 448 placeholder output file for the script. This allows running scripts without 449 specifying ``outputs``. If ``stamp`` is true, a generic output file is 450 used. If ``stamp`` is a file path, that file is used as a stamp file. Like any 451 output file, ``stamp`` must be in the build directory. Defaults to false. 452* ``environment``: Optional list of strings. Environment variables to set, 453 passed as NAME=VALUE strings. 454* ``working_directory``: Optional file path. When provided the current working 455 directory will be set to this location before the Python module or script is 456 run. 457* ``command_launcher``: Optional string. Arguments to prepend to the Python 458 command, e.g. ``'/usr/bin/fakeroot --'`` will run the Python script within a 459 fakeroot environment. 460* ``venv``: Optional gn target of the pw_python_venv that should be used to run 461 this action. 462* ``python_deps``: Extra dependencies that are required for running the Python 463 script for the ``action``. This must be used with ``module`` to specify the 464 build dependency of the ``module`` if it is user-defined code. 465* ``python_metadata_deps``: Extra dependencies that are ensured completed before 466 generating a Python package metadata manifest, not the overall Python script 467 ``action``. This should rarely be used by non-Pigweed code. 468 469.. _module-pw_build-python-action-test: 470 471pw_python_action_test 472--------------------- 473The ``pw_python_action_test`` extends :ref:`module-pw_build-python-action` to 474create a test that is run by a Python script, and its associated test metadata. 475 476Include action tests in the :ref:`module-pw_unit_test-pw_test_group` to produce 477the JSON metadata that :ref:`module-pw_build-test-info` adds. 478 479This template derives several additional targets: 480 481* ``<target_name>.metadata`` produces the test metadata when included in a 482 ``pw_test_group``. This metadata includes the Ninja target that runs the test. 483* If``action`` is not provided as a label, ``<target_name>.script`` wraps a 484 ``pw_python_action`` to run the test as a standalone ``pw_python_package``. 485* ``<target_name>.group`` creates a ``pw_python_group`` in order to apply tools, 486 e.g. linters, to the standalone package. 487* ``<target_name>.lib`` is an empty group for compatibility with 488 ``pw_test_group``. 489* ``<target_name>.run`` invokes the test. 490 491Targets defined using this template will produce test metadata with a 492``test_type`` of "action_test" and a ``ninja_target`` value that will invoke the 493test when passed to Ninja, i.e. ``ninja -C out <ninja_target>``. 494 495Arguments 496^^^^^^^^^ 497``pw_python_action_test`` accepts the following arguments: 498 499* All of the arguments of :ref:`module-pw_unit_test-pw_test`. 500* ``action``: An optional string or scope. If a string, this should be a label 501 to a ``pw_python_action`` target that performs the test. If a scope, this has 502 the same meaning as for ``pw_python_script``. 503* Optionally, the ``test_type`` and ``extra_metadata`` arguments of the 504 :ref:`module-pw_build-test-info` template. 505* Optionally, all of the arguments of the :ref:`module-pw_build-python-action` 506 template except ``module``, ``capture_output``, ``stamp``, and 507 ``python_metadata_deps``. 508* Optionally, all of the arguments of the ``pw_python_package`` template except 509 ``setup``, ``generate_setup``, ``tests``, ``python_test_deps``, and 510 ``proto_library``. 511 512.. _module-pw_build-test-info: 513 514pw_test_info 515------------ 516``pw_test_info`` generates metadata describing tests. To produce a JSON file 517containing this metadata: 518 519#. For new modules, add a :ref:`module-pw_unit_test-pw_test_group` to the 520 BUILD.gn file. All modules are required to have a ``tests`` target. 521#. Include one or more tests or test groups via ``tests`` or ``group_deps``, 522 respectively, in the ``pw_test_group``. 523#. Set ``output_metadata`` to ``true`` in the ``pw_test_group`` definition. 524 525This template does not typically need to be used directly, unless adding new 526types of tests. It is typically used by other templates, such as the 527:ref:`module-pw_unit_test-pw_test` and the 528:ref:`module-pw_unit_test-pw_test_group`. 529 530Arguments 531^^^^^^^^^ 532* ``test_type``: One of "test_group", "unit_test", "action_test", "perf_test", 533 or "fuzz_test". 534* ``test_name``: Name of the test. Defaults to the target name. 535* ``build_label``: GN label for the test. Defaults to the test name. 536* ``extra_metadata``: Additional variables to add to the metadata. 537 538Specific test templates add additional details using ``extra_metadata``. For 539example: 540 541* The :ref:`module-pw_unit_test-pw_test_group` includes its collected list of 542 tests and test groups as ``deps``. 543* The :ref:`module-pw_unit_test-pw_test` and the 544 :ref:`module-pw_perf_test-pw_perf_test` includes the ``test_directory`` 545 that contains the test executable. 546* The :ref:`module-pw_build-python-action-test` includes the Ninja target that 547 can be used to invoke the Python action and run the test. 548 549Example 550^^^^^^^ 551Let ``//my_module/BUILD.gn`` contain the following: 552 553.. code-block:: 554 555 import("$dir_pw_build/python_action_test.gni") 556 import("$dir_pw_perf_test/perf_test.gni") 557 import("$dir_pw_unit_test/test.gni") 558 559 pw_test("my_unit_test") { 560 sources = [ ... ] 561 deps = [ ... ] 562 } 563 564 pw_python_action_test("my_action_test") { 565 script = [ ... ] 566 args = [ ... ] 567 deps = [ ... ] 568 } 569 570 pw_python_action_test("my_integration_test") { 571 script = [ ... ] 572 args = [ ... ] 573 deps = [ ... ] 574 tags = [ "integration" ] 575 } 576 577 pw_perf_test("my_perf_test") { 578 sources = [ ... ] 579 deps = [ ... ] 580 } 581 582 pw_test_group("tests") { 583 tests = [ 584 ":my_unit_test", 585 ":my_action_test", 586 ":my_integration_test", 587 ] 588 } 589 590Let `//BUILD.gn`` contain the following: 591 592.. code-block:: 593 594 import("$dir_pw_unit_test/test.gni") 595 596 group("run_tests") { 597 deps = [ ":my_module_tests(//targets/my_targets:my_toolchain)" ] 598 } 599 600 pw_test_group("my_module_tests") { 601 group_deps = [ "//my_module:tests" ] 602 output_metadata = true 603 } 604 605Then running ``gn gen out`` will produce the following JSON file at 606``out/my_toolchain/my_module_tests.testinfo.json``: 607 608.. code-block:: json 609 610 [ 611 { 612 "build_label": "//my_module:my_unit_test", 613 "test_directory": "my_toolchain/obj/my_module/test", 614 "test_name": "my_unit_test", 615 "test_type": "unit_test" 616 }, 617 { 618 "build_label": "//my_module:my_action_test", 619 "ninja_target": "my_toolchain/obj/my_module/my_action_test.run.stamp", 620 "test_name": "my_action_test", 621 "test_type": "action_test" 622 }, 623 { 624 "build_label": "//my_module:my_integration_test", 625 "ninja_target": "my_toolchain/obj/my_module/my_integration_test.run.stamp", 626 "tags": [ 627 "integration" 628 ], 629 "test_name": "my_integration_test", 630 "test_type": "action_test" 631 }, 632 { 633 "build_label": "//my_module:my_perf_test", 634 "test_directory": "my_toolchain/obj/my_module/test", 635 "test_name": "my_perf_test", 636 "test_type": "perf_test" 637 }, 638 { 639 "build_label": "//my_module:tests", 640 "deps": [ 641 "//my_module:my_unit_test", 642 "//my_module:my_action_test", 643 "//my_module:my_integration_test", 644 ], 645 "test_name": "my_module/tests", 646 "test_type": "test_group" 647 }, 648 { 649 "build_label": "//:my_module_tests", 650 "deps": [ 651 "//my_module:tests", 652 ], 653 "test_name": "my_module_tests", 654 "test_type": "test_group" 655 } 656 ] 657 658.. _module-pw_build-python-action-expressions: 659 660Expressions 661^^^^^^^^^^^ 662``pw_python_action`` evaluates expressions in ``args``, the arguments passed to 663the script. These expressions function similarly to generator expressions in 664CMake. Expressions may be passed as a standalone argument or as part of another 665argument. A single argument may contain multiple expressions. 666 667Generally, these expressions are used within templates rather than directly in 668BUILD.gn files. This allows build code to use GN labels without having to worry 669about converting them to files. 670 671.. note:: 672 673 We intend to replace these expressions with native GN features when possible. 674 See `b/234886742 <http://issuetracker.google.com/234886742>`_. 675 676The following expressions are supported: 677 678.. describe:: <TARGET_FILE(gn_target)> 679 680 Evaluates to the output file of the provided GN target. For example, the 681 expression 682 683 .. code-block:: 684 685 "<TARGET_FILE(//foo/bar:static_lib)>" 686 687 might expand to 688 689 .. code-block:: 690 691 "/home/User/project_root/out/obj/foo/bar/static_lib.a" 692 693 ``TARGET_FILE`` parses the ``.ninja`` file for the GN target, so it should 694 always find the correct output file, regardless of the toolchain's or target's 695 configuration. Some targets, such as ``source_set`` and ``group`` targets, do 696 not have an output file, and attempting to use ``TARGET_FILE`` with them 697 results in an error. 698 699 ``TARGET_FILE`` only resolves GN target labels to their outputs. To resolve 700 paths generally, use the standard GN approach of applying the 701 ``rebase_path(path, root_build_dir)`` function. This function 702 converts the provided GN path or list of paths to be relative to the build 703 directory, from which all build commands and scripts are executed. 704 705.. describe:: <TARGET_FILE_IF_EXISTS(gn_target)> 706 707 ``TARGET_FILE_IF_EXISTS`` evaluates to the output file of the provided GN 708 target, if the output file exists. If the output file does not exist, the 709 entire argument that includes this expression is omitted, even if there is 710 other text or another expression. 711 712 For example, consider this expression: 713 714 .. code-block:: 715 716 "--database=<TARGET_FILE_IF_EXISTS(//alpha/bravo)>" 717 718 If the ``//alpha/bravo`` target file exists, this might expand to the 719 following: 720 721 .. code-block:: 722 723 "--database=/home/User/project/out/obj/alpha/bravo/bravo.elf" 724 725 If the ``//alpha/bravo`` target file does not exist, the entire 726 ``--database=`` argument is omitted from the script arguments. 727 728.. describe:: <TARGET_OBJECTS(gn_target)> 729 730 Evaluates to the object files of the provided GN target. Expands to a separate 731 argument for each object file. If the target has no object files, the argument 732 is omitted entirely. Because it does not expand to a single expression, the 733 ``<TARGET_OBJECTS(...)>`` expression may not have leading or trailing text. 734 735 For example, the expression 736 737 .. code-block:: 738 739 "<TARGET_OBJECTS(//foo/bar:a_source_set)>" 740 741 might expand to multiple separate arguments: 742 743 .. code-block:: 744 745 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_a.cc.o" 746 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_b.cc.o" 747 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_c.cc.o" 748 749Example 750^^^^^^^ 751.. code-block:: 752 753 import("$dir_pw_build/python_action.gni") 754 755 pw_python_action("postprocess_main_image") { 756 script = "py/postprocess_binary.py" 757 args = [ 758 "--database", 759 rebase_path("my/database.csv", root_build_dir), 760 "--binary=<TARGET_FILE(//firmware/images:main)>", 761 ] 762 stamp = true 763 } 764 765.. _module-pw_build-evaluate-path-expressions: 766 767pw_evaluate_path_expressions 768---------------------------- 769It is not always feasible to pass information to a script through command line 770arguments. If a script requires a large amount of input data, writing to a file 771is often more convenient. However, doing so bypasses ``pw_python_action``'s GN 772target label resolution, preventing such scripts from working with build 773artifacts in a build system-agnostic manner. 774 775``pw_evaluate_path_expressions`` is designed to address this use case. It takes 776a list of input files and resolves target expressions within them, modifying the 777files in-place. 778 779Refer to ``pw_python_action``'s :ref:`module-pw_build-python-action-expressions` 780section for the list of supported expressions. 781 782.. note:: 783 784 ``pw_evaluate_path_expressions`` is typically used as an intermediate 785 sub-target of a larger template, rather than a standalone build target. 786 787Arguments 788^^^^^^^^^ 789* ``files``: A list of scopes, each containing a ``source`` file to process and 790 a ``dest`` file to which to write the result. 791 792Example 793^^^^^^^ 794The following template defines an executable target which additionally outputs 795the list of object files from which it was compiled, making use of 796``pw_evaluate_path_expressions`` to resolve their paths. 797 798.. code-block:: 799 800 import("$dir_pw_build/evaluate_path_expressions.gni") 801 802 template("executable_with_artifacts") { 803 executable("${target_name}.exe") { 804 sources = invoker.sources 805 if defined(invoker.deps) { 806 deps = invoker.deps 807 } 808 } 809 810 _artifacts_input = "$target_gen_dir/${target_name}_artifacts.json.in" 811 _artifacts_output = "$target_gen_dir/${target_name}_artifacts.json" 812 _artifacts = { 813 binary = "<TARGET_FILE(:${target_name}.exe)>" 814 objects = "<TARGET_OBJECTS(:${target_name}.exe)>" 815 } 816 write_file(_artifacts_input, _artifacts, "json") 817 818 pw_evaluate_path_expressions("${target_name}.evaluate") { 819 files = [ 820 { 821 source = _artifacts_input 822 dest = _artifacts_output 823 }, 824 ] 825 } 826 827 group(target_name) { 828 deps = [ 829 ":${target_name}.exe", 830 ":${target_name}.evaluate", 831 ] 832 } 833 } 834 835.. _module-pw_build-pw_exec: 836 837pw_exec 838------- 839``pw_exec`` allows for execution of arbitrary programs. It is a wrapper around 840``pw_python_action`` but allows for specifying the program to execute. 841 842.. note:: 843 844 Prefer to use ``pw_python_action`` instead of calling out to shell 845 scripts, as the Python will be more portable. ``pw_exec`` should generally 846 only be used for interacting with legacy/existing scripts. 847 848Arguments 849^^^^^^^^^ 850* ``program``: The program to run. Can be a full path or just a name (in which 851 case $PATH is searched). 852* ``args``: Optional list of arguments to the program. 853* ``deps``: Dependencies for this target. 854* ``public_deps``: Public dependencies for this target. In addition to outputs 855 from this target, outputs generated by public dependencies can be used as 856 inputs from targets that depend on this one. This is not the case for private 857 deps. 858* ``inputs``: Optional list of build inputs to the program. 859* ``outputs``: Optional list of artifacts produced by the program's execution. 860* ``env``: Optional list of key-value pairs defining environment variables for 861 the program. 862* ``env_file``: Optional path to a file containing a list of newline-separated 863 key-value pairs defining environment variables for the program. 864* ``args_file``: Optional path to a file containing additional positional 865 arguments to the program. Each line of the file is appended to the 866 invocation. Useful for specifying arguments from GN metadata. 867* ``skip_empty_args``: If args_file is provided, boolean indicating whether to 868 skip running the program if the file is empty. Used to avoid running 869 commands which error when called without arguments. 870* ``capture_output``: If true, output from the program is hidden unless the 871 program exits with an error. Defaults to true. 872* ``working_directory``: The working directory to execute the subprocess with. 873 If not specified it will not be set and the subprocess will have whatever 874 the parent current working directory is. 875* ``venv``: Python virtualenv to pass along to the underlying 876 :ref:`module-pw_build-pw_python_action`. 877* ``visibility``: GN visibility to apply to the underlying target. 878 879Example 880^^^^^^^ 881.. code-block:: 882 883 import("$dir_pw_build/exec.gni") 884 885 pw_exec("hello_world") { 886 program = "/bin/sh" 887 args = [ 888 "-c", 889 "echo hello \$WORLD", 890 ] 891 env = [ 892 "WORLD=world", 893 ] 894 } 895 896pw_input_group 897-------------- 898``pw_input_group`` defines a group of input files which are not directly 899processed by the build but are still important dependencies of later build 900steps. This is commonly used alongside metadata to propagate file dependencies 901through the build graph and force rebuilds on file modifications. 902 903For example ``pw_docgen`` defines a ``pw_doc_group`` template which outputs 904metadata from a list of input files. The metadata file is not actually part of 905the build, and so changes to any of the input files do not trigger a rebuild. 906This is problematic, as targets that depend on the metadata should rebuild when 907the inputs are modified but GN cannot express this dependency. 908 909``pw_input_group`` solves this problem by allowing a list of files to be listed 910in a target that does not output any build artifacts, causing all dependent 911targets to correctly rebuild. 912 913Arguments 914^^^^^^^^^ 915``pw_input_group`` accepts all arguments that can be passed to a ``group`` 916target, as well as requiring one extra: 917 918* ``inputs``: List of input files. 919 920Example 921^^^^^^^ 922.. code-block:: 923 924 import("$dir_pw_build/input_group.gni") 925 926 pw_input_group("foo_metadata") { 927 metadata = { 928 files = [ 929 "x.foo", 930 "y.foo", 931 "z.foo", 932 ] 933 } 934 inputs = metadata.files 935 } 936 937Targets depending on ``foo_metadata`` will rebuild when any of the ``.foo`` 938files are modified. 939 940pw_zip 941------ 942``pw_zip`` is a target that allows users to zip up a set of input files and 943directories into a single output ``.zip`` file—a simple automation of a 944potentially repetitive task. 945 946Arguments 947^^^^^^^^^ 948* ``inputs``: List of source files as well as the desired relative zip 949 destination. See below for the input syntax. 950* ``dirs``: List of entire directories to be zipped as well as the desired 951 relative zip destination. See below for the input syntax. 952* ``output``: Filename of output ``.zip`` file. 953* ``deps``: List of dependencies for the target. 954 955Input Syntax 956^^^^^^^^^^^^ 957Inputs all need to follow the correct syntax: 958 959#. Path to source file or directory. Directories must end with a ``/``. 960#. The delimiter (defaults to ``>``). 961#. The desired destination of the contents within the ``.zip``. Must start 962 with ``/`` to indicate the zip root. Any number of subdirectories are 963 allowed. If the source is a file it can be put into any subdirectory of the 964 root. If the source is a file, the zip copy can also be renamed by ending 965 the zip destination with a filename (no trailing ``/``). 966 967Thus, it should look like the following: ``"[source file or dir] > /"``. 968 969Example 970^^^^^^^ 971Let's say we have the following structure for a ``//source/`` directory: 972 973.. code-block:: 974 975 source/ 976 ├── file1.txt 977 ├── file2.txt 978 ├── file3.txt 979 └── some_dir/ 980 ├── file4.txt 981 └── some_other_dir/ 982 └── file5.txt 983 984And we create the following build target: 985 986.. code-block:: 987 988 import("$dir_pw_build/zip.gni") 989 990 pw_zip("target_name") { 991 inputs = [ 992 "//source/file1.txt > /", # Copied to the zip root dir. 993 "//source/file2.txt > /renamed.txt", # File renamed. 994 "//source/file3.txt > /bar/", # File moved to the /bar/ dir. 995 ] 996 997 dirs = [ 998 "//source/some_dir/ > /bar/some_dir/", # All /some_dir/ contents copied 999 # as /bar/some_dir/. 1000 ] 1001 1002 # Note on output: if the specific output directory isn't defined 1003 # (such as output = "zoo.zip") then the .zip will output to the 1004 # same directory as the BUILD.gn file that called the target. 1005 output = "//$target_out_dir/foo.zip" # Where the foo.zip will end up 1006 } 1007 1008This will result in a ``.zip`` file called ``foo.zip`` stored in 1009``//$target_out_dir`` with the following structure: 1010 1011.. code-block:: 1012 1013 foo.zip 1014 ├── bar/ 1015 │ ├── file3.txt 1016 │ └── some_dir/ 1017 │ ├── file4.txt 1018 │ └── some_other_dir/ 1019 │ └── file5.txt 1020 ├── file1.txt 1021 └── renamed.txt 1022 1023.. _module-pw_build-relative-source-file-names: 1024 1025pw_relative_source_file_names 1026----------------------------- 1027This template recursively walks the listed dependencies and collects the names 1028of all the headers and source files required by the targets, and then transforms 1029them such that they reflect the ``__FILE__`` when pw_build's ``relative_paths`` 1030config is applied. This is primarily intended for side-band generation of 1031pw_tokenizer tokens so file name tokens can be utilized in places where 1032pw_tokenizer is unable to embed token information as part of C/C++ compilation. 1033 1034This template produces a JSON file containing an array of strings (file paths 1035with ``-ffile-prefix-map``-like transformations applied) that can be used to 1036:ref:`generate a token database <module-pw_tokenizer-database-creation>`. 1037 1038Arguments 1039^^^^^^^^^ 1040* ``deps``: A required list of targets to recursively extract file names from. 1041* ``outputs``: A required array with a single element: the path to write the 1042 final JSON file to. 1043 1044Example 1045^^^^^^^ 1046Let's say we have the following project structure: 1047 1048.. code-block:: 1049 1050 project root 1051 ├── foo/ 1052 │ ├── foo.h 1053 │ └── foo.cc 1054 ├── bar/ 1055 │ ├── bar.h 1056 │ └── bar.cc 1057 ├── unused/ 1058 │ ├── unused.h 1059 │ └── unused.cc 1060 └── main.cc 1061 1062And a BUILD.gn at the root: 1063 1064.. code-block:: 1065 1066 pw_source_set("bar") { 1067 public_configs = [ ":bar_headers" ] 1068 public = [ "bar/bar.h" ] 1069 sources = [ "bar/bar.cc" ] 1070 } 1071 1072 pw_source_set("foo") { 1073 public_configs = [ ":foo_headers" ] 1074 public = [ "foo/foo.h" ] 1075 sources = [ "foo/foo.cc" ] 1076 deps = [ ":bar" ] 1077 } 1078 1079 1080 pw_source_set("unused") { 1081 public_configs = [ ":unused_headers" ] 1082 public = [ "unused/unused.h" ] 1083 sources = [ "unused/unused.cc" ] 1084 deps = [ ":bar" ] 1085 } 1086 1087 pw_executable("main") { 1088 sources = [ "main.cc" ] 1089 deps = [ ":foo" ] 1090 } 1091 1092 pw_relative_source_file_names("main_source_files") { 1093 deps = [ ":main" ] 1094 outputs = [ "$target_gen_dir/main_source_files.json" ] 1095 } 1096 1097The json file written to `out/gen/main_source_files.json` will contain: 1098 1099.. code-block:: 1100 1101 [ 1102 "bar/bar.cc", 1103 "bar/bar.h", 1104 "foo/foo.cc", 1105 "foo/foo.h", 1106 "main.cc" 1107 ] 1108 1109Since ``unused`` isn't a transitive dependency of ``main``, its source files 1110are not included. Similarly, even though ``bar`` is not a direct dependency of 1111``main``, its source files *are* included because ``foo`` brings in ``bar`` as 1112a transitive dependency. 1113 1114Note how the file paths in this example are relative to the project root rather 1115than being absolute paths (e.g. ``/home/user/ralph/coding/my_proj/main.cc``). 1116This is a result of transformations applied to strip absolute pathing prefixes, 1117matching the behavior of pw_build's ``$dir_pw_build:relative_paths`` config. 1118 1119Build time errors: pw_error and pw_build_assert 1120----------------------------------------------- 1121In Pigweed's complex, multi-toolchain GN build it is not possible to build every 1122target in every configuration. GN's ``assert`` statement is not ideal for 1123enforcing the correct configuration because it may prevent the GN build files or 1124targets from being referred to at all, even if they aren't used. 1125 1126The ``pw_error`` GN template results in an error if it is executed during the 1127build. These error targets can exist in the build graph, but cannot be depended 1128on without an error. 1129 1130``pw_build_assert`` evaluates to a ``pw_error`` if a condition fails or nothing 1131(an empty group) if the condition passes. Targets can add a dependency on a 1132``pw_build_assert`` to enforce a condition at build time. 1133 1134The templates for build time errors are defined in ``pw_build/error.gni``. 1135 1136.. _module-pw_build-gn-pw_coverage_report: 1137 1138Generate code coverage reports: ``pw_coverage_report`` 1139------------------------------------------------------ 1140Pigweed supports generating coverage reports, in a variety of formats, for C/C++ 1141code using the ``pw_coverage_report`` GN template. 1142 1143Coverage Caveats 1144^^^^^^^^^^^^^^^^ 1145There are currently two code coverage caveats when enabled: 1146 1147#. Coverage reports are only populated based on host tests that use a ``clang`` 1148 toolchain. 1149 1150#. Coverage reports will only show coverage information for headers included in 1151 a test binary. 1152 1153These two caveats mean that all device-specific code that cannot be compiled for 1154and run on the host will not be able to have reports generated for them, and 1155that the existence of these files will not appear in any coverage report. 1156 1157Try to ensure that your code can be written in a way that it can be compiled 1158into a host test for the purpose of coverage reporting, although this is 1159sometimes impossible due to requiring hardware-specific APIs to be available. 1160 1161Coverage Instrumentation 1162^^^^^^^^^^^^^^^^^^^^^^^^ 1163For the ``pw_coverage_report`` to generate meaningful output, you must ensure 1164that it is invoked by a toolchain that instruments tests for code coverage 1165collection and output. 1166 1167Instrumentation is controlled by two GN build arguments: 1168 1169- ``pw_toolchain_COVERAGE_ENABLED`` being set to ``true``. 1170- ``pw_toolchain_PROFILE_SOURCE_FILES`` is an optional argument that provides a 1171 list of source files to selectively collect coverage. 1172 1173.. note:: 1174 1175 It is possible to also instrument binaries for UBSAN, ASAN, or TSAN at the 1176 same time as coverage. However, TSAN will find issues in the coverage 1177 instrumentation code and fail to properly build. 1178 1179This can most easily be done by using the ``host_clang_coverage`` toolchain 1180provided in :ref:`module-pw_toolchain`, but you can also create custom 1181toolchains that manually set these GN build arguments as well. 1182 1183``pw_coverage_report`` 1184^^^^^^^^^^^^^^^^^^^^^^ 1185``pw_coverage_report`` is basically a GN frontend to the ``llvm-cov`` 1186`tool <https://llvm.org/docs/CommandGuide/llvm-cov.html>`_ that can be 1187integrated into the normal build. 1188 1189It can be found at ``pw_build/coverage_report.gni`` and is available through 1190``import("$dir_pw_build/coverage_report.gni")``. 1191 1192The supported report formats are: 1193 1194- ``text``: A text representation of the code coverage report. This 1195 format is not suitable for further machine manipulation and is instead only 1196 useful for cases where a human needs to interpret the report. The text format 1197 provides a nice summary, but if you desire to drill down into the coverage 1198 details more, please consider using ``html`` instead. 1199 1200 - This is equivalent to ``llvm-cov show --format text`` and similar to 1201 ``llvm-cov report``. 1202 1203- ``html``: A static HTML site that provides an overall coverage summary and 1204 per-file information. This format is not suitable for further machine 1205 manipulation and is instead only useful for cases where a human needs to 1206 interpret the report. 1207 1208 - This is equivalent to ``llvm-cov show --format html``. 1209 1210- ``lcov``: A machine-friendly coverage report format. This format is not human- 1211 friendly. If that is necessary, use ``text`` or ``html`` instead. 1212 1213 - This is equivalent to ``llvm-cov export --format lcov``. 1214 1215- ``json``: A machine-friendly coverage report format. This format is not human- 1216 friendly. If that is necessary, use ``text`` or ``html`` instead. 1217 1218 - This is equivalent to ``llvm-cov export --format json``. 1219 1220Arguments 1221""""""""" 1222There are three classes of ``template`` arguments: build, coverage, and test. 1223 1224**Build Arguments:** 1225 1226- ``enable_if`` (optional): Conditionally activates coverage report generation when set to 1227 a boolean expression that evaluates to ``true``. This can be used to allow 1228 project builds to conditionally enable or disable coverage reports to minimize 1229 work needed for certain build configurations. 1230 1231- ``failure_mode`` (optional/unstable): Specify the failure mode for 1232 ``llvm-profdata`` (used to merge inidividual profraw files from ``pw_test`` 1233 runs). Available options are ``"any"`` (default) or ``"all"``. 1234 1235 - This should be considered an unstable/deprecated argument that should only 1236 be used as a last resort to get a build working again. Using 1237 ``failure_mode = "all"`` usually indicates that there are underlying 1238 problems in the build or test infrastructure that should be independently 1239 resolved. Please reach out to the Pigweed team for assistance. 1240 1241**Coverage Arguments:** 1242 1243- ``filter_paths`` (optional): List of file paths to include when generating the 1244 coverage report. These cannot be regular expressions, but can be concrete file 1245 or folder paths. Folder paths will allow all files in that directory or any 1246 recursive child directory. 1247 1248 - These are passed to ``llvm-cov`` by the optional trailing positional 1249 ``[SOURCES]`` arguments. 1250 1251- ``ignore_filename_patterns`` (optional): List of file path regular expressions 1252 to ignore when generating the coverage report. 1253 1254 - These are passed to ``llvm-cov`` via ``--ignore-filename-regex`` named 1255 parameters. 1256 1257**Test Arguments (one of these is required to be provided):** 1258 1259- ``tests``: A list of ``pw_test`` :ref:`targets<module-pw_unit_test-pw_test>`. 1260 1261- ``group_deps``: A list of ``pw_test_group`` 1262 :ref:`targets<module-pw_unit_test-pw_test_group>`. 1263 1264.. note:: 1265 1266 ``tests`` and ``group_deps`` are treated exactly the same by 1267 ``pw_coverage_report``, so it is not that important to ensure they are used 1268 properly. 1269 1270Target Expansion 1271"""""""""""""""" 1272``pw_coverage_report(<target_name>)`` expands to one concrete target for each 1273report format. 1274 1275- ``<target_name>.text``: Generates the ``text`` coverage report. 1276 1277- ``<target_name>.html``: Generates the ``html`` coverage report. 1278 1279- ``<target_name>.lcov``: Generates the ``lcov`` coverage report. 1280 1281- ``<target_name>.json``: Generates the ``json`` coverage report. 1282 1283To use any of these targets, you need only to add a dependency on the desired 1284target somewhere in your build. 1285 1286There is also a ``<target_name>`` target generated that is a ``group`` that adds 1287a dependency on all of the format-specific targets listed above. 1288 1289.. note:: 1290 These targets are always available, even when the toolchain executing the 1291 target does not support coverage or coverage is not enabled. In these cases, 1292 the targets are set to empty groups. 1293 1294Coverage Output 1295^^^^^^^^^^^^^^^ 1296Coverage reports are currently generated and placed into the build output 1297directory associated with the path to the GN file where the 1298``pw_coverage_report`` is used in a subfolder named 1299``<target_name>.<report_type>``. 1300 1301.. note:: 1302 1303 Due to limitations with telling GN the entire output of coverage reports 1304 (stemming from per-source-file generation for HTML and text representations), 1305 it is not as simple as using GN's built-in ``copy`` to be able to move these 1306 coverage reports to another output location. However, it seems possible to add 1307 a target that can use Python to copy the entire output directory. 1308 1309Improved Ninja interface 1310------------------------ 1311Ninja includes a basic progress display, showing in a single line the number of 1312targets finished, the total number of targets, and the name of the most recent 1313target it has either started or finished. 1314 1315For additional insight into the status of the build, Pigweed includes a Ninja 1316wrapper, ``pw-wrap-ninja``, that displays additional real-time information about 1317the progress of the build. The wrapper is invoked the same way you'd normally 1318invoke Ninja: 1319 1320.. code-block:: sh 1321 1322 pw-wrap-ninja -C out 1323 1324The script lists the progress of the build, as well as the list of targets that 1325Ninja is currently building, along with a timer that measures how long each 1326target has been building for: 1327 1328.. code-block:: 1329 1330 [51.3s] Building [8924/10690] ... 1331 [10.4s] c++ pw_strict_host_clang_debug/obj/pw_string/string_test.lib.string_test.cc.o 1332 [ 9.5s] ACTION //pw_console/py:py.lint.mypy(//pw_build/python_toolchain:python) 1333 [ 9.4s] ACTION //pw_console/py:py.lint.pylint(//pw_build/python_toolchain:python) 1334 [ 6.1s] clang-tidy ../pw_log_rpc/log_service.cc 1335 [ 6.1s] clang-tidy ../pw_log_rpc/log_service_test.cc 1336 [ 6.1s] clang-tidy ../pw_log_rpc/rpc_log_drain.cc 1337 [ 6.1s] clang-tidy ../pw_log_rpc/rpc_log_drain_test.cc 1338 [ 5.4s] c++ pw_strict_host_clang_debug/obj/BUILD_DIR/pw_strict_host_clang_debug/gen/pw... 1339 ... and 109 more 1340 1341This allows you to, at a glance, know what Ninja's currently building, which 1342targets are bottlenecking the rest of the build, and which targets are taking 1343an unusually long time to complete. 1344 1345``pw-wrap-ninja`` includes other useful functionality as well. The 1346``--write-trace`` option writes a build trace to the specified path, which can 1347be viewed in the `Perfetto UI <https://ui.perfetto.dev/>`_, or via Chrome's 1348built-in ``chrome://tracing`` tool. 1349 1350.. _module-pw_build-gn-pw_linker_script: 1351 1352pw_linker_script 1353---------------- 1354Preprocess a linker script and turn it into a target. 1355 1356In lieu of direct GN support for linker scripts, this template makes it 1357possible to run the C Preprocessor on a linker script file so defines can 1358be properly evaluated before the linker script is passed to linker. 1359 1360Arguments 1361^^^^^^^^^ 1362- ``linker_script``: The linker script to send through the C preprocessor. 1363 1364- ``defines``: Preprocessor defines to apply when running the C preprocessor. 1365 1366- ``cflags``: Flags to pass to the C compiler. 1367 1368- ``includes``: Include these files when running the C preprocessor. 1369 1370- ``inputs``: Files that, when changed, should trigger a re-build of the linker 1371 script. linker_script and includes are implicitly added to this by the 1372 template. 1373 1374Example 1375^^^^^^^ 1376.. code-block:: 1377 1378 pw_linker_script("generic_linker_script") { 1379 defines = [ 1380 "PW_HEAP_SIZE=1K", 1381 "PW_NOINIT_SIZE=512" 1382 ] 1383 linker_script = "basic_script.ld" 1384 } 1385