Skip to content

refactor(cmake): decompose top-level CMakeLists.txt into cmake/*.cmake modules#587

Merged
kcenon merged 1 commit intodevelopfrom
refactor/issue-581-cmake-decomposition
May 1, 2026
Merged

refactor(cmake): decompose top-level CMakeLists.txt into cmake/*.cmake modules#587
kcenon merged 1 commit intodevelopfrom
refactor/issue-581-cmake-decomposition

Conversation

@kcenon
Copy link
Copy Markdown
Owner

@kcenon kcenon commented May 1, 2026

What

Decompose the 609-line top-level CMakeLists.txt into 7 focused cmake/*.cmake modules. The top-level file is reduced to 64 lines containing only cmake_minimum_required, project(), CMAKE_MODULE_PATH setup, and ordered include(...) calls.

Closes #581.
Part of #577.

Why

A 600+ line top-level CMakeLists.txt is hard to review and edit. Per-concern modules let git diff clearly show which axis of the build (e.g., install rules vs. test discovery) a PR touches, and the canonical kcenon template enforces ordering invariants (project → options → dependencies → targets → tests → install) that prevent subtle bugs.

How

  • 7 new cmake/*.cmake modules created:
Module Lines Concern
cmake/options.cmake 73 All 18 option(...) declarations grouped by category, plus BUILD_INTEGRATION_TESTS cache fixup
cmake/compiler.cmake 111 C++ standard, output dirs, debug flags, CheckCXXSourceCompiles
cmake/dependencies.cmake 148 FindSystemDependency include + find_package(Threads), asio, OpenSSL, dependency probes
cmake/install.cmake 143 GNUInstallDirs, all install(...) rules, package config generation, D5 legacy-shim install (preserved byte-equivalent)
cmake/tests.cmake 27 enable_testing(), top-level test wiring
cmake/samples.cmake 18 Conditional add_subdirectory for samples/examples
cmake/summary.cmake 87 Build configuration summary printed after all *_FOUND flags settled
  • Existing cmake/FindSystemDependency.cmake (165 lines) and cmake/database_system-config.cmake.in left unchanged.
  • Top-level CMakeLists.txt (64 lines) consists of: cmake_minimum_required + project() + list(APPEND CMAKE_MODULE_PATH ...) + ordered include() calls + add_subdirectory(src) and conditional tests/samples.
  • A 7th module (summary.cmake) was added beyond the plan's 6 because the build-configuration summary block (~78 lines) cannot be merged into install.cmake without exceeding the 150-line cap, and semantically it's status reporting unrelated to install rules.

What was deliberately preserved

  • All ordering invariants: project() before any find_package, CMAKE_MODULE_PATH append before include(FindSystemDependency), GNUInstallDirs before any ${CMAKE_INSTALL_INCLUDEDIR} consumer, add_subdirectory(src) before install rules, summary last.
  • D5 legacy-shim install block (if(NOT DATABASE_DISABLE_LEGACY_HEADERS)) byte-equivalent in install.cmake.
  • All 18 option() defaults, 3 find_package calls, 6 install(...) calls, 6 add_subdirectory(...) calls.

Where

File Status
CMakeLists.txt Reduced from 609 to 64 lines
cmake/options.cmake New
cmake/compiler.cmake New
cmake/dependencies.cmake New
cmake/install.cmake New
cmake/tests.cmake New
cmake/samples.cmake New
cmake/summary.cmake New
cmake/FindSystemDependency.cmake Unchanged
cmake/database_system-config.cmake.in Unchanged
src/CMakeLists.txt, tests/CMakeLists.txt Unchanged (out of D4 scope per issue body)

Test Plan

  • Local cmake/g++ unavailable in sub-agent environment; relied on CI for build verification.
  • CI multi-platform builds (Ubuntu/macOS Debug+Release + integration tests) are the canonical validation that the build graph is preserved.
  • Sub-agent statically verified ordering invariants and call counts since CMake configure errors would only surface at CI time.

Notes for Reviewers

  • Behavior preservation guarantee: every option(...) default, find_package call, install(...) rule, and add_subdirectory(...) line was copied verbatim into the corresponding module. Counts checked: 18 options, 3 find_package, 6 install, 6 add_subdirectory.
  • Issue body said "9 modules": the original D4 plan in the issue listed 6 canonical modules. Implementation uses 7 because summary.cmake couldn't merge into install.cmake without breaking the 150-line cap. The acceptance criterion ("≤ 150 lines per module") is met.
  • Issue body said "19 options": actual count is 18 (verified by grep -c '^option('). Likely an off-by-one in the issue body when written. Functional content preserved.
  • src/CMakeLists.txt not touched: D4 scope per issue body is top-level only. src/CMakeLists.txt (648 lines) could be a candidate for a future decomposition issue but is explicitly out of scope here.

Rollback

git revert of this single squash-merge commit fully restores the monolithic 609-line CMakeLists.txt. No build behavior change so revert is symmetric.

…e modules

Split the 609-line top-level CMakeLists.txt into 7 focused modules
(options, compiler, dependencies, install, tests, samples, summary)
under cmake/. The top-level file is reduced to 64 lines containing
only cmake_minimum_required, project(), CMAKE_MODULE_PATH, and ordered
include() calls plus the if(BUILD_DATABASE) add_subdirectory(src) gate.

Module breakdown (all <= 150 lines):
  - cmake/options.cmake (73)       all 18 option() declarations,
                                   experimental backend warnings, and
                                   the BUILD_INTEGRATION_TESTS override.
  - cmake/compiler.cmake (111)     CXX standard, output dirs, debug
                                   flags, platform definitions, optional
                                   coroutine probe, ENABLE_COVERAGE.
  - cmake/dependencies.cmake (148) FindSystemDependency helper, Threads,
                                   OpenSSL, ASIO version probe, and
                                   common/thread/monitoring/container
                                   ecosystem integration.
  - cmake/install.cmake (143)      GNUInstallDirs, tiered install
                                   degradation, header install (incl.
                                   the issue-#582 legacy shim install
                                   gated by DATABASE_DISABLE_LEGACY_HEADERS),
                                   target export, package config files.
  - cmake/tests.cmake (27)         enable_testing() and the unit-test,
                                   benchmark, and integration-test
                                   add_subdirectory() wiring.
  - cmake/samples.cmake (18)       samples and examples add_subdirectory
                                   gated by their respective options.
  - cmake/summary.cmake (87)       human-readable build configuration
                                   summary printed last.

No semantic change: build graph, target list, install paths, CTest
discovery, and option defaults are all preserved. Ordering invariants
(project() before find_package, CMAKE_MODULE_PATH before
include(FindSystemDependency), GNUInstallDirs before
${CMAKE_INSTALL_INCLUDEDIR} use, install rules after add_subdirectory(src),
summary last) are maintained.

Counts verified pre/post:
  option():            18 / 18
  find_package():       3 /  3
  install():            6 /  6
  add_subdirectory():   6 /  6

Existing cmake/FindSystemDependency.cmake and
cmake/database_system-config.cmake.in are unchanged.

Part of #577. Closes #581.
@kcenon kcenon merged commit 593a18a into develop May 1, 2026
9 checks passed
@kcenon kcenon deleted the refactor/issue-581-cmake-decomposition branch May 1, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant