xref: /aosp_15_r20/external/pigweed/pw_toolchain/gn.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_toolchain-gn:
2
3============================
4GN build system integrations
5============================
6``pw_toolchain`` module provides GN toolchains that may be used to build
7Pigweed. GN toolchains function both as a set of tools for compilation and as a
8workspace for evaluating build files. The same compilations and actions can be
9executed by different toolchains. Each toolchain maintains its own set of
10`build args <https://gn.googlesource.com/gn/+/main/docs/reference.md#buildargs>`_,
11and build steps from all toolchains can be executed in parallel.
12
13Various GCC and Clang toolchains for multiple platforms are provided.
14Toolchains names typically include the compiler (``clang`` or ``gcc`` and
15optimization level (``debug``, ``size_optimized``, ``speed_optimized``).
16
17--------------------
18Non-C/C++ toolchains
19--------------------
20``pw_toolchain/non_c_toolchain.gni`` provides the ``pw_non_c_toolchain``
21template. This template creates toolchains that cannot compile C/C++ source
22code. These toolchains may only be used to execute GN actions or declare groups
23of targets in other toolchains. Attempting to compile C/C++ code with either of
24these toolchains results in errors.
25
26Non-C/C++ toolchains can be used to consolidate actions that should only occur
27once in a multi-toolchain build. Build targets from all toolchains can refer to
28these actions in a non-C/C++ toolchain so they only execute once instead of once
29per toolchain.
30
31For example, Pigweed runs protobuf compilation and Python package actions like
32installation and Pylint in toolchains created with ``pw_non_c_toolchain``. This
33allows all toolchains to cleanly share the same protobuf and Python declarations
34without any duplicated work.
35
36-------------------------------
37Testing other compiler versions
38-------------------------------
39The clang-based toolchain provided by Pigweed can be substituted with another
40version by modifying the ``pw_toolchain_CLANG_PREFIX`` GN build argument to
41point to the directory that contains the desired clang, clang++, and llvm-ar
42binaries. This should only be used for debugging purposes. Pigweed does not
43officially support any compilers other than those provided by Pigweed.
44
45------------------------------
46Running static analysis checks
47------------------------------
48``clang-tidy`` can be run as a compiler replacement, to analyze all sources
49built for a target. ``pw_toolchain/static_analysis_toolchain.gni`` provides
50the ``pw_static_analysis_toolchain`` template. This template creates toolchains
51that execute ``clang-tidy`` for C/C++ sources, and mock implementations of
52the ``link``, ``alink`` and ``solink`` tools.
53
54In addition to the standard toolchain requirements (``cc``, ``cxx``, etc.), the
55``pw_static_analysis_toolchain`` template requires a scope ``static_analysis``
56to be defined on the invoker.
57
58.. code-block::
59
60   static_analysis = {
61    # Configure whether static_analysis should be enabled for invoker toolchain.
62    # This is must be set true if using pw_static_analysis_toolchain.
63    enabled = true
64    # Optionally override clang-tidy binary to use by setting to proper path.
65    clang_tidy_path = ""
66    # Optionally specify additional command(s) to run as part of cc tool.
67    cc_post = ""
68    # Optionally specify additional command(s) to run as part of cxx tool.
69    cxx_post = ""
70   }
71
72The ``generate_toolchain`` supports the above mentioned ``static_analysis``
73scope, which if specified must at the very least define the bool ``enabled``
74within the scope. If the ``static_analysis`` scope is provided and
75``static_analysis.enabled = true``, the derived toolchain
76``${target_name}.static_analysis`` will be generated using
77``pw_generate_static_analysis_toolchain`` and the toolchain options.
78
79An example on the utility of the ``static_analysis`` scope args is shown in the
80snippet below where we enable clang-tidy caching and add ``//.clang-tidy`` as a
81dependency to the generated ``.d`` files for the
82``pw_static_analysis_toolchain``.
83
84.. code-block::
85
86   static_analysis = {
87    clang_tidy_path = "//third_party/ctcache/clang-tidy"
88    _clang_tidy_cfg_path = rebase_path("//.clang-tidy", root_build_dir)
89    cc_post = "echo '-: $_clang_tidy_cfg_path' >> {{output}}.d"
90    cxx_post = "echo '-: $_clang_tidy_cfg_path' >> {{output}}.d"
91   }
92
93Excluding files from checks
94===========================
95The build argument ``pw_toolchain_STATIC_ANALYSIS_SKIP_SOURCES_RES`` is used
96to exclude source files from the analysis. The list must contain regular
97expressions matching individual files, rather than directories. For example,
98provide ``"the_path/.*"`` to exclude all files in all directories under
99``the_path``.
100
101The build argument ``pw_toolchain_STATIC_ANALYSIS_SKIP_INCLUDE_PATHS`` is used
102used to exclude header files from the analysis. This argument must be a list of
103POSIX-style path suffixes for include paths, or regular expressions matching
104include paths. For example, passing ``the_path/include`` excludes all header
105files that are accessed from include paths ending in ``the_path/include``,
106while passing ``.*/third_party/.*`` excludes all third-party header files.
107
108Note that ``pw_toolchain_STATIC_ANALYSIS_SKIP_INCLUDE_PATHS`` operates on
109include paths, not header file paths. For example, say your compile commands
110include ``-Idrivers``, and this results in a file at ``drivers/public/i2c.h``
111being included. You can skip this header by adding ``drivers`` or ``drivers.*``
112to ``pw_toolchain_STATIC_ANALYSIS_SKIP_INCLUDE_PATHS``, but *not* by adding
113``drivers/.*``: this last regex matches the header file path, but not the
114include path.
115
116Provided toolchains
117===================
118``pw_toolchain`` provides static analysis GN toolchains that may be used to
119test host targets:
120
121- pw_toolchain_host_clang.debug.static_analysis
122- pw_toolchain_host_clang.speed_optimized.static_analysis
123- pw_toolchain_host_clang.size_optimized.static_analysis
124- pw_toolchain_host_clang.fuzz.static_analysis
125  (if pw_toolchain_OSS_FUZZ_ENABLED is false)
126- pw_toolchain_arm_clang.debug.static_analysis
127- pw_toolchain_arm_clang.speed_optimized.static_analysis
128- pw_toolchain_arm_clang.size_optimized.static_analysis
129
130For example, to run ``clang-tidy`` on all source dependencies of the
131``default`` target:
132
133.. code-block::
134
135   generate_toolchain("my_toolchain") {
136     ..
137     static_analysis = {
138      enabled = true
139     }
140   }
141
142   group("static_analysis") {
143     deps = [ ":default(my_toolchain.static_analysis)" ]
144   }
145
146.. warning::
147
148   The status of the static analysis checks might change when
149   any relevant .clang-tidy file is updated. You should
150   clean the output directory before invoking
151   ``clang-tidy``.
152
153-------------
154Target traits
155-------------
156Pigweed targets expose a set of constants that describe properties of the target
157or the toolchain compiling code for it. These are referred to as target traits.
158
159In GN, these traits are exposed as GN args and are prefixed with
160``pw_toolchain_`` (e.g. ``pw_toolchain_CXX_STANDARD``). They are defined in
161``pw_toolchain/traits.gni``.
162
163Traits must never be set by the user (e.g. with ``gn args``). Traits are always
164set by the target.
165
166.. warning::
167
168   This feature is under development and is likely to change significantly.
169   See `b/234883746 <http://issuetracker.google.com/issues/234883746>`_.
170
171List of traits
172==============
173- ``CXX_STANDARD``. The C++ standard used by the toolchain. The value must be an
174  integer value matching one of the standard values for the ``__cplusplus``
175  macro. For example, ``201703`` corresponds to C++17. See
176  https://en.cppreference.com/w/cpp/preprocessor/replace#Predefined_macros for
177  further details.
178