Appearance
Formatting, Linting, and Editor Integration
An editor should consume the build's understanding of each translation unit. If it guesses a different standard, macros, target, or include path, completion and diagnostics become a parallel fiction.
Compilation databases bridge build and tooling
compile_commands.json records the working directory and compile command for source files. CMake can generate it with compatible generators:
sh
cmake -S . -B build -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ONclangd, clang-tidy, include tools, and custom analysis can then parse files with authoritative flags. Multi-config and MSBuild workflows may need alternative exporters or IDE-native integration.
Generated files and headers must exist before tools can fully analyze them. Configure the project before diagnosing every missing generated include.
clangd provides language intelligence
clangd uses compiler infrastructure for completion, navigation, rename, diagnostics, and formatting integration. Point it to the compilation database or make the database discoverable. A fallback flags file is useful only for simple projects because one flag set rarely fits every target.
Visual Studio IntelliSense and the Microsoft VS Code extension use their own project/configuration mechanisms. Whichever engine you choose, avoid maintaining include paths manually when CMake or MSBuild already knows them.
Formatting should be mechanical
clang-format applies a versioned .clang-format policy. Choose a base style, adjust a small number of team-relevant options, and avoid formatting entire legacy trees in feature changes. Pinning the formatter major version reduces noisy churn.
EditorConfig covers basic whitespace and line-ending behavior across file types. Formatting does not establish semantic correctness and should not be mixed conceptually with lint findings.
Include hygiene affects build and API boundaries
“Include what you use” means a source or public header should directly include declarations it relies on rather than depending on transitive accidents. Forward declarations can reduce coupling when complete types are unnecessary, but standard-library types should generally be included through their documented headers.
Tools such as include-what-you-use can help but need project-specific mappings and review. Removing a seemingly unused include can change macros or platform declarations, so changes must compile across targets.
Hooks accelerate feedback; CI enforces it
Pre-commit hooks can format changed files or run focused checks, but hooks can be missing or bypassed. CI should run the reproducible command that defines repository acceptance. Keep local commands fast enough that developers actually use them.
Optional prompts
Debug: clangd reports unknown macros although the CMake build succeeds. What artifact should it consume?
Answer: The compilation database or IDE build model containing the real per-file macro definitions, includes, language mode, and target.
Explain: Why pin clang-format for a repository?
Answer: Formatting algorithms and defaults can change between releases; pinning prevents tool upgrades from producing unrelated whole-tree diffs.