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` 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 ``_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=``. * 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 `_. 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_`` 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_}" 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__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)