aboutsummaryrefslogtreecommitdiff
path: root/pw_build/cmake.rst
diff options
context:
space:
mode:
Diffstat (limited to 'pw_build/cmake.rst')
-rw-r--r--pw_build/cmake.rst184
1 files changed, 184 insertions, 0 deletions
diff --git a/pw_build/cmake.rst b/pw_build/cmake.rst
new file mode 100644
index 000000000..11f3b7514
--- /dev/null
+++ b/pw_build/cmake.rst
@@ -0,0 +1,184 @@
+CMake
+=====
+Pigweed's `CMake`_ support is provided primarily for projects that have an
+existing CMake build and wish to integrate Pigweed without switching to a new
+build system.
+
+The following command generates Ninja build files for a host build in the
+``out/cmake_host`` directory:
+
+.. code-block:: sh
+
+ cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake
+
+The ``PW_ROOT`` environment variable must point to the root of the Pigweed
+directory. This variable is set by Pigweed's environment setup.
+
+Tests can be executed with the ``pw_run_tests.GROUP`` targets. To run Pigweed
+module tests, execute ``pw_run_tests.modules``:
+
+.. code-block:: sh
+
+ ninja -C out/cmake_host pw_run_tests.modules
+
+:ref:`module-pw_watch` supports CMake, so you can also run
+
+.. code-block:: sh
+
+ pw watch -C out/cmake_host pw_run_tests.modules
+
+CMake functions
+---------------
+CMake convenience functions are defined in ``pw_build/pigweed.cmake``.
+
+* ``pw_add_library_generic`` -- The base helper used to instantiate CMake
+ libraries. This is meant for use in downstream projects as upstream Pigweed
+ modules are expected to use ``pw_add_library``.
+* ``pw_add_library`` -- Add an upstream Pigweed library.
+* ``pw_add_facade_generic`` -- The base helper used to instantiate facade
+ libraries. This is meant for use in downstream projects as upstream Pigweed
+ modules are expected to use ``pw_add_facade``.
+* ``pw_add_facade`` -- Declare an upstream Pigweed facade.
+* ``pw_set_backend`` -- Set the backend library to use for a facade.
+* ``pw_add_test_generic`` -- The base helper used to instantiate test targets.
+ This is meant for use in downstrema projects as upstream Pigweed modules are
+ expected to use ``pw_add_test``.
+* ``pw_add_test`` -- Declare an upstream Pigweed test target.
+* ``pw_add_test_group`` -- Declare a target to group and bundle test targets.
+* ``pw_target_link_targets`` -- Helper wrapper around ``target_link_libraries``
+ which only supports CMake targets and detects when the target does not exist.
+ Note that generator expressions are not supported.
+* ``pw_add_global_compile_options`` -- Applies compilation options to all
+ targets in the build. This should only be used to add essential compilation
+ options, such as those that affect the ABI. Use ``pw_add_library`` or
+ ``target_compile_options`` to apply other compile options.
+* ``pw_add_error_target`` -- Declares target which reports a message and causes
+ a build failure only when compiled. This is useful when ``FATAL_ERROR``
+ messages cannot be used to catch problems during the CMake configuration
+ phase.
+* ``pw_parse_arguments`` -- Helper to parse CMake function arguments.
+
+See ``pw_build/pigweed.cmake`` for the complete documentation of these
+functions.
+
+Special libraries that do not fit well with these functions are created with the
+standard CMake functions, such as ``add_library`` and ``target_link_libraries``.
+
+Facades and backends
+--------------------
+The CMake build uses CMake cache variables for configuring
+:ref:`facades<docs-module-structure-facades>` and backends. Cache variables are
+similar to GN's build args set with ``gn args``. Unlike GN, CMake does not
+support multi-toolchain builds, so these variables have a single global value
+per build directory.
+
+The ``pw_add_module_facade`` function declares a cache variable named
+``<module_name>_BACKEND`` for each facade. Cache variables can be awkward to
+work with, since their values only change when they're assigned, but then
+persist accross CMake invocations. These variables should be set in one of the
+following ways:
+
+* Prior to setting a backend, your application should include
+ ``$ENV{PW_ROOT}/backends.cmake``. This file will setup all the backend targets
+ such that any misspelling of a facade or backend will yield a warning.
+
+ .. note::
+ Zephyr developers do not need to do this, backends can be set automatically
+ by enabling the appropriate Kconfig options.
+
+* Call ``pw_set_backend`` to set backends appropriate for the target in the
+ target's toolchain file. The toolchain file is provided to ``cmake`` with
+ ``-DCMAKE_TOOLCHAIN_FILE=<toolchain file>``.
+* Call ``pw_set_backend`` in the top-level ``CMakeLists.txt`` before other
+ CMake code executes.
+* Set the backend variable at the command line with the ``-D`` option.
+
+ .. code-block:: sh
+
+ cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
+ -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
+ -Dpw_log_BACKEND=pw_log_basic
+
+* Temporarily override a backend by setting it interactively with ``ccmake`` or
+ ``cmake-gui``.
+
+If the backend is set to a build target that does not exist, there will be an
+error message like the following:
+
+.. code-block::
+
+ CMake Error at pw_build/pigweed.cmake:257 (message):
+ my_module.my_facade's INTERFACE dep "my_nonexistent_backend" is not
+ a target.
+ Call Stack (most recent call first):
+ pw_build/pigweed.cmake:238:EVAL:1 (_pw_target_link_targets_deferred_check)
+ CMakeLists.txt:DEFERRED
+
+
+Toolchain setup
+---------------
+In CMake, the toolchain is configured by setting CMake variables, as described
+in the `CMake documentation <https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html>`_.
+These variables are typically set in a toolchain CMake file passed to ``cmake``
+with the ``-D`` option (``-DCMAKE_TOOLCHAIN_FILE=path/to/file.cmake``).
+For Pigweed embedded builds, set ``CMAKE_SYSTEM_NAME`` to the empty string
+(``""``).
+
+Toolchains may set the ``pw_build_WARNINGS`` variable to a list of ``INTERFACE``
+libraries with compilation options for Pigweed's upstream libraries. This
+defaults to a strict set of warnings. Projects may need to use less strict
+compilation warnings to compile backends exposed to Pigweed code (such as
+``pw_log``) that cannot compile with Pigweed's flags. If desired, Projects can
+access these warnings by depending on ``pw_build.warnings``.
+
+Third party libraries
+---------------------
+The CMake build includes third-party libraries similarly to the GN build. A
+``dir_pw_third_party_<library>`` cache variable is defined for each third-party
+dependency. The variable must be set to the absolute path of the library in
+order to use it. If the variable is empty
+(``if("${dir_pw_third_party_<library>}" STREQUAL "")``), the dependency is not
+available.
+
+Third-party dependencies are not automatically added to the build. They can be
+manually added with ``add_subdirectory`` or by setting the
+``pw_third_party_<library>_ADD_SUBDIRECTORY`` option to ``ON``.
+
+Third party variables are set like any other cache global variable in CMake. It
+is recommended to set these in one of the following ways:
+
+* Set with the CMake ``set`` function in the toolchain file or a
+ ``CMakeLists.txt`` before other CMake code executes.
+
+ .. code-block:: cmake
+
+ set(dir_pw_third_party_nanopb ${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb CACHE PATH "" FORCE)
+
+* Set the variable at the command line with the ``-D`` option.
+
+ .. code-block:: sh
+
+ cmake -B out/cmake_host -S "$PW_ROOT" -G Ninja \
+ -DCMAKE_TOOLCHAIN_FILE=$PW_ROOT/pw_toolchain/host_clang/toolchain.cmake \
+ -Ddir_pw_third_party_nanopb=/path/to/nanopb
+
+* Set the variable interactively with ``ccmake`` or ``cmake-gui``.
+
+Use Pigweed from an existing CMake project
+------------------------------------------
+To use Pigweed libraries form a CMake-based project, simply include the Pigweed
+repository from a ``CMakeLists.txt``.
+
+.. code-block:: cmake
+
+ add_subdirectory(path/to/pigweed pigweed)
+
+All module libraries will be available as ``module_name`` or
+``module_name.sublibrary``.
+
+If desired, modules can be included individually.
+
+.. code-block:: cmake
+
+ add_subdirectory(path/to/pigweed/pw_some_module pw_some_module)
+ add_subdirectory(path/to/pigweed/pw_another_module pw_another_module)