This repository is meant to be renamed into a real C++ library while keeping the build, wrapper, documentation, packaging, and CI machinery reusable.
Agents tailoring a fresh project should use bootstrap_prompts.md as the interactive configuration checklist before editing.
Use this order for a new library checkout:
-
Choose the project name, main C++ module name, optional CUDA module name, C++ namespace, and Python package name.
-
Inspect and apply the template cleanup before the broad rename pass:
./tailor_template_cleanup.sh --list ./tailor_template_cleanup.sh --apply --yes
Add
--keep-profilingonly when the new project should keep the optional Valgrind/perf helper scripts. -
Rename the template identifiers in tracked source files only. Exclude build trees, install trees, virtual environments, generated Python build metadata, and other generated artifacts. After cleanup succeeds, either delete
tailor_template_cleanup.shor exclude it from the rename pass; it is a one-shot template helper. -
Remove optional skeletons that the project will not use. For example, if the CUDA module directory is deleted, also remove the matching
add_subdirectory()entry fromsrc/CMakeLists.txt. -
Configure, build, and run CTest from a clean build directory.
-
Inspect remaining template names with
rg "template_project|template_src|template_src_kernels|cpp_playground"and keep only intentional references in examples or documentation.
The cleanup script contains template-specific filenames and test names, so running it before a global template_project replacement avoids stale cleanup paths.
Use one global replacement pass for the project name, then inspect the changed CMake package files and CMake option names.
| Template item | Replace with |
|---|---|
template_project |
Project/package name in snake_case |
template_src |
Primary C++ module directory |
template_src_kernels |
CUDA kernel module directory, or delete if CUDA is not used |
cpp_playground |
Top C++ namespace exposed to wrappers |
Update these files first:
CMakeLists.txt:set(project_name "...")CMakeLists.txt: default wrapper namespace value if wrappers are usedsrc/CMakeLists.txt: moduleadd_subdirectory()entries and status messagessrc/cmake/template_projectConfig.cmake.in: rename file and package referencessrc/bin/,examples/, andtests/: include paths and starter class namespython/pyproject.toml.in: package metadatapython/template_project/: package directory name.github/workflows/*.yml: workflow names, artifact names, and renamed CMake option prefixes when usefulREADME.mdanddoc/main_page.md: public project name and usage notes
Put public headers and compiled library sources under src/<module>/. The default library target exports ${PROJECT_NAME}::${PROJECT_NAME} after installation and exposes headers from include/<project_name>/.
The expected pattern is:
src/<module>/CMakeLists.txt
src/<module>/CMyClass.h
src/<module>/CMyClass.cpp
tests/<module>_test/testMyClass.cpp
examples/<module>_examples/exampleMyClass.cpp
Keep the wrapper-facing facade under src/wrapped_impl/ when a stable Python/MATLAB API should differ from internal C++ classes.
Installed consumers should use the exported package:
find_package(my_project REQUIRED)
target_link_libraries(my_target PRIVATE my_project::my_project)Nested consumers should override the internal target namespace if they include multiple template-derived libraries:
set(LIB_NAMESPACE_OVERRIDE nested_my_project CACHE STRING "" FORCE)
set(LIB_TARGET_NAME_OVERRIDE nested_my_project_library CACHE STRING "" FORCE)
add_subdirectory(path/to/my_project)
target_link_libraries(parent_target PRIVATE nested_my_project::my_project)Only the main project configures documentation, tests, examples, wrappers, and generic doc targets. Nested projects keep their library target available without publishing documentation for the parent build.
Use Catch2 for compiled tests, pytest for Python tests, and CTest as the common runner. Put compiled tests in test*.cpp or test*.cu files and Python tests in test*.py files. Add narrow CMake-script tests under tests/cmake/ when the behavior is about configuration, installation, generated files, CI YAML, or documentation output rather than runtime C++ behavior.
Run focused checks during development. Prefer ctest --test-dir <build> so the
same command works from the repository root, local scripts, and CI jobs:
cmake -S . -B build -DENABLE_TESTS=ON
cmake --build build --parallel 4
ctest --test-dir build --output-on-failureTest discovery is filename based:
test*.cppandtest*.cubecome Catch2 tests when Catch2 is available.test*.pybecomes pytest-backed CTest tests whenENABLE_PYTHON_TESTS=ON.- Use
EXCLUDED_LISTintests/CMakeLists.txtfor local files that should not be registered by the generic helper.
Run focused subsets:
ctest --test-dir build --output-on-failure -L python
ctest --test-dir build --output-on-failure -L catch2
ctest --test-dir build --output-on-failure -R testPythonSmokePass local CTest filters through the build helper:
./build_lib.sh --ctest-extra-args "-L python"Run Python tests inside conda while keeping C++ tests native:
cmake -S . -B build -DENABLE_TESTS=ON -DPYTHON_TEST_CONDA_ENV=my_env
cmake -S . -B build -DENABLE_TESTS=ON -DPYTHON_TEST_CONDA_PREFIX=/path/to/conda/envUse PYTHON_TEST_CONDA_ENV for a named environment and
PYTHON_TEST_CONDA_PREFIX for a temporary or path-pinned environment. Set only
one of them. The selected environment must provide pytest; CMake checks this
only when Python tests are enabled and at least one test*.py file is present.
Before broad renaming, list template-development-only files:
./tailor_template_cleanup.sh --listApply the cleanup once the list is acceptable:
./tailor_template_cleanup.sh --apply --yesBy default this also removes profiling/. Keep those scripts only when the new project will use Valgrind/perf helpers:
./tailor_template_cleanup.sh --apply --yes --keep-profilingThe script removes agent/context notes, internal development notes, workflow snapshot files, template-specific validation CTest scripts, optional profiling scripts, and the workspace file tied to this template checkout. It keeps reusable project infrastructure such as cmake/, build_lib.sh, docs workflow files, issue forms, examples, toolchains, starter unit tests, .devcontainer/, and .vscode/.
It also removes the root CMake hook for the template MATLAB regression helper and rewrites tests/CMakeLists.txt so only starter project unit tests remain registered.