CMake Coding Guidelines
Requirements
- CMake ≥ 3.20; modern target-based usage.
Essentials
- Target-based builds - Use targets, no global include/link dirs, see references/target-types.md, references/compile-options.md
- Visibility specifiers - Use PUBLIC/PRIVATE/INTERFACE correctly, see references/visibility-specifiers.md
- Dependencies - Declare explicitly with find_package, see references/find-package.md
- Testing - Enable testing with CTest, see references/testing.md
- Project structure - Organize multi-directory projects, see references/project-structure.md
Gotchas
target_link_librariesscope matters: PRIVATE = consumers don't see it, INTERFACE = no compile, PUBLIC = both. Wrong scope leaks transitive depsfind_packagemay use PATHS or HINTS but ignores both if a config file is on a system path; use<Pkg>_ROOTenv var to force-locate- Generator expressions (
$<CONFIG:Debug>) only evaluate at build time: debugging bymessage()won't show their final values CMAKE_INSTALL_PREFIXis captured at configure time; changing it after first config requires a clean reconfigure
Progressive disclosure
- Read references/target-types.md - Load when choosing between library types or executables
- Read references/visibility-specifiers.md - Load when deciding PUBLIC vs PRIVATE vs INTERFACE
- Read references/compile-options.md - Load when adding compiler flags to targets
- Read references/find-package.md - Load when integrating external dependencies
- Read references/testing.md - Load when setting up CTest or test targets
- Read references/project-structure.md - Load when organizing multi-directory CMake projects
- Read references/generator-expressions.md - Load when using conditional build configuration
- Read references/installation.md - Load when creating install targets or package exports