diff options
Diffstat (limited to 'pw_build/cmake.rst')
-rw-r--r-- | pw_build/cmake.rst | 184 |
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) |