luban.cmake generated module
The cmake module luban generates and include()s into your project. Git-tracked — committed alongside source, so non-luban machines can build the project too.
Anatomy
# generated by luban — DO NOT EDIT BY HAND
# regenerate via: luban add / remove / sync / target add / target remove
# project deps come from vcpkg.json; flags come from luban.toml ([scaffold] section).
# ---- targets (LUBAN_TARGETS) ----
set(LUBAN_TARGETS calc mathlib)
# ---- find_package (auto from vcpkg.json dependencies) ----
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
# ---- luban_apply: call once per target after add_executable / add_library ----
function(luban_apply target)
target_compile_features(${target} PRIVATE cxx_std_23)
if(NOT MSVC)
target_compile_options(${target} PRIVATE -Wall -Wextra)
# static-link toolchain runtime so the exe runs without toolchain DLLs on PATH.
target_link_options(${target} PRIVATE -static -static-libgcc -static-libstdc++)
endif()
target_link_libraries(${target} PRIVATE
fmt::fmt
spdlog::spdlog
)
endfunction()
# ---- luban_register_targets: call once from root CMakeLists.txt ----
function(luban_register_targets)
foreach(t IN LISTS LUBAN_TARGETS)
if(EXISTS ${CMAKE_SOURCE_DIR}/src/${t}/CMakeLists.txt)
add_subdirectory(src/${t})
else()
message(WARNING "luban: target '${t}' has no src/${t}/CMakeLists.txt; skipping")
endif()
endforeach()
endfunction()
Three concerns, three sections
| Section | Source | What it controls |
|---|---|---|
LUBAN_TARGETS | luban target add/remove | Which subdirs luban_register_targets() walks |
find_package(...) | vcpkg.json dependencies | Which vcpkg libs are imported |
luban_apply(target) body | luban.toml [scaffold] + vcpkg.json deps | Flags + library links applied per target |
Inputs
vcpkg.json → dependencies (drives find_package + target_link_libraries)
luban.toml → cpp, warnings, sanitizers (drive compile_features + compile_options)
luban.cmake itself → LUBAN_TARGETS list (read back via parse so target add/remove are atomic)
How users interact
The user's root CMakeLists.txt is just:
cmake_minimum_required(VERSION 3.25)
project(foo CXX)
include(${CMAKE_SOURCE_DIR}/luban.cmake)
luban_register_targets()
Each src/<target>/CMakeLists.txt does:
add_executable(foo main.cpp)
luban_apply(foo)
# user can add target_link_libraries / target_compile_options here
That's the full surface area. Two function calls per project.
When luban.cmake is regenerated
luban add <pkg>/luban remove <pkg>— find_package + link list updatedluban sync— full regen from vcpkg.json + luban.tomlluban target add/luban target remove— LUBAN_TARGETS updated, rest preserved if vcpkg.json/luban.toml unchanged
The whole file is rewritten each time (no diff/merge); user-edits to luban.cmake will be lost. Don't edit it by hand. The header comment says this; the user-facing contract is: write your custom cmake outside this file.
Why this shape
See Architecture → Why no IR for the full rationale.