Skip to content

Guardrails / cpp

Dependencies come from a package manager ​

cpp/package-manager-declared@v1

The checkout declares its dependencies through vcpkg or Conan, so it names the versions it builds against instead of taking whatever the machine has installed.

Idcpp/package-manager-declared
Versionv1
Categorycpp
Default severitywarning
Interpreterpython3
Timeout30 seconds
Violations tolerated0
Collectscpp

Collectors ​

This guardrail doesn't gather anything itself. It relies on the collectors below, which the CLI runs once per build before any check, and reads what they found from GUARDRAIL_FACTS. If a collector collects nothing, this guardrail is skipped, not failed.

CollectorGathersInputs it is given
cppThe C or C++ build in the project directory: which build system and package manager it uses, the C++ standard and CMake version it requires, the packages it declares and which of them are pinned, and the packages it expects the machine to carry. CMakeLists.txt is a script, so what it declares conditionally is not seen and scanned says so.projectDir

The inputs above are this guardrail's own inputs, passed straight through to the collector. Setting one in buildnote.json changes what is collected, and two guardrails configured the same way share a single collection.

Configuration ​

json
{
  "guardrails": {
      "failOn": "error",
      "checks": [
          {
              "use": "cpp/package-manager-declared@v1",
              "severity": "warning",
              "with": {
                  "projectDir": "."
              },
              "exemptions": []
          }
      ]
  }
}

Inputs ​

InputDescriptionDefaultEnvironment variable
projectDirDirectory holding the project, relative to the directory the CLI runs in..GUARDRAIL_INPUT_PROJECTDIR

How to fix ​

Declare your dependencies in a manifest the build resolves from, so find_package doesn't just pick up whatever is installed. For example, a vcpkg.json next to CMakeLists.txt:

json
{
  "name": "widget",
  "version": "1.2.3",
  "builtin-baseline": "6f3a1c2d9b8e4f7a0c5d2e1b3a4f5c6d7e8f9a0b",
  "dependencies": ["fmt", { "name": "spdlog", "version>=": "1.13.0" }]
}

or a conanfile.txt listing fmt/10.2.1 under [requires]. Without a manifest, the build links against whatever system packages the machine happens to have. The same commit builds against a different fmt on a laptop, in CI and in the release image, and the difference shows up as a crash instead of as a resolution error.

More in cpp ​

  • cpp/cmake-minimum-floor. A CMake build names the CMake version whose policy defaults it uses, and that version is no older than the configured floor.
  • cpp/standard-declared. A CMake build that enables C++ declares the standard it compiles against, and that standard is no older than the configured floor.
  • cpp/standard-required. A CMake build that enables C++ requires the standard it declares, so a compiler that doesn't support it fails instead of falling back to an older one.

All 4 cpp guardrails

Buildnote Limited
Registered in England and Wales, Reg: 16140412