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