This manual documents the project helper API implemented under `cmake/`. The examples are intentionally close to the positive helper fixtures and current root usage, but paths and target names are illustrative unless a section explicitly says otherwise.
## Global conventions
- Call native `project(<name> LANGUAGES C CXX)` before `cc_project()`; the helper rejects CMake's implicit `project(Project)` default.
- The primary project standard is C++14. Fuzz lane targets require the fuzz preset or equivalent Clang + C++17 configuration.
-`INCS`, `DEPS`, and `DEFINES` use explicit visibility groups. Every item must follow `PUBLIC`, `PRIVATE`, or `INTERFACE`; unqualified items are rejected.
- Executable-like targets (`cc_executable`, `cc_test`, `cc_benchmark`, and `cc_fuzz`) do not support `INTERFACE` visibility because they are not consumed as link interfaces. Use `PUBLIC` or `PRIVATE` only.
-`cc_library(TYPE INTERFACE)` supports only `INTERFACE` visibility for `INCS`, `DEPS`, and `DEFINES`.
- Helpers automatically link the framework Core runtime defaults: `spdlog::spdlog`, `fmt::fmt`, `nlohmann_json::nlohmann_json`, `toml11::toml11`, `CLI11::CLI11`, `asio::asio`, `concurrentqueue::concurrentqueue`, `ghcFilesystem::ghc_filesystem`, `nonstd::expected-lite`, and `httplib::httplib`. Static/shared libraries receive these defaults as `PUBLIC`, interface libraries as `INTERFACE`, and executable-like targets as `PRIVATE`.
- Helpers do not acquire lane-specific external dependencies directly. The template infrastructure loads `GTest::gtest`, `benchmark::benchmark`, and `fuzztest::fuzztest` from the committed archive model when the corresponding helper lane is enabled.
- There are aggregate targets `run_tests` and `run_benchmarks`, but no per-target `run_test_<name>`, `run_benchmark_<name>`, or `run_fuzz_<name>` wrappers.
## `cc_project()`
Signature:
```cmake
cc_project()
```
Use in the root `CMakeLists.txt` after native `project()` and after any cache variables that should influence helper options.
```cmake
cmake_minimum_required(VERSION3.19)
project(my_packageLANGUAGESCCXX)
include(cmake/cc_project.cmake)
cc_project()
```
Behavior:
- Sets C++ defaults: C++14 by default, required standard, extensions off.
- Enables `CMAKE_EXPORT_COMPILE_COMMANDS` unless the caller already set it.
- Enables position-independent code.
- Defines helper options:
-`CC_ENABLE_INSTALL`: ON by default for the top-level project, OFF for subprojects.
- Uses public lane options only: `CC_ENABLE_TESTING`, `CC_ENABLE_BENCHMARKS`, `CC_ENABLE_FUZZTEST`, and `CC_ENABLE_ASAN`. Users do not need lane `if()` wrappers around `cc_test()`, `cc_benchmark()`, or `cc_fuzz()`.
- Without `NO_MAIN`, also requires and links `benchmark::benchmark_main`.
- With `NO_MAIN`, links `benchmark::benchmark` only; use this when the benchmark source provides `main()`.
- Requires non-empty `SRCS`.
- Does not register the benchmark with default CTest.
- Adds the benchmark target as a dependency of `run_benchmarks` when that aggregate target exists.
- Adds a `POST_BUILD` command to `run_benchmarks` that directly executes the benchmark binary with `ARGS`.
-`ARGS` are native Google Benchmark runtime arguments. There is no helper-specific `OUTPUT` keyword; use native flags such as `--benchmark_out=<path>` and `--benchmark_out_format=json`.
- When fuzz is requested but unavailable, logs a status message and returns without creating a target. This is the normal behavior for default C++14/test lanes.
- Fuzz targets are created only when `CC_ENABLE_FUZZTEST_AVAILABLE` is true: Clang, C++17, and the isolated fuzz GTest lane via `cmake --preset fuzz` or equivalent setup.
Example with explicit smoke and long-run arguments:
```cmake
cc_fuzz(parser_fuzz
REQUIRED
SRCSparser_fuzz.cc
DEPSPRIVATEparser
FEATUREScxx_std_17
SMOKE_ARGS--fuzz_for=1s
SMOKE_ENVFUZZTEST_PRNG_SEED=42
SMOKE_TIMEOUT10
ARGS--fuzz_for=600s
)
```
## `cc_install()`
Signature:
```cmake
cc_install(<target>[DEPS<logical-name>...])
```
Behavior:
- Marks an existing target for install/export by setting `_CC_INSTALL TRUE`.
- Fails if the target does not exist.
-`DEPS` lists install-time dependency logical names registered with `cc_register_dependency()`.
-`DEPS` is not a link dependency list. Link dependencies belong in `cc_library(... DEPS ...)` or `cc_executable(... DEPS ...)`; install-time `DEPS` control generated `find_dependency()` calls and static private dependency validation.
- Installable targets must have explicit namespaced `ALIAS` metadata before finalization. The helpers do not auto-create aliases.
Example using explicit install marking instead of an `INSTALL` keyword:
```cmake
cc_library(core
TYPESTATIC
SRCScore.cpp
INCSPUBLIC${CMAKE_CURRENT_SOURCE_DIR}/include
DEPSPRIVATEZLIB::ZLIB
ALIASmypkg::core
)
cc_register_dependency(zlib
PACKAGEZLIB
TARGETSZLIB::ZLIB
)
cc_install(coreDEPSzlib)
```
## `cc_register_dependency()`
Signature:
```cmake
cc_register_dependency(<logical-name>
PACKAGE<PackageName>
[VERSION<version-or-range>]
[EXACT]
[COMPONENTS<component>...]
[OPTIONAL_COMPONENTS<component>...]
[TARGETS<target>...]
)
```
Behavior:
- Registers package metadata for generated package config files.
-`PACKAGE` is required and becomes the `find_dependency(<PackageName> ...)` package name.
-`VERSION`, `EXACT`, `COMPONENTS`, and `OPTIONAL_COMPONENTS` are forwarded to `find_dependency()`.
-`TARGETS` records the imported targets provided by the package. It is metadata used by install/export validation.
- Duplicate logical names are allowed only when all metadata matches exactly; conflicting re-registration fails at configure time.
- Reference registered logical names from `cc_install(<target> DEPS <logical-name>...)`.
Example:
```cmake
cc_register_dependency(fmt
PACKAGEfmt
VERSION10.0
TARGETSfmt::fmt
)
cc_library(formatting
TYPESTATIC
SRCSformatting.cpp
DEPSPUBLICfmt::fmt
ALIASmypkg::formatting
INSTALL
)
cc_install(formattingDEPSfmt)
```
## `cc_finalize_install()`
Signature:
```cmake
cc_finalize_install()
```
Behavior:
- Idempotent; repeated calls after the first do nothing.
- Returns without producing install rules when `CC_ENABLE_INSTALL` is OFF.
- Uses only targets marked by `INSTALL` or `cc_install()`.
- Validates that every install target has an explicit namespaced alias of the form `namespace::name`.
- Requires all installed targets to use the same namespace.
- Sets `EXPORT_NAME` from the alias leaf and installs targets into a single export set named `<project>Targets`.
- Generates and installs `<project>Config.cmake` and `<project>ConfigVersion.cmake`.
- Emits `find_dependency()` calls for logical dependencies declared with `cc_install(... DEPS ...)`.
- Installs public headers from `include/<project>/` when that directory exists.
-`cc_project()` schedules this function with `cmake_language(DEFER)` for top-level projects, so most projects should not need to call it manually.
Manual finalization example for a narrow fixture or custom project layout:
```cmake
include(cmake/cc_project.cmake)
include(cmake/cc_targets.cmake)
include(cmake/cc_install.cmake)
cc_project()
cc_library(core
TYPESTATIC
SRCScore.cpp
ALIASmypkg::core
INSTALL
)
cc_finalize_install()
```
## Unsupported helper patterns
Do not use these patterns through the helper API:
```cmake
# Unsupported: OBJECT library type.
cc_library(objTYPEOBJECTSRCSobj.cpp)
# Unsupported: missing visibility before dependency.