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