xref: /aosp_15_r20/external/pigweed/pw_build/cmake.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_build-cmake:
2
3CMake
4=====
5.. pigweed-module-subpage::
6   :name: pw_build
7
8Pigweed's `CMake`_ support is provided primarily for projects that have an
9existing CMake build and wish to integrate Pigweed without switching to a new
10build system.
11
12.. tip::
13   To run upstream Pigweed's CMake build use the ``pw build`` command:
14
15   .. code-block:: console
16
17      pw build -r default_cmake
18
19   This will install any required packages, generate cmake build files and invkoke ninja.
20
21   .. code-block:: text
22
23      19:36:58 INF [1/1] Starting ==> Recipe: default_cmake Targets: pw_run_tests.modules pw_apps pw_run_tests.pw_bluetooth Logfile: /out/build_default_cmake.txt
24      19:36:58 INF [1/1] Run ==> pw --no-banner package install emboss
25      19:36:59 INF [1/1] Run ==> pw --no-banner package install nanopb
26      19:37:00 INF [1/1] Run ==> pw --no-banner package install boringssl
27      19:37:10 INF [1/1] Run ==> cmake --fresh --debug-output -DCMAKE_MESSAGE_LOG_LEVEL=WARNING -S . -B ./out/cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=./pw_toolchain/host_clang/toolchain.cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -Ddir_pw_third_party_nanopb=./environment/packages/nanopb -Dpw_third_party_nanopb_ADD_SUBDIRECTORY=ON -Ddir_pw_third_party_emboss=./environment/packages/emboss -Ddir_pw_third_party_boringssl=./environment/packages/boringssl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
28      19:37:10 INF [1/1] Run ==> ninja -C out/cmake pw_apps pw_run_tests.modules pw_run_tests.pw_bluetooth
29
30   :ref:`module-pw_watch` works with ``pw build`` as well. You can run the
31   following to automatically rebuild when files change.
32
33   .. code-block:: console
34
35      pw build -r default_cmake --watch
36
37CMake functions
38---------------
39CMake convenience functions are defined in ``pw_build/pigweed.cmake``.
40
41* ``pw_add_library_generic`` -- The base helper used to instantiate CMake
42  libraries. This is meant for use in downstream projects as upstream Pigweed
43  modules are expected to use ``pw_add_library``.
44* ``pw_add_library`` -- Add an upstream Pigweed library.
45* ``pw_add_facade_generic`` -- The base helper used to instantiate facade
46  libraries. This is meant for use in downstream projects as upstream Pigweed
47  modules are expected to use ``pw_add_facade``.
48* ``pw_add_facade`` -- Declare an upstream Pigweed facade.
49* ``pw_set_backend`` -- Set the backend library to use for a facade.
50* ``pw_add_test_generic`` -- The base helper used to instantiate test targets.
51  This is meant for use in downstrema projects as upstream Pigweed modules are
52  expected to use ``pw_add_test``.
53* ``pw_add_test`` -- Declare an upstream Pigweed test target.
54* ``pw_add_test_group`` -- Declare a target to group and bundle test targets.
55* ``pw_target_link_targets`` -- Helper wrapper around ``target_link_libraries``
56  which only supports CMake targets and detects when the target does not exist.
57  Note that generator expressions are not supported.
58* ``pw_add_global_compile_options`` -- Applies compilation options to all
59  targets in the build. This should only be used to add essential compilation
60  options, such as those that affect the ABI. Use ``pw_add_library`` or
61  ``target_compile_options`` to apply other compile options.
62* ``pw_add_error_target`` -- Declares target which reports a message and causes
63  a build failure only when compiled. This is useful when ``FATAL_ERROR``
64  messages cannot be used to catch problems during the CMake configuration
65  phase.
66* ``pw_parse_arguments`` -- Helper to parse CMake function arguments.
67* ``pw_rebase_paths`` -- Helper to update a set of file paths to be rooted on a
68  new directory.
69
70See ``pw_build/pigweed.cmake`` for the complete documentation of these
71functions.
72
73Special libraries that do not fit well with these functions are created with the
74standard CMake functions, such as ``add_library`` and ``target_link_libraries``.
75
76Facades and backends
77--------------------
78The CMake build uses CMake cache variables for configuring
79:ref:`facades<docs-module-structure-facades>` and backends. Cache variables are
80similar to GN's build args set with ``gn args``. Unlike GN, CMake does not
81support multi-toolchain builds, so these variables have a single global value
82per build directory.
83
84The ``pw_add_module_facade`` function declares a cache variable named
85``<module_name>_BACKEND`` for each facade. Cache variables can be awkward to
86work with, since their values only change when they're assigned, but then
87persist accross CMake invocations. These variables should be set in one of the
88following ways:
89
90* Prior to setting a backend, your application should include
91  ``$ENV{PW_ROOT}/backends.cmake``. This file will setup all the backend targets
92  such that any misspelling of a facade or backend will yield a warning.
93
94  .. note::
95    Zephyr developers do not need to do this, backends can be set automatically
96    by enabling the appropriate Kconfig options.
97
98* Call ``pw_set_backend`` to set backends appropriate for the target in the
99  target's toolchain file. The toolchain file is provided to ``cmake`` with
100  ``-DCMAKE_TOOLCHAIN_FILE=<toolchain file>``.
101* Call ``pw_set_backend`` in the top-level ``CMakeLists.txt`` before other
102  CMake code executes.
103* Set the backend variable at the command line with the ``-D`` option.
104
105  .. code-block:: sh
106
107     cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
108         -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
109         -Dpw_log_BACKEND=pw_log_basic
110
111* Temporarily override a backend by setting it interactively with ``ccmake`` or
112  ``cmake-gui``.
113
114If the backend is set to a build target that does not exist, there will be an
115error message like the following:
116
117.. code-block::
118
119   CMake Error at pw_build/pigweed.cmake:257 (message):
120     my_module.my_facade's INTERFACE dep "my_nonexistent_backend" is not
121     a target.
122   Call Stack (most recent call first):
123     pw_build/pigweed.cmake:238:EVAL:1 (_pw_target_link_targets_deferred_check)
124     CMakeLists.txt:DEFERRED
125
126
127Toolchain setup
128---------------
129In CMake, the toolchain is configured by setting CMake variables, as described
130in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_.
131These variables are typically set in a toolchain CMake file passed to ``cmake``
132with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``).
133For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string
134(``""``).
135
136Toolchains may set the ``pw_build_WARNINGS`` variable to a list of ``INTERFACE``
137libraries with compilation options for Pigweed's upstream libraries. This
138defaults to a strict set of warnings. Projects may need to use less strict
139compilation warnings to compile backends exposed to Pigweed code (such as
140``pw_log``) that cannot compile with Pigweed's flags. If desired, Projects can
141access these warnings by depending on ``pw_build.warnings``.
142
143Third party libraries
144---------------------
145The CMake build includes third-party libraries similarly to the GN build. A
146``dir_pw_third_party_<library>`` cache variable is defined for each third-party
147dependency. The variable must be set to the absolute path of the library in
148order to use it. If the variable is empty
149(``if("${dir_pw_third_party_<library>}" STREQUAL "")``), the dependency is not
150available.
151
152Third-party dependencies are not automatically added to the build. They can be
153manually added with ``add_subdirectory`` or by setting the
154``pw_third_party_<library>_ADD_SUBDIRECTORY`` option to ``ON``.
155
156Third party variables are set like any other cache global variable in CMake. It
157is recommended to set these in one of the following ways:
158
159* Set with the CMake ``set`` function in the toolchain file or a
160  ``CMakeLists.txt`` before other CMake code executes.
161
162  .. code-block:: cmake
163
164     set(dir_pw_third_party_nanopb ${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb CACHE PATH "" FORCE)
165
166* Set the variable at the command line with the ``-D`` option.
167
168  .. code-block:: sh
169
170     cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
171         -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
172         -Ddir_pw_third_party_nanopb=/path/to/nanopb
173
174* Set the variable interactively with ``ccmake`` or ``cmake-gui``.
175
176.. _module-pw_build-existing-cmake-project:
177
178Use Pigweed from an existing CMake project
179------------------------------------------
180To use Pigweed libraries form a CMake-based project, simply include the Pigweed
181repository from a ``CMakeLists.txt``.
182
183.. code-block:: cmake
184
185   add_subdirectory(path/to/pigweed pigweed)
186
187All module libraries will be available as ``module_name`` or
188``module_name.sublibrary``.
189
190If desired, modules can be included individually.
191
192.. code-block:: cmake
193
194   add_subdirectory(path/to/pigweed/pw_some_module pw_some_module)
195   add_subdirectory(path/to/pigweed/pw_another_module pw_another_module)
196
197.. seealso::
198   Additional Pigweed CMake function references:
199   - :bdg-ref-primary-line:`module-pw_fuzzer-guides-using_fuzztest-toolchain`
200   - :bdg-ref-primary-line:`module-pw_protobuf_compiler-cmake`
201   - :bdg-ref-primary-line:`module-pw_unit_test-cmake`
202