blob: c2fe2f5b33a00af988d8609103cab1097e840737 [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
149dummy output file for the action.
150
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
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 Hepler79d983f2020-10-12 08:46:34 -0700165* ``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 Frolov69ad1922019-12-13 13:11:32 -0800169
Wyatt Hepler8224a642020-07-29 08:55:56 -0700170**Expressions**
171
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700172``pw_python_action`` evaluates expressions in ``args``, the arguments passed to
Wyatt Hepler8224a642020-07-29 08:55:56 -0700173the script. These expressions function similarly to generator expressions in
174CMake. Expressions may be passed as a standalone argument or as part of another
175argument. A single argument may contain multiple expressions.
176
177Generally, these expressions are used within templates rather than directly in
178BUILD.gn files. This allows build code to use GN labels without having to worry
179about converting them to files.
180
Wyatt Heplera2ddc412021-03-16 13:47:29 -0700181.. 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 Hepler53a06fb2020-07-31 13:04:56 -0700186The following expressions are supported:
Wyatt Hepler8224a642020-07-29 08:55:56 -0700187
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 Heplere0575f72020-10-16 10:47:03 -0700193 .. code-block::
Wyatt Hepler8224a642020-07-29 08:55:56 -0700194
195 "<TARGET_FILE(//foo/bar:static_lib)>"
196
197 might expand to
198
Wyatt Heplere0575f72020-10-16 10:47:03 -0700199 .. code-block::
Wyatt Hepler8224a642020-07-29 08:55:56 -0700200
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 Hepler53a06fb2020-07-31 13:04:56 -0700215.. 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 Heplere0575f72020-10-16 10:47:03 -0700224 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700225
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 Heplere0575f72020-10-16 10:47:03 -0700231 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700232
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 Heplere0575f72020-10-16 10:47:03 -0700247 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700248
249 "<TARGET_OBJECTS(//foo/bar:a_source_set)>"
250
251 might expand to multiple separate arguments:
252
Wyatt Heplere0575f72020-10-16 10:47:03 -0700253 .. code-block::
Wyatt Hepler53a06fb2020-07-31 13:04:56 -0700254
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 Frolov69ad1922019-12-13 13:11:32 -0800259**Example**
260
Wyatt Heplere0575f72020-10-16 10:47:03 -0700261.. code-block::
Alexei Frolov69ad1922019-12-13 13:11:32 -0800262
Wyatt Hepler51ded742020-10-19 14:45:27 -0700263 import("$dir_pw_build/python_action.gni")
Alexei Frolov69ad1922019-12-13 13:11:32 -0800264
Wyatt Heplerc8e05a42020-10-19 14:49:39 -0700265 pw_python_action("postprocess_main_image") {
Wyatt Hepler8224a642020-07-29 08:55:56 -0700266 script = "py/postprocess_binary.py"
267 args = [
268 "--database",
269 rebase_path("my/database.csv"),
270 "--binary=<TARGET_FILE(//firmware/images:main)>",
271 ]
Alexei Frolov69ad1922019-12-13 13:11:32 -0800272 stamp = true
273 }
274
275pw_input_group
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800276--------------
Alexei Frolov69ad1922019-12-13 13:11:32 -0800277``pw_input_group`` defines a group of input files which are not directly
278processed by the build but are still important dependencies of later build
279steps. This is commonly used alongside metadata to propagate file dependencies
280through the build graph and force rebuilds on file modifications.
281
282For example ``pw_docgen`` defines a ``pw_doc_group`` template which outputs
283metadata from a list of input files. The metadata file is not actually part of
284the build, and so changes to any of the input files do not trigger a rebuild.
285This is problematic, as targets that depend on the metadata should rebuild when
286the 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
289in a target that does not output any build artifacts, causing all dependent
290targets to correctly rebuild.
291
292**Arguments**
293
294``pw_input_group`` accepts all arguments that can be passed to a ``group``
295target, as well as requiring one extra:
296
297* ``inputs``: List of input files.
298
299**Example**
300
Wyatt Heplere0575f72020-10-16 10:47:03 -0700301.. code-block::
Alexei Frolov69ad1922019-12-13 13:11:32 -0800302
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
316Targets depending on ``foo_metadata`` will rebuild when any of the ``.foo``
317files are modified.
Rob Mohr84f234e2019-12-06 09:16:50 -0800318
Sam McCauley0da412c2020-10-02 10:34:56 -0700319pw_zip
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800320------
Sam McCauley0da412c2020-10-02 10:34:56 -0700321``pw_zip`` is a target that allows users to zip up a set of input files and
322directories into a single output ``.zip`` file—a simple automation of a
323potentially 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
336Inputs 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
346Thus, it should look like the following: ``"[source file or dir] > /"``.
347
348**Example**
349
350Let's say we have the following structure for a ``//source/`` directory:
351
Wyatt Heplere0575f72020-10-16 10:47:03 -0700352.. code-block::
Sam McCauley0da412c2020-10-02 10:34:56 -0700353
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
363And we create the following build target:
364
Wyatt Heplere0575f72020-10-16 10:47:03 -0700365.. code-block::
Sam McCauley0da412c2020-10-02 10:34:56 -0700366
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
387This will result in a ``.zip`` file called ``foo.zip`` stored in
388``//$target_out_dir`` with the following structure:
389
Wyatt Heplere0575f72020-10-16 10:47:03 -0700390.. code-block::
Sam McCauley0da412c2020-10-02 10:34:56 -0700391
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 Heplerb59d2c92021-05-11 11:20:43 -0700402CMake
403=====
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700404Pigweed's `CMake`_ support is provided primarily for projects that have an
405existing CMake build and wish to integrate Pigweed without switching to a new
406build system.
Armando Montanezbcc194b2020-03-10 10:23:18 -0700407
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700408The following command generates Ninja build files for a host build in the
409``out/cmake_host`` directory:
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800410
Wyatt Heplere0575f72020-10-16 10:47:03 -0700411.. code-block:: sh
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800412
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800413 cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake
414
415The ``PW_ROOT`` environment variable must point to the root of the Pigweed
416directory. This variable is set by Pigweed's environment setup.
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800417
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700418Tests can be executed with the ``pw_run_tests.GROUP`` targets. To run Pigweed
419module 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 Hepler00efe182020-11-23 08:25:14 -0800429 pw watch -C out/cmake_host pw_run_tests.modules
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800430
431CMake functions
432---------------
433CMake 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 Heplerc9e51d22020-10-29 09:12:37 -0700437* ``pw_auto_add_module_tests`` -- Create test targets for all tests in a module.
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800438* ``pw_add_facade`` -- Declare a module facade.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700439* ``pw_set_backend`` -- Set the backend library to use for a facade.
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800440* ``pw_add_module_library`` -- Add a library that is part of a module.
441* ``pw_add_test`` -- Declare a test target.
442
443See ``pw_build/pigweed.cmake`` for the complete documentation of these
444functions.
445
446Special libraries that do not fit well with these functions are created with the
447standard CMake functions, such as ``add_library`` and ``target_link_libraries``.
448
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700449Facades and backends
450--------------------
451The CMake build uses CMake cache variables for configuring
452:ref:`facades<docs-module-structure-facades>` and backends. Cache variables are
453similar to GN's build args set with ``gn args``. Unlike GN, CMake does not
454support multi-toolchain builds, so these variables have a single global value
455per build directory.
456
457The ``pw_add_facade`` function declares a cache variable named
458``<module_name>_BACKEND`` for each facade. Cache variables can be awkward to
459work with, since their values only change when they're assigned, but then
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800460persist accross CMake invocations. These variables should be set in one of the
461following ways:
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700462
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800463* Call ``pw_set_backend`` to set backends appropriate for the target in the
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700464 target's toolchain file. The toolchain file is provided to ``cmake`` with
465 ``-DCMAKE_TOOLCHAIN_FILE=<toolchain file>``.
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800466* 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 Heplerc9e51d22020-10-29 09:12:37 -0700477 ``cmake-gui``.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700478
Wyatt Hepler8026d8d2021-05-11 11:37:29 -0700479If the backend is set to a build target that does not exist, there will be an
480error 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 Hepler73439f72020-11-03 14:28:11 -0800491Toolchain setup
492---------------
493In CMake, the toolchain is configured by setting CMake variables, as described
494in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_.
495These variables are typically set in a toolchain CMake file passed to ``cmake``
496with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``).
497For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string
498(``""``).
499
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700500Third party libraries
501---------------------
502The 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 Hepler8f357f42021-03-17 15:37:09 -0700504dependency. The variable must be set to the absolute path of the library in
505order to use it. If the variable is empty
506(``if("${dir_pw_third_party_<library>}" STREQUAL "")``), the dependency is not
507available.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700508
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700509Third-party dependencies are not automatically added to the build. They can be
510manually added with ``add_subdirectory`` or by setting the
511``pw_third_party_<library>_ADD_SUBDIRECTORY`` option to ``ON``.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700512
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800513Third party variables are set like any other cache global variable in CMake. It
514is recommended to set these in one of the following ways:
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800515
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800516* Set with the CMake ``set`` function in the toolchain file or a
517 ``CMakeLists.txt`` before other CMake code executes.
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800518
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800519 .. code-block:: cmake
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800520
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700521 set(dir_pw_third_party_nanopb ${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb CACHE PATH "" FORCE)
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800522
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 Heplerdcfa92b2020-11-10 09:47:30 -0800532
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800533Use Pigweed from an existing CMake project
534------------------------------------------
535To use Pigweed libraries form a CMake-based project, simply include the Pigweed
536repository from a ``CMakeLists.txt``.
537
Wyatt Heplere0575f72020-10-16 10:47:03 -0700538.. code-block:: cmake
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800539
540 add_subdirectory(path/to/pigweed pigweed)
541
542All module libraries will be available as ``module_name`` or
543``module_name.sublibrary``.
544
545If desired, modules can be included individually.
546
Wyatt Heplere0575f72020-10-16 10:47:03 -0700547.. code-block:: cmake
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800548
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800549 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 Mohr84f234e2019-12-06 09:16:50 -0800552Bazel
553=====
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800554Bazel is currently very experimental, and only builds for host and ARM Cortex-M
555microcontrollers.
Armando Montanezbcc194b2020-03-10 10:23:18 -0700556
Rob Mohr84f234e2019-12-06 09:16:50 -0800557The common configuration for Bazel for all modules is in the ``pigweed.bzl``
558file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test``
559are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``.
560These wrappers add parameters to calls to the compiler and linker.
561
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800562Currently Pigweed is making use of a set of
563[open source](https://github.com/silvergasp/bazel-embedded) toolchains. The host
564builds are only supported on Linux/Mac based systems. Additionally the host
565builds are not entirely hermetic, and will make use of system
566libraries and headers. This is close to the default configuration for Bazel,
567though slightly more hermetic. The host toolchain is based around clang-11 which
568has a system dependency on 'libtinfo.so.5' which is often included as part of
569the libncurses packages. On Debian based systems this can be installed using the
570command below:
571
572.. code-block:: sh
573
574 sudo apt install libncurses5
575
576The host toolchain does not currently support native Windows, though using WSL
577is a viable alternative.
578
579The ARM Cortex-M Bazel toolchains are based around gcc-arm-non-eabi and are
580entirely hermetic. You can target Cortex-M, by using the platforms command line
581option. This set of toolchains is supported from hosts; Windows, Mac and Linux.
Nathaniel Broughce910982021-02-16 15:51:57 +0800582The platforms that are currently supported are listed below:
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800583
584.. code-block:: sh
585
Nathaniel Broughce910982021-02-16 15:51:57 +0800586 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 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_m4_fpu
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800593 bazel build //:your_target \
Nathaniel Broughce910982021-02-16 15:51:57 +0800594 --platforms=@pigweed//pw_build/platforms:cortex_m7_fpu
595
596
597The above examples are cpu/fpu oriented platforms and can be used where
598applicable for your application. There some more specific platforms for the
599types of boards that are included as examples in Pigweed. It is strongly
600encouraged that you create your own set of platforms specific for your project,
601that implement the constraint_settings in this repository. e.g.
602
603New 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
613New 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
623New 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
644In 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
652You can also specify that a specific target is only compatible with one
653platform:
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