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