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 | 8bd4fb0 | 2021-05-03 15:30:58 -0700 | [diff] [blame] | 75 | .. _module-pw_build-link-deps: |
| 76 | |
| 77 | Link-only deps |
| 78 | -------------- |
| 79 | It may be necessary to specify additional link-time dependencies that may not be |
| 80 | explicitly depended on elsewhere in the build. One example of this is a |
| 81 | ``pw_assert`` backend, which may need to leave out dependencies to avoid |
| 82 | circular dependencies. Its dependencies need to be linked for executables and |
| 83 | libraries, even if they aren't pulled in elsewhere. |
| 84 | |
| 85 | The ``pw_build_LINK_DEPS`` build arg is a list of dependencies to add to all |
| 86 | ``pw_executable``, ``pw_static_library``, and ``pw_shared_library`` targets. |
| 87 | This should only be used as a last resort when dependencies cannot be properly |
| 88 | expressed in the build. |
| 89 | |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 90 | Python packages |
| 91 | --------------- |
| 92 | GN templates for :ref:`Python build automation <docs-python-build>` are |
| 93 | described in :ref:`module-pw_build-python`. |
| 94 | |
| 95 | .. toctree:: |
| 96 | :hidden: |
| 97 | |
| 98 | python |
| 99 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 100 | .. _module-pw_build-facade: |
| 101 | |
| 102 | pw_facade |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 103 | --------- |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 104 | In their simplest form, a :ref:`facade<docs-module-structure-facades>` is a GN |
| 105 | build arg used to change a dependency at compile time. Pigweed targets configure |
| 106 | these facades as needed. |
| 107 | |
| 108 | The ``pw_facade`` template bundles a ``pw_source_set`` with a facade build arg. |
| 109 | This allows the facade to provide header files, compilation options or anything |
| 110 | else a GN ``source_set`` provides. |
| 111 | |
| 112 | The ``pw_facade`` template declares two targets: |
| 113 | |
| 114 | * ``$target_name``: the public-facing ``pw_source_set``, with a ``public_dep`` |
| 115 | on the backend |
| 116 | * ``$target_name.facade``: target used by the backend to avoid circular |
| 117 | dependencies |
| 118 | |
| 119 | .. code-block:: |
| 120 | |
| 121 | # Declares ":foo" and ":foo.facade" GN targets |
| 122 | pw_facade("foo") { |
| 123 | backend = pw_log_BACKEND |
| 124 | public_configs = [ ":public_include_path" ] |
| 125 | public = [ "public/pw_foo/foo.h" ] |
| 126 | } |
| 127 | |
Wyatt Hepler | 6166322 | 2021-05-06 10:57:43 -0700 | [diff] [blame] | 128 | Low-level facades like ``pw_assert`` cannot express all of their dependencies |
| 129 | due to the potential for dependency cycles. Facades with this issue may require |
| 130 | backends to place their implementations in a separate build target to be listed |
| 131 | in ``pw_build_LINK_DEPS`` (see :ref:`module-pw_build-link-deps`). The |
| 132 | ``require_link_deps`` variable in ``pw_facade`` asserts that all specified build |
| 133 | targets are present in ``pw_build_LINK_DEPS`` if the facade's backend variable |
| 134 | is set. |
| 135 | |
Wyatt Hepler | 0d32d1d | 2020-10-23 08:05:23 -0700 | [diff] [blame] | 136 | .. _module-pw_build-python-action: |
Alexei Frolov | 199045a | 2020-08-28 13:02:30 -0700 | [diff] [blame] | 137 | |
Wyatt Hepler | c8e05a4 | 2020-10-19 14:49:39 -0700 | [diff] [blame] | 138 | pw_python_action |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 139 | ---------------- |
Wyatt Hepler | c8e05a4 | 2020-10-19 14:49:39 -0700 | [diff] [blame] | 140 | The ``pw_python_action`` template is a convenience wrapper around ``action`` for |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 141 | running Python scripts. The main benefit it provides is resolution of GN target |
| 142 | labels to compiled binary files. This allows Python scripts to be written |
| 143 | independently of GN, taking only filesystem paths as arguments. |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 144 | |
| 145 | Another convenience provided by the template is to allow running scripts without |
| 146 | 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] | 147 | 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] | 148 | solves this by accepting a boolean ``stamp`` argument which tells it to create a |
| 149 | dummy output file for the action. |
| 150 | |
| 151 | **Arguments** |
| 152 | |
Wyatt Hepler | c8e05a4 | 2020-10-19 14:49:39 -0700 | [diff] [blame] | 153 | ``pw_python_action`` accepts all of the arguments of a regular ``action`` |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 154 | target. Additionally, it has some of its own arguments: |
| 155 | |
Wyatt Hepler | 79d983f | 2020-10-12 08:46:34 -0700 | [diff] [blame] | 156 | * ``module``: Run the specified Python module instead of a script. Either |
| 157 | ``script`` or ``module`` must be specified, but not both. |
Wyatt Hepler | a74f7b0 | 2020-07-23 14:10:56 -0700 | [diff] [blame] | 158 | * ``capture_output``: Optional boolean. If true, script output is hidden unless |
| 159 | the script fails with an error. Defaults to true. |
| 160 | * ``stamp``: Optional variable indicating whether to automatically create a |
| 161 | dummy output file for the script. This allows running scripts without |
| 162 | specifying ``outputs``. If ``stamp`` is true, a generic output file is |
| 163 | used. If ``stamp`` is a file path, that file is used as a stamp file. Like any |
| 164 | output file, ``stamp`` must be in the build directory. Defaults to false. |
Wyatt Hepler | 79d983f | 2020-10-12 08:46:34 -0700 | [diff] [blame] | 165 | * ``directory``: Optional path. Change to this directory before executing the |
| 166 | command. Paths in arguments may need to be adjusted. |
| 167 | * ``environment``: Optional list of strings. Environment variables to set, |
| 168 | passed as NAME=VALUE strings. |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 169 | |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 170 | **Expressions** |
| 171 | |
Wyatt Hepler | c8e05a4 | 2020-10-19 14:49:39 -0700 | [diff] [blame] | 172 | ``pw_python_action`` evaluates expressions in ``args``, the arguments passed to |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 173 | the script. These expressions function similarly to generator expressions in |
| 174 | CMake. Expressions may be passed as a standalone argument or as part of another |
| 175 | argument. A single argument may contain multiple expressions. |
| 176 | |
| 177 | Generally, these expressions are used within templates rather than directly in |
| 178 | BUILD.gn files. This allows build code to use GN labels without having to worry |
| 179 | about converting them to files. |
| 180 | |
Wyatt Hepler | a2ddc41 | 2021-03-16 13:47:29 -0700 | [diff] [blame] | 181 | .. note:: |
| 182 | |
| 183 | We intend to replace these expressions with native GN features when possible. |
| 184 | See `pwbug/347 <http://bugs.pigweed.dev/347>`_. |
| 185 | |
Wyatt Hepler | 53a06fb | 2020-07-31 13:04:56 -0700 | [diff] [blame] | 186 | The following expressions are supported: |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 187 | |
| 188 | .. describe:: <TARGET_FILE(gn_target)> |
| 189 | |
| 190 | Evaluates to the output file of the provided GN target. For example, the |
| 191 | expression |
| 192 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 193 | .. code-block:: |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 194 | |
| 195 | "<TARGET_FILE(//foo/bar:static_lib)>" |
| 196 | |
| 197 | might expand to |
| 198 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 199 | .. code-block:: |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 200 | |
| 201 | "/home/User/project_root/out/obj/foo/bar/static_lib.a" |
| 202 | |
| 203 | ``TARGET_FILE`` parses the ``.ninja`` file for the GN target, so it should |
| 204 | always find the correct output file, regardless of the toolchain's or target's |
| 205 | configuration. Some targets, such as ``source_set`` and ``group`` targets, do |
| 206 | not have an output file, and attempting to use ``TARGET_FILE`` with them |
| 207 | results in an error. |
| 208 | |
| 209 | ``TARGET_FILE`` only resolves GN target labels to their outputs. To resolve |
| 210 | paths generally, use the standard GN approach of applying the |
| 211 | ``rebase_path(path)`` function. With default arguments, ``rebase_path`` |
| 212 | converts the provided GN path or list of paths to be relative to the build |
| 213 | directory, from which all build commands and scripts are executed. |
| 214 | |
Wyatt Hepler | 53a06fb | 2020-07-31 13:04:56 -0700 | [diff] [blame] | 215 | .. describe:: <TARGET_FILE_IF_EXISTS(gn_target)> |
| 216 | |
| 217 | ``TARGET_FILE_IF_EXISTS`` evaluates to the output file of the provided GN |
| 218 | target, if the output file exists. If the output file does not exist, the |
| 219 | entire argument that includes this expression is omitted, even if there is |
| 220 | other text or another expression. |
| 221 | |
| 222 | For example, consider this expression: |
| 223 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 224 | .. code-block:: |
Wyatt Hepler | 53a06fb | 2020-07-31 13:04:56 -0700 | [diff] [blame] | 225 | |
| 226 | "--database=<TARGET_FILE_IF_EXISTS(//alpha/bravo)>" |
| 227 | |
| 228 | If the ``//alpha/bravo`` target file exists, this might expand to the |
| 229 | following: |
| 230 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 231 | .. code-block:: |
Wyatt Hepler | 53a06fb | 2020-07-31 13:04:56 -0700 | [diff] [blame] | 232 | |
| 233 | "--database=/home/User/project/out/obj/alpha/bravo/bravo.elf" |
| 234 | |
| 235 | If the ``//alpha/bravo`` target file does not exist, the entire |
| 236 | ``--database=`` argument is omitted from the script arguments. |
| 237 | |
| 238 | .. describe:: <TARGET_OBJECTS(gn_target)> |
| 239 | |
| 240 | Evaluates to the object files of the provided GN target. Expands to a separate |
| 241 | argument for each object file. If the target has no object files, the argument |
| 242 | is omitted entirely. Because it does not expand to a single expression, the |
| 243 | ``<TARGET_OBJECTS(...)>`` expression may not have leading or trailing text. |
| 244 | |
| 245 | For example, the expression |
| 246 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 247 | .. code-block:: |
Wyatt Hepler | 53a06fb | 2020-07-31 13:04:56 -0700 | [diff] [blame] | 248 | |
| 249 | "<TARGET_OBJECTS(//foo/bar:a_source_set)>" |
| 250 | |
| 251 | might expand to multiple separate arguments: |
| 252 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 253 | .. code-block:: |
Wyatt Hepler | 53a06fb | 2020-07-31 13:04:56 -0700 | [diff] [blame] | 254 | |
| 255 | "/home/User/project_root/out/obj/foo/bar/a_source_set.file_a.cc.o" |
| 256 | "/home/User/project_root/out/obj/foo/bar/a_source_set.file_b.cc.o" |
| 257 | "/home/User/project_root/out/obj/foo/bar/a_source_set.file_c.cc.o" |
| 258 | |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 259 | **Example** |
| 260 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 261 | .. code-block:: |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 262 | |
Wyatt Hepler | 51ded74 | 2020-10-19 14:45:27 -0700 | [diff] [blame] | 263 | import("$dir_pw_build/python_action.gni") |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 264 | |
Wyatt Hepler | c8e05a4 | 2020-10-19 14:49:39 -0700 | [diff] [blame] | 265 | pw_python_action("postprocess_main_image") { |
Wyatt Hepler | 8224a64 | 2020-07-29 08:55:56 -0700 | [diff] [blame] | 266 | script = "py/postprocess_binary.py" |
| 267 | args = [ |
| 268 | "--database", |
| 269 | rebase_path("my/database.csv"), |
| 270 | "--binary=<TARGET_FILE(//firmware/images:main)>", |
| 271 | ] |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 272 | stamp = true |
| 273 | } |
| 274 | |
| 275 | pw_input_group |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 276 | -------------- |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 277 | ``pw_input_group`` defines a group of input files which are not directly |
| 278 | processed by the build but are still important dependencies of later build |
| 279 | steps. This is commonly used alongside metadata to propagate file dependencies |
| 280 | through the build graph and force rebuilds on file modifications. |
| 281 | |
| 282 | For example ``pw_docgen`` defines a ``pw_doc_group`` template which outputs |
| 283 | metadata from a list of input files. The metadata file is not actually part of |
| 284 | the build, and so changes to any of the input files do not trigger a rebuild. |
| 285 | This is problematic, as targets that depend on the metadata should rebuild when |
| 286 | the inputs are modified but GN cannot express this dependency. |
| 287 | |
| 288 | ``pw_input_group`` solves this problem by allowing a list of files to be listed |
| 289 | in a target that does not output any build artifacts, causing all dependent |
| 290 | targets to correctly rebuild. |
| 291 | |
| 292 | **Arguments** |
| 293 | |
| 294 | ``pw_input_group`` accepts all arguments that can be passed to a ``group`` |
| 295 | target, as well as requiring one extra: |
| 296 | |
| 297 | * ``inputs``: List of input files. |
| 298 | |
| 299 | **Example** |
| 300 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 301 | .. code-block:: |
Alexei Frolov | 69ad192 | 2019-12-13 13:11:32 -0800 | [diff] [blame] | 302 | |
| 303 | import("$dir_pw_build/input_group.gni") |
| 304 | |
| 305 | pw_input_group("foo_metadata") { |
| 306 | metadata = { |
| 307 | files = [ |
| 308 | "x.foo", |
| 309 | "y.foo", |
| 310 | "z.foo", |
| 311 | ] |
| 312 | } |
| 313 | inputs = metadata.files |
| 314 | } |
| 315 | |
| 316 | Targets depending on ``foo_metadata`` will rebuild when any of the ``.foo`` |
| 317 | files are modified. |
Rob Mohr | 84f234e | 2019-12-06 09:16:50 -0800 | [diff] [blame] | 318 | |
Sam McCauley | 0da412c | 2020-10-02 10:34:56 -0700 | [diff] [blame] | 319 | pw_zip |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 320 | ------ |
Sam McCauley | 0da412c | 2020-10-02 10:34:56 -0700 | [diff] [blame] | 321 | ``pw_zip`` is a target that allows users to zip up a set of input files and |
| 322 | directories into a single output ``.zip`` file—a simple automation of a |
| 323 | potentially repetitive task. |
| 324 | |
| 325 | **Arguments** |
| 326 | |
| 327 | * ``inputs``: List of source files as well as the desired relative zip |
| 328 | destination. See below for the input syntax. |
| 329 | * ``dirs``: List of entire directories to be zipped as well as the desired |
| 330 | relative zip destination. See below for the input syntax. |
| 331 | * ``output``: Filename of output ``.zip`` file. |
| 332 | * ``deps``: List of dependencies for the target. |
| 333 | |
| 334 | **Input Syntax** |
| 335 | |
| 336 | Inputs all need to follow the correct syntax: |
| 337 | |
| 338 | #. Path to source file or directory. Directories must end with a ``/``. |
| 339 | #. The delimiter (defaults to ``>``). |
| 340 | #. The desired destination of the contents within the ``.zip``. Must start |
| 341 | with ``/`` to indicate the zip root. Any number of subdirectories are |
| 342 | allowed. If the source is a file it can be put into any subdirectory of the |
| 343 | root. If the source is a file, the zip copy can also be renamed by ending |
| 344 | the zip destination with a filename (no trailing ``/``). |
| 345 | |
| 346 | Thus, it should look like the following: ``"[source file or dir] > /"``. |
| 347 | |
| 348 | **Example** |
| 349 | |
| 350 | Let's say we have the following structure for a ``//source/`` directory: |
| 351 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 352 | .. code-block:: |
Sam McCauley | 0da412c | 2020-10-02 10:34:56 -0700 | [diff] [blame] | 353 | |
| 354 | source/ |
| 355 | ├── file1.txt |
| 356 | ├── file2.txt |
| 357 | ├── file3.txt |
| 358 | └── some_dir/ |
| 359 | ├── file4.txt |
| 360 | └── some_other_dir/ |
| 361 | └── file5.txt |
| 362 | |
| 363 | And we create the following build target: |
| 364 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 365 | .. code-block:: |
Sam McCauley | 0da412c | 2020-10-02 10:34:56 -0700 | [diff] [blame] | 366 | |
| 367 | import("$dir_pw_build/zip.gni") |
| 368 | |
| 369 | pw_zip("target_name") { |
| 370 | inputs = [ |
| 371 | "//source/file1.txt > /", # Copied to the zip root dir. |
| 372 | "//source/file2.txt > /renamed.txt", # File renamed. |
| 373 | "//source/file3.txt > /bar/", # File moved to the /bar/ dir. |
| 374 | ] |
| 375 | |
| 376 | dirs = [ |
| 377 | "//source/some_dir/ > /bar/some_dir/", # All /some_dir/ contents copied |
| 378 | # as /bar/some_dir/. |
| 379 | ] |
| 380 | |
| 381 | # Note on output: if the specific output directory isn't defined |
| 382 | # (such as output = "zoo.zip") then the .zip will output to the |
| 383 | # same directory as the BUILD.gn file that called the target. |
| 384 | output = "//$target_out_dir/foo.zip" # Where the foo.zip will end up |
| 385 | } |
| 386 | |
| 387 | This will result in a ``.zip`` file called ``foo.zip`` stored in |
| 388 | ``//$target_out_dir`` with the following structure: |
| 389 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 390 | .. code-block:: |
Sam McCauley | 0da412c | 2020-10-02 10:34:56 -0700 | [diff] [blame] | 391 | |
| 392 | foo.zip |
| 393 | ├── bar/ |
| 394 | │  ├── file3.txt |
| 395 | │  └── some_dir/ |
| 396 | │  ├── file4.txt |
| 397 | │  └── some_other_dir/ |
| 398 | │  └── file5.txt |
| 399 | ├── file1.txt |
| 400 | └── renamed.txt |
| 401 | |
Wyatt Hepler | b59d2c9 | 2021-05-11 11:20:43 -0700 | [diff] [blame] | 402 | CMake |
| 403 | ===== |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 404 | Pigweed's `CMake`_ support is provided primarily for projects that have an |
| 405 | existing CMake build and wish to integrate Pigweed without switching to a new |
| 406 | build system. |
Armando Montanez | bcc194b | 2020-03-10 10:23:18 -0700 | [diff] [blame] | 407 | |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 408 | The following command generates Ninja build files for a host build in the |
| 409 | ``out/cmake_host`` directory: |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 410 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 411 | .. code-block:: sh |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 412 | |
Wyatt Hepler | dcfa92b | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 413 | cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake |
| 414 | |
| 415 | The ``PW_ROOT`` environment variable must point to the root of the Pigweed |
| 416 | directory. This variable is set by Pigweed's environment setup. |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 417 | |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 418 | Tests can be executed with the ``pw_run_tests.GROUP`` targets. To run Pigweed |
| 419 | module tests, execute ``pw_run_tests.modules``: |
| 420 | |
| 421 | .. code-block:: sh |
| 422 | |
| 423 | ninja -C out/cmake_host pw_run_tests.modules |
| 424 | |
| 425 | :ref:`module-pw_watch` supports CMake, so you can also run |
| 426 | |
| 427 | .. code-block:: sh |
| 428 | |
Wyatt Hepler | 00efe18 | 2020-11-23 08:25:14 -0800 | [diff] [blame] | 429 | pw watch -C out/cmake_host pw_run_tests.modules |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 430 | |
| 431 | CMake functions |
| 432 | --------------- |
| 433 | CMake convenience functions are defined in ``pw_build/pigweed.cmake``. |
| 434 | |
| 435 | * ``pw_auto_add_simple_module`` -- For modules with only one library, |
| 436 | automatically declare the library and its tests. |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 437 | * ``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] | 438 | * ``pw_add_facade`` -- Declare a module facade. |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 439 | * ``pw_set_backend`` -- Set the backend library to use for a facade. |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 440 | * ``pw_add_module_library`` -- Add a library that is part of a module. |
| 441 | * ``pw_add_test`` -- Declare a test target. |
| 442 | |
| 443 | See ``pw_build/pigweed.cmake`` for the complete documentation of these |
| 444 | functions. |
| 445 | |
| 446 | Special libraries that do not fit well with these functions are created with the |
| 447 | standard CMake functions, such as ``add_library`` and ``target_link_libraries``. |
| 448 | |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 449 | Facades and backends |
| 450 | -------------------- |
| 451 | The CMake build uses CMake cache variables for configuring |
| 452 | :ref:`facades<docs-module-structure-facades>` and backends. Cache variables are |
| 453 | similar to GN's build args set with ``gn args``. Unlike GN, CMake does not |
| 454 | support multi-toolchain builds, so these variables have a single global value |
| 455 | per build directory. |
| 456 | |
| 457 | The ``pw_add_facade`` function declares a cache variable named |
| 458 | ``<module_name>_BACKEND`` for each facade. Cache variables can be awkward to |
| 459 | 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] | 460 | persist accross CMake invocations. These variables should be set in one of the |
| 461 | following ways: |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 462 | |
Wyatt Hepler | d9336a4 | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 463 | * 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] | 464 | target's toolchain file. The toolchain file is provided to ``cmake`` with |
| 465 | ``-DCMAKE_TOOLCHAIN_FILE=<toolchain file>``. |
Wyatt Hepler | d9336a4 | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 466 | * Call ``pw_set_backend`` in the top-level ``CMakeLists.txt`` before other |
| 467 | CMake code executes. |
| 468 | * Set the backend variable at the command line with the ``-D`` option. |
| 469 | |
| 470 | .. code-block:: sh |
| 471 | |
| 472 | cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \ |
| 473 | -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \ |
| 474 | -Dpw_log_BACKEND=pw_log_basic |
| 475 | |
| 476 | * Temporarily override a backend by setting it interactively with ``ccmake`` or |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 477 | ``cmake-gui``. |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 478 | |
Wyatt Hepler | 8026d8d | 2021-05-11 11:37:29 -0700 | [diff] [blame] | 479 | If the backend is set to a build target that does not exist, there will be an |
| 480 | error message like the following: |
| 481 | |
| 482 | .. code-block:: |
| 483 | |
| 484 | CMake Error at pw_build/pigweed.cmake:244 (add_custom_target): |
| 485 | Error evaluating generator expression: |
| 486 | |
| 487 | $<TARGET_PROPERTY:my_backend_that_does_not_exist,TYPE> |
| 488 | |
| 489 | Target "my_backend_that_does_not_exist" not found. |
| 490 | |
Wyatt Hepler | 73439f7 | 2020-11-03 14:28:11 -0800 | [diff] [blame] | 491 | Toolchain setup |
| 492 | --------------- |
| 493 | In CMake, the toolchain is configured by setting CMake variables, as described |
| 494 | in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_. |
| 495 | These variables are typically set in a toolchain CMake file passed to ``cmake`` |
| 496 | with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``). |
| 497 | For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string |
| 498 | (``""``). |
| 499 | |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 500 | Third party libraries |
| 501 | --------------------- |
| 502 | The CMake build includes third-party libraries similarly to the GN build. A |
| 503 | ``dir_pw_third_party_<library>`` cache variable is defined for each third-party |
Wyatt Hepler | 8f357f4 | 2021-03-17 15:37:09 -0700 | [diff] [blame] | 504 | dependency. The variable must be set to the absolute path of the library in |
| 505 | order to use it. If the variable is empty |
| 506 | (``if("${dir_pw_third_party_<library>}" STREQUAL "")``), the dependency is not |
| 507 | available. |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 508 | |
Wyatt Hepler | 8f357f4 | 2021-03-17 15:37:09 -0700 | [diff] [blame] | 509 | Third-party dependencies are not automatically added to the build. They can be |
| 510 | manually added with ``add_subdirectory`` or by setting the |
| 511 | ``pw_third_party_<library>_ADD_SUBDIRECTORY`` option to ``ON``. |
Wyatt Hepler | c9e51d2 | 2020-10-29 09:12:37 -0700 | [diff] [blame] | 512 | |
Wyatt Hepler | d9336a4 | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 513 | Third party variables are set like any other cache global variable in CMake. It |
| 514 | is recommended to set these in one of the following ways: |
Wyatt Hepler | dcfa92b | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 515 | |
Wyatt Hepler | d9336a4 | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 516 | * Set with the CMake ``set`` function in the toolchain file or a |
| 517 | ``CMakeLists.txt`` before other CMake code executes. |
Wyatt Hepler | dcfa92b | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 518 | |
Wyatt Hepler | d9336a4 | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 519 | .. code-block:: cmake |
Wyatt Hepler | dcfa92b | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 520 | |
Wyatt Hepler | 8f357f4 | 2021-03-17 15:37:09 -0700 | [diff] [blame] | 521 | set(dir_pw_third_party_nanopb ${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb CACHE PATH "" FORCE) |
Wyatt Hepler | d9336a4 | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 522 | |
| 523 | * Set the variable at the command line with the ``-D`` option. |
| 524 | |
| 525 | .. code-block:: sh |
| 526 | |
| 527 | cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \ |
| 528 | -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \ |
| 529 | -Ddir_pw_third_party_nanopb=/path/to/nanopb |
| 530 | |
| 531 | * Set the variable interactively with ``ccmake`` or ``cmake-gui``. |
Wyatt Hepler | dcfa92b | 2020-11-10 09:47:30 -0800 | [diff] [blame] | 532 | |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 533 | Use Pigweed from an existing CMake project |
| 534 | ------------------------------------------ |
| 535 | To use Pigweed libraries form a CMake-based project, simply include the Pigweed |
| 536 | repository from a ``CMakeLists.txt``. |
| 537 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 538 | .. code-block:: cmake |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 539 | |
| 540 | add_subdirectory(path/to/pigweed pigweed) |
| 541 | |
| 542 | All module libraries will be available as ``module_name`` or |
| 543 | ``module_name.sublibrary``. |
| 544 | |
| 545 | If desired, modules can be included individually. |
| 546 | |
Wyatt Hepler | e0575f7 | 2020-10-16 10:47:03 -0700 | [diff] [blame] | 547 | .. code-block:: cmake |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 548 | |
Wyatt Hepler | 0fbcdfc | 2020-01-02 07:53:39 -0800 | [diff] [blame] | 549 | add_subdirectory(path/to/pigweed/pw_some_module pw_some_module) |
| 550 | add_subdirectory(path/to/pigweed/pw_another_module pw_another_module) |
| 551 | |
Rob Mohr | 84f234e | 2019-12-06 09:16:50 -0800 | [diff] [blame] | 552 | Bazel |
| 553 | ===== |
Nathaniel Brough | 82cf687 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 554 | Bazel is currently very experimental, and only builds for host and ARM Cortex-M |
| 555 | microcontrollers. |
Armando Montanez | bcc194b | 2020-03-10 10:23:18 -0700 | [diff] [blame] | 556 | |
Rob Mohr | 84f234e | 2019-12-06 09:16:50 -0800 | [diff] [blame] | 557 | The common configuration for Bazel for all modules is in the ``pigweed.bzl`` |
| 558 | file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test`` |
| 559 | are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``. |
| 560 | These wrappers add parameters to calls to the compiler and linker. |
| 561 | |
Nathaniel Brough | 82cf687 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 562 | Currently Pigweed is making use of a set of |
| 563 | [open source](https://github.com/silvergasp/bazel-embedded) toolchains. The host |
| 564 | builds are only supported on Linux/Mac based systems. Additionally the host |
| 565 | builds are not entirely hermetic, and will make use of system |
| 566 | libraries and headers. This is close to the default configuration for Bazel, |
| 567 | though slightly more hermetic. The host toolchain is based around clang-11 which |
| 568 | has a system dependency on 'libtinfo.so.5' which is often included as part of |
| 569 | the libncurses packages. On Debian based systems this can be installed using the |
| 570 | command below: |
| 571 | |
| 572 | .. code-block:: sh |
| 573 | |
| 574 | sudo apt install libncurses5 |
| 575 | |
| 576 | The host toolchain does not currently support native Windows, though using WSL |
| 577 | is a viable alternative. |
| 578 | |
| 579 | The ARM Cortex-M Bazel toolchains are based around gcc-arm-non-eabi and are |
| 580 | entirely hermetic. You can target Cortex-M, by using the platforms command line |
| 581 | option. This set of toolchains is supported from hosts; Windows, Mac and Linux. |
Nathaniel Brough | ce91098 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 582 | The platforms that are currently supported are listed below: |
Nathaniel Brough | 82cf687 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 583 | |
| 584 | .. code-block:: sh |
| 585 | |
Nathaniel Brough | ce91098 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 586 | bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m0 |
| 587 | bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m1 |
| 588 | bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m3 |
| 589 | bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m4 |
| 590 | bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m7 |
Nathaniel Brough | 82cf687 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 591 | bazel build //:your_target \ |
Nathaniel Brough | ce91098 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 592 | --platforms=@pigweed//pw_build/platforms:cortex_m4_fpu |
Nathaniel Brough | 82cf687 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 593 | bazel build //:your_target \ |
Nathaniel Brough | ce91098 | 2021-02-16 15:51:57 +0800 | [diff] [blame] | 594 | --platforms=@pigweed//pw_build/platforms:cortex_m7_fpu |
| 595 | |
| 596 | |
| 597 | The above examples are cpu/fpu oriented platforms and can be used where |
| 598 | applicable for your application. There some more specific platforms for the |
| 599 | types of boards that are included as examples in Pigweed. It is strongly |
| 600 | encouraged that you create your own set of platforms specific for your project, |
| 601 | that implement the constraint_settings in this repository. e.g. |
| 602 | |
| 603 | New board constraint_value: |
| 604 | |
| 605 | .. code-block:: python |
| 606 | |
| 607 | #your_repo/build_settings/constraints/board/BUILD |
| 608 | constraint_value( |
| 609 | name = "nucleo_l432kc", |
| 610 | constraint_setting = "@pigweed//pw_build/constraints/board", |
| 611 | ) |
| 612 | |
| 613 | New chipset constraint_value: |
| 614 | |
| 615 | .. code-block:: python |
| 616 | |
| 617 | # your_repo/build_settings/constraints/chipset/BUILD |
| 618 | constraint_value( |
| 619 | name = "stm32l432kc", |
| 620 | constraint_setting = "@pigweed//pw_build/constraints/chipset", |
| 621 | ) |
| 622 | |
| 623 | New platforms for chipset and board: |
| 624 | |
| 625 | .. code-block:: python |
| 626 | |
| 627 | #your_repo/build_settings/platforms/BUILD |
| 628 | # Works with all stm32l432kc |
| 629 | platforms( |
| 630 | name = "stm32l432kc", |
| 631 | parents = ["@pigweed//pw_build/platforms:cortex_m4"], |
| 632 | constraint_values = |
| 633 | ["@your_repo//build_settings/constraints/chipset:stm32l432kc"], |
| 634 | ) |
| 635 | |
| 636 | # Works with only the nucleo_l432kc |
| 637 | platforms( |
| 638 | name = "nucleo_l432kc", |
| 639 | parents = [":stm32l432kc"], |
| 640 | constraint_values = |
| 641 | ["@your_repo//build_settings/constraints/board:nucleo_l432kc"], |
| 642 | ) |
| 643 | |
| 644 | In the above example you can build your code with the command line: |
| 645 | |
| 646 | .. code-block:: python |
| 647 | |
| 648 | bazel build //:your_target_for_nucleo_l432kc \ |
| 649 | --platforms=@your_repo//build_settings:nucleo_l432kc |
| 650 | |
| 651 | |
| 652 | You can also specify that a specific target is only compatible with one |
| 653 | platform: |
| 654 | |
| 655 | .. code-block:: python |
| 656 | |
| 657 | cc_library( |
| 658 | name = "compatible_with_all_stm32l432kc", |
| 659 | srcs = ["tomato_src.c"], |
| 660 | target_compatible_with = |
| 661 | ["@your_repo//build_settings/constraints/chipset:stm32l432kc"], |
| 662 | ) |
| 663 | |
| 664 | cc_library( |
| 665 | name = "compatible_with_only_nucleo_l432kc", |
| 666 | srcs = ["bbq_src.c"], |
| 667 | target_compatible_with = |
| 668 | ["@your_repo//build_settings/constraints/board:nucleo_l432kc"], |
| 669 | ) |
| 670 | |