blob: c974828996c236b3cde1bdc1cee6089a40c655a0 [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 Hepler73439f72020-11-03 14:28:11 -0800479Toolchain setup
480---------------
481In CMake, the toolchain is configured by setting CMake variables, as described
482in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_.
483These variables are typically set in a toolchain CMake file passed to ``cmake``
484with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``).
485For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string
486(``""``).
487
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700488Third party libraries
489---------------------
490The CMake build includes third-party libraries similarly to the GN build. A
491``dir_pw_third_party_<library>`` cache variable is defined for each third-party
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700492dependency. The variable must be set to the absolute path of the library in
493order to use it. If the variable is empty
494(``if("${dir_pw_third_party_<library>}" STREQUAL "")``), the dependency is not
495available.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700496
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700497Third-party dependencies are not automatically added to the build. They can be
498manually added with ``add_subdirectory`` or by setting the
499``pw_third_party_<library>_ADD_SUBDIRECTORY`` option to ``ON``.
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700500
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800501Third party variables are set like any other cache global variable in CMake. It
502is recommended to set these in one of the following ways:
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800503
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800504* Set with the CMake ``set`` function in the toolchain file or a
505 ``CMakeLists.txt`` before other CMake code executes.
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800506
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800507 .. code-block:: cmake
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800508
Wyatt Hepler8f357f42021-03-17 15:37:09 -0700509 set(dir_pw_third_party_nanopb ${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb CACHE PATH "" FORCE)
Wyatt Heplerd9336a42020-11-10 09:47:30 -0800510
511* Set the variable at the command line with the ``-D`` option.
512
513 .. code-block:: sh
514
515 cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
516 -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
517 -Ddir_pw_third_party_nanopb=/path/to/nanopb
518
519* Set the variable interactively with ``ccmake`` or ``cmake-gui``.
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800520
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800521Use Pigweed from an existing CMake project
522------------------------------------------
523To use Pigweed libraries form a CMake-based project, simply include the Pigweed
524repository from a ``CMakeLists.txt``.
525
Wyatt Heplere0575f72020-10-16 10:47:03 -0700526.. code-block:: cmake
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800527
528 add_subdirectory(path/to/pigweed pigweed)
529
530All module libraries will be available as ``module_name`` or
531``module_name.sublibrary``.
532
533If desired, modules can be included individually.
534
Wyatt Heplere0575f72020-10-16 10:47:03 -0700535.. code-block:: cmake
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800536
Wyatt Hepler0fbcdfc2020-01-02 07:53:39 -0800537 add_subdirectory(path/to/pigweed/pw_some_module pw_some_module)
538 add_subdirectory(path/to/pigweed/pw_another_module pw_another_module)
539
Rob Mohr84f234e2019-12-06 09:16:50 -0800540Bazel
541=====
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800542Bazel is currently very experimental, and only builds for host and ARM Cortex-M
543microcontrollers.
Armando Montanezbcc194b2020-03-10 10:23:18 -0700544
Rob Mohr84f234e2019-12-06 09:16:50 -0800545The common configuration for Bazel for all modules is in the ``pigweed.bzl``
546file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test``
547are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``.
548These wrappers add parameters to calls to the compiler and linker.
549
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800550Currently Pigweed is making use of a set of
551[open source](https://github.com/silvergasp/bazel-embedded) toolchains. The host
552builds are only supported on Linux/Mac based systems. Additionally the host
553builds are not entirely hermetic, and will make use of system
554libraries and headers. This is close to the default configuration for Bazel,
555though slightly more hermetic. The host toolchain is based around clang-11 which
556has a system dependency on 'libtinfo.so.5' which is often included as part of
557the libncurses packages. On Debian based systems this can be installed using the
558command below:
559
560.. code-block:: sh
561
562 sudo apt install libncurses5
563
564The host toolchain does not currently support native Windows, though using WSL
565is a viable alternative.
566
567The ARM Cortex-M Bazel toolchains are based around gcc-arm-non-eabi and are
568entirely hermetic. You can target Cortex-M, by using the platforms command line
569option. This set of toolchains is supported from hosts; Windows, Mac and Linux.
Nathaniel Broughce910982021-02-16 15:51:57 +0800570The platforms that are currently supported are listed below:
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800571
572.. code-block:: sh
573
Nathaniel Broughce910982021-02-16 15:51:57 +0800574 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m0
575 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m1
576 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m3
577 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m4
578 bazel build //:your_target --platforms=@pigweed//pw_build/platforms:cortex_m7
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800579 bazel build //:your_target \
Nathaniel Broughce910982021-02-16 15:51:57 +0800580 --platforms=@pigweed//pw_build/platforms:cortex_m4_fpu
Nathaniel Brough82cf6872021-02-16 15:51:57 +0800581 bazel build //:your_target \
Nathaniel Broughce910982021-02-16 15:51:57 +0800582 --platforms=@pigweed//pw_build/platforms:cortex_m7_fpu
583
584
585The above examples are cpu/fpu oriented platforms and can be used where
586applicable for your application. There some more specific platforms for the
587types of boards that are included as examples in Pigweed. It is strongly
588encouraged that you create your own set of platforms specific for your project,
589that implement the constraint_settings in this repository. e.g.
590
591New board constraint_value:
592
593.. code-block:: python
594
595 #your_repo/build_settings/constraints/board/BUILD
596 constraint_value(
597 name = "nucleo_l432kc",
598 constraint_setting = "@pigweed//pw_build/constraints/board",
599 )
600
601New chipset constraint_value:
602
603.. code-block:: python
604
605 # your_repo/build_settings/constraints/chipset/BUILD
606 constraint_value(
607 name = "stm32l432kc",
608 constraint_setting = "@pigweed//pw_build/constraints/chipset",
609 )
610
611New platforms for chipset and board:
612
613.. code-block:: python
614
615 #your_repo/build_settings/platforms/BUILD
616 # Works with all stm32l432kc
617 platforms(
618 name = "stm32l432kc",
619 parents = ["@pigweed//pw_build/platforms:cortex_m4"],
620 constraint_values =
621 ["@your_repo//build_settings/constraints/chipset:stm32l432kc"],
622 )
623
624 # Works with only the nucleo_l432kc
625 platforms(
626 name = "nucleo_l432kc",
627 parents = [":stm32l432kc"],
628 constraint_values =
629 ["@your_repo//build_settings/constraints/board:nucleo_l432kc"],
630 )
631
632In the above example you can build your code with the command line:
633
634.. code-block:: python
635
636 bazel build //:your_target_for_nucleo_l432kc \
637 --platforms=@your_repo//build_settings:nucleo_l432kc
638
639
640You can also specify that a specific target is only compatible with one
641platform:
642
643.. code-block:: python
644
645 cc_library(
646 name = "compatible_with_all_stm32l432kc",
647 srcs = ["tomato_src.c"],
648 target_compatible_with =
649 ["@your_repo//build_settings/constraints/chipset:stm32l432kc"],
650 )
651
652 cc_library(
653 name = "compatible_with_only_nucleo_l432kc",
654 srcs = ["bbq_src.c"],
655 target_compatible_with =
656 ["@your_repo//build_settings/constraints/board:nucleo_l432kc"],
657 )
658