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