ADR-008: Project-owned local dependency source overrides

Date: 2026-07-27

Status: Accepted

Context

Pet pins cmocka and SDL through CMake FetchContent. The defaults are reproducible, but the first configure may need network access even when a developer already has a suitable local checkout. Editing populated dependency sources is fragile because a later populate operation may replace those edits.

The project needs one stable override policy that does not expose its internal FetchContent content names as the developer contract. It must keep third-party diagnostics outside project diagnostics and must not turn package-manager discovery into another dependency path.

ESP-IDF is different from cmocka and SDL. It is an externally installed SDK and toolchain selected by its own environment rather than a dependency fetched by the hosted CMake build.

Decision

Pet exposes two CMake cache path variables:

  • PET_CMOCKA_SOURCE_DIR
  • PET_SDL_SOURCE_DIR

An unset variable keeps the pinned FetchContent declaration as the default. A set variable must name a source directory with a top-level CMakeLists.txt. Pet maps it to CMake’s dependency-specific FETCHCONTENT_SOURCE_DIR_* mechanism before making that dependency available. CMake then performs no download or update step for that dependency.

Developers may set the variables with -D arguments or in the Git-ignored CMakeUserPresets.json. CLI use should provide absolute paths. A relative path follows CMake’s normal cache path resolution. Local overrides must provide the targets and interfaces the build expects and must pass the same project tests. They are developer-controlled sources, not new project version pins or support claims.

cmocka is configured only when tests are enabled. SDL is configured only when the SDL frontend is selected. Their existing system-header and third-party diagnostic treatment remains unchanged.

ESP-IDF installation, IDF_PATH, toolchain activation, and SDK component discovery remain local environment setup. The firmware integration must use the supported ESP-IDF build model and must not introduce another Pet-specific source checkout variable without a later decision.

System package discovery, package-manager integration, vendored dependency sources, arbitrary local layouts, and guaranteed offline-first configuration without prepared local checkouts are out of scope.

Consequences

Pinned clean builds remain unchanged. A developer with prepared cmocka and SDL checkouts can configure and rebuild without contacting their dependency hosts.

The public variables remain stable if internal FetchContent content names change. The small mapping layer also provides project-owned path validation and diagnostics.

Local dependency changes can differ from the pins, so successful configuration is not enough to claim compatibility. The normal build and test suite remain the evidence. Release evidence continues to use pinned defaults unless it explicitly records an override.

CMakeUserPresets.json can hold machine-specific paths without modifying tracked project files. The project entrypoint does not gain arbitrary CMake argument forwarding. Maintainers use direct CMake for local override workflows.

Alternatives considered

Document FETCHCONTENT_SOURCE_DIR_CMOCKA and FETCHCONTENT_SOURCE_DIR_SDL3 directly. Rejected as the public contract because those names expose internal FetchContent identifiers and provide no project-owned validation.

Use find_package() before FetchContent. Rejected because package layouts and exported target names differ across systems and package managers. It would make the selected dependency less predictable than an explicit source checkout.

Vendor cmocka and SDL. Rejected because it duplicates third-party source in the repository and creates update ownership outside the release scope.

Use disconnected FetchContent modes alone. Rejected because they depend on an already populated build cache and do not identify a durable local source checkout.

References