Skip to content

Latest commit

 

History

History
154 lines (108 loc) · 6.86 KB

File metadata and controls

154 lines (108 loc) · 6.86 KB

Template Usage Guide

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.

Fresh Library Tailoring Sequence

Use this order for a new library checkout:

  1. Choose the project name, main C++ module name, optional CUDA module name, C++ namespace, and Python package name.

  2. Inspect and apply the template cleanup before the broad rename pass:

    ./tailor_template_cleanup.sh --list
    ./tailor_template_cleanup.sh --apply --yes

    Add --keep-profiling only when the new project should keep the optional Valgrind/perf helper scripts.

  3. 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.sh or exclude it from the rename pass; it is a one-shot template helper.

  4. 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 from src/CMakeLists.txt.

  5. Configure, build, and run CTest from a clean build directory.

  6. 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.

Rename Checklist

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 used
  • src/CMakeLists.txt: module add_subdirectory() entries and status messages
  • src/cmake/template_projectConfig.cmake.in: rename file and package references
  • src/bin/, examples/, and tests/: include paths and starter class names
  • python/pyproject.toml.in: package metadata
  • python/template_project/: package directory name
  • .github/workflows/*.yml: workflow names, artifact names, and renamed CMake option prefixes when useful
  • README.md and doc/main_page.md: public project name and usage notes

Adding C++ Code

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.

Library Consumers

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.

Tests

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-failure

Test discovery is filename based:

  • test*.cpp and test*.cu become Catch2 tests when Catch2 is available.
  • test*.py becomes pytest-backed CTest tests when ENABLE_PYTHON_TESTS=ON.
  • Use EXCLUDED_LIST in tests/CMakeLists.txt for 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 testPythonSmoke

Pass 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/env

Use 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.

Tailoring Cleanup Script

Before broad renaming, list template-development-only files:

./tailor_template_cleanup.sh --list

Apply the cleanup once the list is acceptable:

./tailor_template_cleanup.sh --apply --yes

By 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-profiling

The 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.