Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

pants-backend-cmake

A Pants backend for CMake projects. CMake stays the source of truth: the backend runs cmake -G Ninja once, reads the generated build.ninja, and replays every edge (one translation unit, one archive, one link) as its own cached Pants process. Nothing in CMakeLists.txt is declared twice, and the unit of caching is the edge, not the project. CMake provides the build artefacts; tests, packaging and dependencies are Pants' business.

This release targets Pants 2.32.x. Install it with pants-backend-cmake==0.1.0rc0 in [GLOBAL].plugins in pants.toml, and enable pants_backend_cmake in [GLOBAL].backend_packages.

Status: alpha. Linux hosts, cross builds through a cmake_toolchain_file, Ninja generator, local execution only (the compilers are found on the machine).

examples/cc has a cmake_project with a static library and an executable, and a cc_binary and a cc_test that link the library.

Targets

  • cmake_project: the project. sources is what CMake reads: CMake files, configure-time inputs, and any source or header no dependency provides. Files matching configure_placeholders (sources and headers by default) reach configure as zero-byte placeholders, so editing one never reruns configure; everything else is given as is. dependencies are files, cc_sources and codegen targets producing either (such as cpp_generate); their files are mounted for the compile and link steps, and configure sees only those matching configure_placeholders. A path both sources and a dependency provide is an error (drop it with "!gen/registry.cpp"). cmake_args and build_dir (default build) are passed to CMake. coverage_cmake_args are added to cmake_args for the build coverage consumers link (see C/C++ tools).

    The project is a target generator: it generates a cmake_target <project>#<name> for every library and executable CMake defines. They are found by a configure that sees sources as above (files matching configure_placeholders as placeholders, the rest as they are) and, as placeholders, the paths its explicit dependencies provide that match configure_placeholders, so no generator runs. Only explicit dependencies count, less those a ! entry names, and only files, cc_sources and targets whose backend declares their outputs ahead of time (a DeclaredOutputsFieldSet member, such as cpp_generate) provide paths. It configures once for each platform the project targets (its platforms and those in overrides, the host when unset) that this host has a toolchain for. platforms and build_type on the project apply to the generated targets, and overrides={"app": {...}} adjusts one of them (but not its dependencies, project or cmake_name). Each depends on <project>#_inputs (a cmake_project_inputs), which owns the project's files and dependencies, so --changed-dependents reaches it. Goals that replace a generator with what it generates (lint ::) run the project's own tools, such as clang-tidy, on #_inputs, with its build_type.

    A setup mistake (a path both sources and a dependency provide, a dependency address that does not resolve, an unknown platform name, a build_dir outside the project) or a failed configure does not stop the rest of the repository: the project, or just that platform for a failed configure, generates no targets and the error is logged. A platform without a working toolchain is a warning, and one no cc_toolchain builds for is logged only at debug level. It is logged whenever Pants generates the project's targets: on every run without pantsd, and with pantsd again after the generation's inputs change (a BUILD file or CMake file edit) or pantsd restarts. pants package of a hand-written cmake_target naming the project raises the error, as does pants lint <project>#_inputs with clang-tidy enabled, for the host only.

  • cmake_target: one CMake STATIC, SHARED, MODULE library or EXECUTABLE, named by project (the cmake_project's address, inferred as a dependency unless the project generated it) and cmake_name (defaults to the target name); build_type sets its configure's CMAKE_BUILD_TYPE, and when unset the project's build_type applies (for a parametrized project, the one project names, as in :proj@build_type=Release). Generated ones are the usual way; a hand-written one works the same. pants package writes its outputs at their build paths, dist/<build_dir>/libfoo.a, and those for other platforms under dist/<platform>/ (see Platforms). Object libraries are internal and are not addressed.

C/C++ tools

A static or shared cmake_target is a pants-backend-cc library, so a cc_test or cc_binary depending on it compiles and links in the project's build directory as CMake would build a consumer of it (see How it works); nothing PRIVATE leaks. clang_tidy_paths on cmake_project selects what pants_backend_cc.lint.clang_tidy lints. A cpp_generate target (pants_backend_cc.generate) can be a dependency of a cmake_project or cc_test.

For pants test --use-coverage with pants_backend_cc.coverage, a cc_test links the project's coverage build: a configure of its own with coverage_cmake_args added, which should make the compiles write gcov notes and the links bring the gcov runtime (--coverage, or the project's own switch). Its replay keeps each compile's .gcno, and the test gets the notes and inputs of every compile behind the libraries on its link line. A project without coverage_cmake_args serves its usual build, and other consumers never see the coverage build.

Platforms

The compilers and ar come from the cc_toolchain (pants-backend-cc) for the host and the platform being built; without any, gcc, g++ and ar for the host. A cmake_target builds for its platforms, and for the host when a cc_test or cc_binary links it. Enable pants_backend_platforms and pants_backend_cc to declare platform and cc_toolchain targets.

The backend adds cmake_toolchain_file to cc_toolchain, passed as CMAKE_TOOLCHAIN_FILE: a cross build needs one for CMAKE_SYSTEM_NAME. See the field's help for what it may contain.

Subsystems

  • [cmake]: the pinned CMake download (version, known_versions).
  • [ninja]: the pinned Ninja download. Ninja is only needed by configure; the replay never runs it.

How it works

  1. Configure: cmake -S <project> -B <build_dir> -G Ninja in a sandbox, with the consumer probes injected through CMAKE_PROJECT_INCLUDE. The generated files are kept, except the cache, the compiler-id artefacts, the logs and the probe sources; every absolute sandbox path in them is rewritten to a placeholder, the paths of CMake's own binaries (read from CMakeCache.txt) to bare names, and the regenerate edge and its "missing input is not an error" twin are dropped, so the configured tree has the same digest in every sandbox.
  2. Discovery: the Ninja graph is parsed; CMake's # ... build statements for <TYPE> target <name> comments give each edge its target and kind; a target's outputs are what its link and symlink edges write; the edges one target needs are found by walking producers and stopping at other targets' outputs.
  3. Replay (pants package): one rule per edge, awaiting its producers, each a process with exactly its own inputs: the source, the headers it includes (from a per-TU -M scan), the configure-time generated files, and the outputs of the producers of its declared inputs. The engine schedules the dataflow and memoizes shared edges.
  4. Link interface (cc_test): configure injects a consumer probe per library and language, a hidden executable linking the library (util_rules/probes.py). A consumer compiles with the probe's compile line (PUBLIC and INTERFACE requirements, transitively, plus the project's flags) and links with its link line (the link closure and CMake's driver) against the replayed libraries, in the build directory.

Limitations

  • Order-only dependencies are not followed. Generated sources produced by add_custom_command and discovered only through them are an error at planning time: check them in and list them as sources, or generate them with a codegen dependency.
  • A scan that fails, or that finds an include the project does not provide, is an error. Compiler launchers (CMAKE_<LANG>_COMPILER_LAUNCHER, CMAKE_<LANG>_CLANG_TIDY) are stripped for the scan but kept for the compile, where they need their own environment.
  • Ninja dyndep (C++ modules), subninja and validation inputs are not handled.
  • Two dependencies providing one path with different contents fail with the engine's digest-merge error, which does not name the targets.
  • Debug and coverage builds embed the compile sandbox path (DW_AT_comp_dir, .gcda paths); -ffile-prefix-map is not injected. pants_backend_cc.coverage maps the .gcda paths itself.
  • Parametrized projects package to the same dist/<build_dir>/ path.
  • The cmake_targets one cc_test or cc_binary links must belong to one project. The probes are added in the top-level directory's scope, so directory-scoped settings of a subdirectory do not reach a consumer. The backend owns CMAKE_PROJECT_INCLUDE; a project that sets it itself loses it.
  • cmake_args are the same for every platform.
  • Pants on Windows is out of scope, and a macOS host is untested.

Metadata

Release files for pants-backend-cmake 0.1.0rc0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pants-backend-cmake 0.1.0rc0
File Size Uploaded Provenance Actions
pants_backend_cmake-0.1.0rc0.tar.gz 38.7 kB Without provenance Details for pants_backend_cmake-0.1.0rc0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pants-backend-cmake 0.1.0rc0
File Interpreter ABI Platform Actions
pants_backend_cmake-0.1.0rc0-py3-none-any.whl Python 3 none any Details for pants_backend_cmake-0.1.0rc0-py3-none-any.whl

Total release size: 84.2 kB

Release files / pants_backend_cmake-0.1.0rc0.tar.gz

Download URL pants_backend_cmake-0.1.0rc0.tar.gz
Size 38.7 kB
Tags Source
SHA-256 checksum
How to use checksums
bac56779e51ec9030c912b8b0db9d45be7f222d3121e77d80ba0b8559c1b075b
BLAKE2b-256 checksum
How to use checksums
645245797a76a320bdbdcfe99802944c6681a1d2cb2c40a20715a3a8ae56378c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Release files / pants_backend_cmake-0.1.0rc0-py3-none-any.whl

Download URL pants_backend_cmake-0.1.0rc0-py3-none-any.whl
Size 45.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
374c113472d9c3b5020d439da21e037cec46e1b40bfd67d4609a4ec4628b383a
BLAKE2b-256 checksum
How to use checksums
6668452fad94d03cd006cb81e8c1db62e144ed3b8603e869bf88cd4827c128e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Security for pants-backend-cmake 0.1.0rc0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page