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