blob: 7bf075bb92ee9f7a41645f299107a7770a0806f9 [file] [log] [blame]
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -07001.. _module-pw_build:
Alexei Frolov9d169d52020-03-03 17:20:06 -08002
Rob Mohr84f234e2019-12-06 09:16:50 -08003--------
4pw_build
5--------
Alexei Frolov9d169d52020-03-03 17:20:06 -08006Pigweed's modules aim to be easily integratable into both new and existing
7embedded projects. To that goal, the ``pw_build`` module provides support for
8multiple build systems. Our personal favorite is `GN`_/`Ninja`_, which is used
9by upstream developers for its speed and flexibility. `CMake`_ and `Bazel`_
10build files are also provided by all modules, allowing Pigweed to be added to a
11project with minimal effort.
Rob Mohr84f234e2019-12-06 09:16:50 -080012
13.. _GN: https://gn.googlesource.com/gn/
14.. _Ninja: https://ninja-build.org/
Alexei Frolov9d169d52020-03-03 17:20:06 -080015.. _CMake: https://cmake.org/
Rob Mohr84f234e2019-12-06 09:16:50 -080016.. _Bazel: https://bazel.build/
17
Alexei Frolov9d169d52020-03-03 17:20:06 -080018Beyond just compiling code, Pigweed’s GN build system can also:
19
20* Generate HTML documentation, via our Sphinx integration (with ``pw_docgen``)
Armando Montanez0054a9b2020-03-13 13:06:24 -070021* Display memory usage report cards (with ``pw_bloat``)
Alexei Frolov9d169d52020-03-03 17:20:06 -080022* Incrementally run unit tests after code changes (with ``pw_target_runner``)
23* And more!
24
25These are only supported in the GN build, so we recommend using it if possible.
26
Rob Mohr84f234e2019-12-06 09:16:50 -080027GN / Ninja
28==========
Armando Montanezbcc194b2020-03-10 10:23:18 -070029The GN / Ninja build system is the primary build system used for upstream
30Pigweed development, and is the most tested and feature-rich build system
31Pigweed offers.
Rob Mohr84f234e2019-12-06 09:16:50 -080032
Armando Montanezbcc194b2020-03-10 10:23:18 -070033This module's ``build.gn`` file contains a number of C/C++ ``config``
34declarations that are used by upstream Pigweed to set some architecture-agnostic
35compiler defaults. (See Pigweed's ``//BUILDCONFIG.gn``)
36
Armando Montanez0054a9b2020-03-13 13:06:24 -070037``pw_build`` also provides several useful GN templates that are used throughout
Armando Montanezbcc194b2020-03-10 10:23:18 -070038Pigweed.
Alexei Frolov69ad1922019-12-13 13:11:32 -080039
Alexei Frolovedd2f142020-06-09 19:11:27 -070040Target types
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080041------------
Wyatt Heplere0575f72020-10-16 10:47:03 -070042.. code-block::
Alexei Frolov69ad1922019-12-13 13:11:32 -080043
Alexei Frolovedd2f142020-06-09 19:11:27 -070044 import("$dir_pw_build/target_types.gni")
Alexei Frolov69ad1922019-12-13 13:11:32 -080045
Alexei Frolovedd2f142020-06-09 19:11:27 -070046 pw_source_set("my_library") {
47 sources = [ "lib.cc" ]
48 }
49
50Pigweed defines wrappers around the four basic GN binary types ``source_set``,
51``executable``, ``static_library``, and ``shared_library``. These wrappers apply
52default arguments to each target as specified in the ``default_configs`` and
53``default_public_deps`` build args. Additionally, they allow defaults to be
54removed on a per-target basis using ``remove_configs`` and
55``remove_public_deps`` variables, respectively.
56
57The ``pw_executable`` template provides additional functionality around building
58complete binaries. As Pigweed is a collection of libraries, it does not know how
59its final targets are built. ``pw_executable`` solves this by letting each user
60of Pigweed specify a global executable template for their target, and have
61Pigweed build against it. This is controlled by the build variable
62``pw_executable_config.target_type``, specifying the name of the executable
63template for a project.
Alexei Frolov69ad1922019-12-13 13:11:32 -080064
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 Frolovedd2f142020-06-09 19:11:27 -070072All of the ``pw_*`` target type overrides accept any arguments, as they simply
73forward them through to the underlying target.
Alexei Frolov69ad1922019-12-13 13:11:32 -080074
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -070075.. _module-pw_build-link-deps:
76
77Link-only deps
78--------------
79It may be necessary to specify additional link-time dependencies that may not be
80explicitly 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
82circular dependencies. Its dependencies need to be linked for executables and
83libraries, even if they aren't pulled in elsewhere.
84
85The ``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.
87This should only be used as a last resort when dependencies cannot be properly
88expressed in the build.
89
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080090Python packages
91---------------
92GN templates for :ref:`Python build automation <docs-python-build>` are
93described in :ref:`module-pw_build-python`.
94
95.. toctree::
96 :hidden:
97
98 python
99
Wyatt Heplere0575f72020-10-16 10:47:03 -0700100.. _module-pw_build-facade:
101
102pw_facade
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800103---------
Wyatt Heplere0575f72020-10-16 10:47:03 -0700104In their simplest form, a :ref:`facade<docs-module-structure-facades>` is a GN
105build arg used to change a dependency at compile time. Pigweed targets configure
106these facades as needed.
107
108The ``pw_facade`` template bundles a ``pw_source_set`` with a facade build arg.
109This allows the facade to provide header files, compilation options or anything
110else a GN ``source_set`` provides.
111
112The ``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 Hepler61663222021-05-06 10:57:43 -0700128Low-level facades like ``pw_assert`` cannot express all of their dependencies
129due to the potential for dependency cycles. Facades with this issue may require
130backends to place their implementations in a separate build target to be listed
131in ``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
133targets are present in ``pw_build_LINK_DEPS`` if the facade's backend variable
134is set.
135
Wyatt Hepler0d32d1d2020-10-23 08:05:23 -0700136.. _module-pw_build-python-action:
Alexei Frolov199045a2020-08-28 13:02:30 -0700137
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700138pw_python_action
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800139----------------
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700140The ``pw_python_action`` template is a convenience wrapper around ``action`` for
Wyatt Hepler8224a642020-07-29 08:55:56 -0700141running Python scripts. The main benefit it provides is resolution of GN target
142labels to compiled binary files. This allows Python scripts to be written
143independently of GN, taking only filesystem paths as arguments.
Alexei Frolov69ad1922019-12-13 13:11:32 -0800144
145Another convenience provided by the template is to allow running scripts without
146any outputs. Sometimes scripts run in a build do not directly produce output
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700147files, but GN requires that all actions have an output. ``pw_python_action``
Alexei Frolov69ad1922019-12-13 13:11:32 -0800148solves this by accepting a boolean ``stamp`` argument which tells it to create a
Rob Mohr463700d2021-05-22 10:31:03 -0700149placeholder output file for the action.
Alexei Frolov69ad1922019-12-13 13:11:32 -0800150
151**Arguments**
152
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700153``pw_python_action`` accepts all of the arguments of a regular ``action``
Alexei Frolov69ad1922019-12-13 13:11:32 -0800154target. Additionally, it has some of its own arguments:
155
Wyatt Hepler79d983f2020-10-12 08:46:34 -0700156* ``module``: Run the specified Python module instead of a script. Either
157 ``script`` or ``module`` must be specified, but not both.
Wyatt Heplera74f7b02020-07-23 14:10:56 -0700158* ``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
Rob Mohr463700d2021-05-22 10:31:03 -0700161 placeholder output file for the script. This allows running scripts without
Wyatt Heplera74f7b02020-07-23 14:10:56 -0700162 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 Hepler79d983f2020-10-12 08:46:34 -0700165* ``environment``: Optional list of strings. Environment variables to set,
166 passed as NAME=VALUE strings.
Alexei Frolov69ad1922019-12-13 13:11:32 -0800167
Wyatt Hepler8224a642020-07-29 08:55:56 -0700168**Expressions**
169
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700170``pw_python_action`` evaluates expressions in ``args``, the arguments passed to
Wyatt Hepler8224a642020-07-29 08:55:56 -0700171the script. These expressions function similarly to generator expressions in
172CMake. Expressions may be passed as a standalone argument or as part of another
173argument. A single argument may contain multiple expressions.
174
175Generally, these expressions are used within templates rather than directly in
176BUILD.gn files. This allows build code to use GN labels without having to worry
177about converting them to files.
178
Wyatt Heplera2ddc412021-03-16 13:47:29 -0700179.. note::
180
181 We intend to replace these expressions with native GN features when possible.
182 See `pwbug/347 <http://bugs.pigweed.dev/347>`_.
183
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700184The following expressions are supported:
Wyatt Hepler8224a642020-07-29 08:55:56 -0700185
186.. describe:: <TARGET_FILE(gn_target)>
187
188 Evaluates to the output file of the provided GN target. For example, the
189 expression
190
Wyatt Heplere0575f72020-10-16 10:47:03 -0700191 .. code-block::
Wyatt Hepler8224a642020-07-29 08:55:56 -0700192
193 "<TARGET_FILE(//foo/bar:static_lib)>"
194
195 might expand to
196
Wyatt Heplere0575f72020-10-16 10:47:03 -0700197 .. code-block::
Wyatt Hepler8224a642020-07-29 08:55:56 -0700198
199 "/home/User/project_root/out/obj/foo/bar/static_lib.a"
200
201 ``TARGET_FILE`` parses the ``.ninja`` file for the GN target, so it should
202 always find the correct output file, regardless of the toolchain's or target's
203 configuration. Some targets, such as ``source_set`` and ``group`` targets, do
204 not have an output file, and attempting to use ``TARGET_FILE`` with them
205 results in an error.
206
207 ``TARGET_FILE`` only resolves GN target labels to their outputs. To resolve
208 paths generally, use the standard GN approach of applying the
Michael Spangc8b93902021-05-30 15:53:56 -0400209 ``rebase_path(path, root_build_dir)`` function. This function
Wyatt Hepler8224a642020-07-29 08:55:56 -0700210 converts the provided GN path or list of paths to be relative to the build
211 directory, from which all build commands and scripts are executed.
212
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700213.. describe:: <TARGET_FILE_IF_EXISTS(gn_target)>
214
215 ``TARGET_FILE_IF_EXISTS`` evaluates to the output file of the provided GN
216 target, if the output file exists. If the output file does not exist, the
217 entire argument that includes this expression is omitted, even if there is
218 other text or another expression.
219
220 For example, consider this expression:
221
Wyatt Heplere0575f72020-10-16 10:47:03 -0700222 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700223
224 "--database=<TARGET_FILE_IF_EXISTS(//alpha/bravo)>"
225
226 If the ``//alpha/bravo`` target file exists, this might expand to the
227 following:
228
Wyatt Heplere0575f72020-10-16 10:47:03 -0700229 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700230
231 "--database=/home/User/project/out/obj/alpha/bravo/bravo.elf"
232
233 If the ``//alpha/bravo`` target file does not exist, the entire
234 ``--database=`` argument is omitted from the script arguments.
235
236.. describe:: <TARGET_OBJECTS(gn_target)>
237
238 Evaluates to the object files of the provided GN target. Expands to a separate
239 argument for each object file. If the target has no object files, the argument
240 is omitted entirely. Because it does not expand to a single expression, the
241 ``<TARGET_OBJECTS(...)>`` expression may not have leading or trailing text.
242
243 For example, the expression
244
Wyatt Heplere0575f72020-10-16 10:47:03 -0700245 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700246
247 "<TARGET_OBJECTS(//foo/bar:a_source_set)>"
248
249 might expand to multiple separate arguments:
250
Wyatt Heplere0575f72020-10-16 10:47:03 -0700251 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700252
253 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_a.cc.o"
254 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_b.cc.o"
255 "/home/User/project_root/out/obj/foo/bar/a_source_set.file_c.cc.o"
256
Alexei Frolov69ad1922019-12-13 13:11:32 -0800257**Example**
258
Wyatt Heplere0575f72020-10-16 10:47:03 -0700259.. code-block::
Alexei Frolov69ad1922019-12-13 13:11:32 -0800260
Wyatt Hepler51ded742020-10-19 14:45:27 -0700261 import("$dir_pw_build/python_action.gni")
Alexei Frolov69ad1922019-12-13 13:11:32 -0800262
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700263 pw_python_action("postprocess_main_image") {
Wyatt Hepler8224a642020-07-29 08:55:56 -0700264 script = "py/postprocess_binary.py"
265 args = [
266 "--database",
Michael Spangc8b93902021-05-30 15:53:56 -0400267 rebase_path("my/database.csv", root_build_dir),
Wyatt Hepler8224a642020-07-29 08:55:56 -0700268 "--binary=<TARGET_FILE(//firmware/images:main)>",
269 ]
Alexei Frolov69ad1922019-12-13 13:11:32 -0800270 stamp = true
271 }
272
273pw_input_group
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800274--------------
Alexei Frolov69ad1922019-12-13 13:11:32 -0800275``pw_input_group`` defines a group of input files which are not directly
276processed by the build but are still important dependencies of later build
277steps. This is commonly used alongside metadata to propagate file dependencies
278through the build graph and force rebuilds on file modifications.
279
280For example ``pw_docgen`` defines a ``pw_doc_group`` template which outputs
281metadata from a list of input files. The metadata file is not actually part of
282the build, and so changes to any of the input files do not trigger a rebuild.
283This is problematic, as targets that depend on the metadata should rebuild when
284the inputs are modified but GN cannot express this dependency.
285
286``pw_input_group`` solves this problem by allowing a list of files to be listed
287in a target that does not output any build artifacts, causing all dependent
288targets to correctly rebuild.
289
290**Arguments**
291
292``pw_input_group`` accepts all arguments that can be passed to a ``group``
293target, as well as requiring one extra:
294
295* ``inputs``: List of input files.
296
297**Example**
298
Wyatt Heplere0575f72020-10-16 10:47:03 -0700299.. code-block::
Alexei Frolov69ad1922019-12-13 13:11:32 -0800300
301 import("$dir_pw_build/input_group.gni")
302
303 pw_input_group("foo_metadata") {
304 metadata = {
305 files = [
306 "x.foo",
307 "y.foo",
308 "z.foo",
309 ]
310 }
311 inputs = metadata.files
312 }
313
314Targets depending on ``foo_metadata`` will rebuild when any of the ``.foo``
315files are modified.
Rob Mohr84f234e2019-12-06 09:16:50 -0800316
Sam McCauley0da412c2020-10-02 10:34:56 -0700317pw_zip
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800318------
Sam McCauley0da412c2020-10-02 10:34:56 -0700319``pw_zip`` is a target that allows users to zip up a set of input files and
320directories into a single output ``.zip`` file—a simple automation of a
321potentially repetitive task.
322
323**Arguments**
324
325* ``inputs``: List of source files as well as the desired relative zip
326 destination. See below for the input syntax.
327* ``dirs``: List of entire directories to be zipped as well as the desired
328 relative zip destination. See below for the input syntax.
329* ``output``: Filename of output ``.zip`` file.
330* ``deps``: List of dependencies for the target.
331
332**Input Syntax**
333
334Inputs all need to follow the correct syntax:
335
336#. Path to source file or directory. Directories must end with a ``/``.
337#. The delimiter (defaults to ``>``).
338#. The desired destination of the contents within the ``.zip``. Must start
339 with ``/`` to indicate the zip root. Any number of subdirectories are
340 allowed. If the source is a file it can be put into any subdirectory of the
341 root. If the source is a file, the zip copy can also be renamed by ending
342 the zip destination with a filename (no trailing ``/``).
343
344Thus, it should look like the following: ``"[source file or dir] > /"``.
345
346**Example**
347
348Let's say we have the following structure for a ``//source/`` directory:
349
Wyatt Heplere0575f72020-10-16 10:47:03 -0700350.. code-block::
Sam McCauley0da412c2020-10-02 10:34:56 -0700351
352 source/
353 ├── file1.txt
354 ├── file2.txt
355 ├── file3.txt
356 └── some_dir/
357 ├── file4.txt
358 └── some_other_dir/
359 └── file5.txt
360
361And we create the following build target:
362
Wyatt Heplere0575f72020-10-16 10:47:03 -0700363.. code-block::
Sam McCauley0da412c2020-10-02 10:34:56 -0700364
365 import("$dir_pw_build/zip.gni")
366
367 pw_zip("target_name") {
368 inputs = [
369 "//source/file1.txt > /", # Copied to the zip root dir.
370 "//source/file2.txt > /renamed.txt", # File renamed.
371 "//source/file3.txt > /bar/", # File moved to the /bar/ dir.
372 ]
373
374 dirs = [
375 "//source/some_dir/ > /bar/some_dir/", # All /some_dir/ contents copied
376 # as /bar/some_dir/.
377 ]
378
379 # Note on output: if the specific output directory isn't defined
380 # (such as output = "zoo.zip") then the .zip will output to the
381 # same directory as the BUILD.gn file that called the target.
382 output = "//$target_out_dir/foo.zip" # Where the foo.zip will end up
383 }
384
385This will result in a ``.zip`` file called ``foo.zip`` stored in
386``//$target_out_dir`` with the following structure:
387
Wyatt Heplere0575f72020-10-16 10:47:03 -0700388.. code-block::
Sam McCauley0da412c2020-10-02 10:34:56 -0700389
390 foo.zip
391 ├── bar/
392 │   ├── file3.txt
393 │   └── some_dir/
394 │   ├── file4.txt
395 │   └── some_other_dir/
396 │   └── file5.txt
397 ├── file1.txt
398 └── renamed.txt
399
Wyatt Heplerb59d2c92021-05-11 11:20:43 -0700400CMake
401=====
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700402Pigweed's `CMake`_ support is provided primarily for projects that have an
403existing CMake build and wish to integrate Pigweed without switching to a new
404build system.
Armando Montanezbcc194b2020-03-10 10:23:18 -0700405
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700406The following command generates Ninja build files for a host build in the
407``out/cmake_host`` directory:
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800408
Wyatt Heplere0575f72020-10-16 10:47:03 -0700409.. code-block:: sh
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800410
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800411 cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake
412
413The ``PW_ROOT`` environment variable must point to the root of the Pigweed
414directory. This variable is set by Pigweed's environment setup.
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800415
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700416Tests can be executed with the ``pw_run_tests.GROUP`` targets. To run Pigweed
417module tests, execute ``pw_run_tests.modules``:
418
419.. code-block:: sh
420
421 ninja -C out/cmake_host pw_run_tests.modules
422
423:ref:`module-pw_watch` supports CMake, so you can also run
424
425.. code-block:: sh
426
Wyatt Hepler00efe182020-11-23 08:25:14 -0800427 pw watch -C out/cmake_host pw_run_tests.modules
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800428
429CMake functions
430---------------
431CMake convenience functions are defined in ``pw_build/pigweed.cmake``.
432
433* ``pw_auto_add_simple_module`` -- For modules with only one library,
434 automatically declare the library and its tests.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700435* ``pw_auto_add_module_tests`` -- Create test targets for all tests in a module.
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800436* ``pw_add_facade`` -- Declare a module facade.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700437* ``pw_set_backend`` -- Set the backend library to use for a facade.
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800438* ``pw_add_module_library`` -- Add a library that is part of a module.
439* ``pw_add_test`` -- Declare a test target.
440
441See ``pw_build/pigweed.cmake`` for the complete documentation of these
442functions.
443
444Special libraries that do not fit well with these functions are created with the
445standard CMake functions, such as ``add_library`` and ``target_link_libraries``.
446
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700447Facades and backends
448--------------------
449The CMake build uses CMake cache variables for configuring
450:ref:`facades<docs-module-structure-facades>` and backends. Cache variables are
451similar to GN's build args set with ``gn args``. Unlike GN, CMake does not
452support multi-toolchain builds, so these variables have a single global value
453per build directory.
454
455The ``pw_add_facade`` function declares a cache variable named
456``<module_name>_BACKEND`` for each facade. Cache variables can be awkward to
457work with, since their values only change when they're assigned, but then
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800458persist accross CMake invocations. These variables should be set in one of the
459following ways:
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700460
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800461* Call ``pw_set_backend`` to set backends appropriate for the target in the
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700462 target's toolchain file. The toolchain file is provided to ``cmake`` with
463 ``-DCMAKE_TOOLCHAIN_FILE=<toolchain file>``.
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800464* Call ``pw_set_backend`` in the top-level ``CMakeLists.txt`` before other
465 CMake code executes.
466* Set the backend variable at the command line with the ``-D`` option.
467
468 .. code-block:: sh
469
470 cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
471 -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
472 -Dpw_log_BACKEND=pw_log_basic
473
474* Temporarily override a backend by setting it interactively with ``ccmake`` or
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700475 ``cmake-gui``.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700476
Wyatt Hepler8026d8d2021-05-11 11:37:29 -0700477If the backend is set to a build target that does not exist, there will be an
478error message like the following:
479
480.. code-block::
481
482 CMake Error at pw_build/pigweed.cmake:244 (add_custom_target):
483 Error evaluating generator expression:
484
485 $<TARGET_PROPERTY:my_backend_that_does_not_exist,TYPE>
486
487 Target "my_backend_that_does_not_exist" not found.
488
Wyatt Hepler73439f72020-11-03 14:28:11 -0800489Toolchain setup
490---------------
491In CMake, the toolchain is configured by setting CMake variables, as described
492in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_.
493These variables are typically set in a toolchain CMake file passed to ``cmake``
494with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``).
495For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string
496(``""``).
497
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700498Third party libraries
499---------------------
500The CMake build includes third-party libraries similarly to the GN build. A
501``dir_pw_third_party_<library>`` cache variable is defined for each third-party
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700502dependency. The variable must be set to the absolute path of the library in
503order to use it. If the variable is empty
504(``if("${dir_pw_third_party_<library>}" STREQUAL "")``), the dependency is not
505available.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700506
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700507Third-party dependencies are not automatically added to the build. They can be
508manually added with ``add_subdirectory`` or by setting the
509``pw_third_party_<library>_ADD_SUBDIRECTORY`` option to ``ON``.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700510
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800511Third party variables are set like any other cache global variable in CMake. It
512is recommended to set these in one of the following ways:
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800513
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800514* Set with the CMake ``set`` function in the toolchain file or a
515 ``CMakeLists.txt`` before other CMake code executes.
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800516
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800517 .. code-block:: cmake
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800518
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700519 set(dir_pw_third_party_nanopb ${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb CACHE PATH "" FORCE)
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800520
521* Set the variable at the command line with the ``-D`` option.
522
523 .. code-block:: sh
524
525 cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
526 -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
527 -Ddir_pw_third_party_nanopb=/path/to/nanopb
528
529* Set the variable interactively with ``ccmake`` or ``cmake-gui``.
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800530
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800531Use Pigweed from an existing CMake project
532------------------------------------------
533To use Pigweed libraries form a CMake-based project, simply include the Pigweed
534repository from a ``CMakeLists.txt``.
535
Wyatt Heplere0575f72020-10-16 10:47:03 -0700536.. code-block:: cmake
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800537
538 add_subdirectory(path/to/pigweed pigweed)
539
540All module libraries will be available as ``module_name`` or
541``module_name.sublibrary``.
542
543If desired, modules can be included individually.
544
Wyatt Heplere0575f72020-10-16 10:47:03 -0700545.. code-block:: cmake
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800546
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800547 add_subdirectory(path/to/pigweed/pw_some_module pw_some_module)
548 add_subdirectory(path/to/pigweed/pw_another_module pw_another_module)
549
Rob Mohr84f234e2019-12-06 09:16:50 -0800550Bazel
551=====
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800552Bazel is currently very experimental, and only builds for host and ARM Cortex-M
553microcontrollers.
Armando Montanezbcc194b2020-03-10 10:23:18 -0700554
Rob Mohr84f234e2019-12-06 09:16:50 -0800555The common configuration for Bazel for all modules is in the ``pigweed.bzl``
556file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test``
557are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``.
558These wrappers add parameters to calls to the compiler and linker.
559
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800560Currently Pigweed is making use of a set of
561[open source](https://github.com/silvergasp/bazel-embedded) toolchains. The host
562builds are only supported on Linux/Mac based systems. Additionally the host
563builds are not entirely hermetic, and will make use of system
564libraries and headers. This is close to the default configuration for Bazel,
565though slightly more hermetic. The host toolchain is based around clang-11 which
566has a system dependency on 'libtinfo.so.5' which is often included as part of
567the libncurses packages. On Debian based systems this can be installed using the
568command below:
569
570.. code-block:: sh
571
572 sudo apt install libncurses5
573
574The host toolchain does not currently support native Windows, though using WSL
575is a viable alternative.
576
577The ARM Cortex-M Bazel toolchains are based around gcc-arm-non-eabi and are
578entirely hermetic. You can target Cortex-M, by using the platforms command line
579option. This set of toolchains is supported from hosts; Windows, Mac and Linux.
Nathaniel Broughce910982021-02-16 15:51:57 +0800580The platforms that are currently supported are listed below:
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800581
582.. code-block:: sh
583
Nathaniel Broughce910982021-02-16 15:51:57 +0800584 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m0
585 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m1
586 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m3
587 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m4
588 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m7
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800589 bazel build //:your_target \
Nathaniel Broughce910982021-02-16 15:51:57 +0800590 --platforms=@pigweed//pw_build/platforms:cortex_m4_fpu
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800591 bazel build //:your_target \
Nathaniel Broughce910982021-02-16 15:51:57 +0800592 --platforms=@pigweed//pw_build/platforms:cortex_m7_fpu
593
594
595The above examples are cpu/fpu oriented platforms and can be used where
596applicable for your application. There some more specific platforms for the
597types of boards that are included as examples in Pigweed. It is strongly
598encouraged that you create your own set of platforms specific for your project,
599that implement the constraint_settings in this repository. e.g.
600
601New board constraint_value:
602
603.. code-block:: python
604
605 #your_repo/build_settings/constraints/board/BUILD
606 constraint_value(
607 name = "nucleo_l432kc",
608 constraint_setting = "@pigweed//pw_build/constraints/board",
609 )
610
611New chipset constraint_value:
612
613.. code-block:: python
614
615 # your_repo/build_settings/constraints/chipset/BUILD
616 constraint_value(
617 name = "stm32l432kc",
618 constraint_setting = "@pigweed//pw_build/constraints/chipset",
619 )
620
621New platforms for chipset and board:
622
623.. code-block:: python
624
625 #your_repo/build_settings/platforms/BUILD
626 # Works with all stm32l432kc
627 platforms(
628 name = "stm32l432kc",
629 parents = ["@pigweed//pw_build/platforms:cortex_m4"],
630 constraint_values =
631 ["@your_repo//build_settings/constraints/chipset:stm32l432kc"],
632 )
633
634 # Works with only the nucleo_l432kc
635 platforms(
636 name = "nucleo_l432kc",
637 parents = [":stm32l432kc"],
638 constraint_values =
639 ["@your_repo//build_settings/constraints/board:nucleo_l432kc"],
640 )
641
642In the above example you can build your code with the command line:
643
644.. code-block:: python
645
646 bazel build //:your_target_for_nucleo_l432kc \
647 --platforms=@your_repo//build_settings:nucleo_l432kc
648
649
650You can also specify that a specific target is only compatible with one
651platform:
652
653.. code-block:: python
654
655 cc_library(
656 name = "compatible_with_all_stm32l432kc",
657 srcs = ["tomato_src.c"],
658 target_compatible_with =
659 ["@your_repo//build_settings/constraints/chipset:stm32l432kc"],
660 )
661
662 cc_library(
663 name = "compatible_with_only_nucleo_l432kc",
664 srcs = ["bbq_src.c"],
665 target_compatible_with =
666 ["@your_repo//build_settings/constraints/board:nucleo_l432kc"],
667 )
668