Use this guide to add a new subproject under projects// while keeping the root orchestrator, tests, and packaging metadata consistent.
mkdir -p projects/<name>/{include/<name>,src,tests}Choose one of the two common templates below.
Minimal STATIC library template (similar to hello-lib):
add_library(<name> STATIC src/<source>.cpp)
target_include_directories(
<name>
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_features(<name> PUBLIC cxx_std_20)
polycpp_add_strict_warnings(<name>)
polycpp_apply_sanitizers(<name>)
polycpp_enable_clang_tidy(<name>)
include(GNUInstallDirs)
install(
TARGETS <name>
EXPORT <name>-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT <name>_runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT <name>_runtime
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT <name>_runtime)
install(
DIRECTORY include/<name>/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/<name>
COMPONENT <name>_dev
FILES_MATCHING PATTERN "*.hpp")
install(
EXPORT <name>-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/<name>
NAMESPACE polycpp::
COMPONENT <name>_dev)
if(POLYCPP_BUILD_TESTS)
add_subdirectory(tests)
endif()Minimal executable template (similar to hello-app):
add_executable(<name> src/main.cpp)
target_compile_features(<name> PRIVATE cxx_std_20)
polycpp_add_strict_warnings(<name>)
polycpp_apply_sanitizers(<name>)
polycpp_enable_clang_tidy(<name>)
include(GNUInstallDirs)
install(
TARGETS <name>
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT <name>_runtime)
if(POLYCPP_BUILD_TESTS)
add_subdirectory(tests)
endif()Add one cache option and one guarded add_subdirectory call:
option(POLYCPP_BUILD_<NAME> "Build <name>" ON)
if(POLYCPP_BUILD_<NAME> AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/projects/<name>/CMakeLists.txt")
add_subdirectory(projects/<name>)
endif()Follow the same pattern as projects/hello-lib/tests/CMakeLists.txt: create a test target, link GTest and your subproject target, apply warnings and sanitizers, then call gtest_discover_tests.
Tag install destinations with COMPONENT _runtime and, for libraries with public headers or export files, COMPONENT _dev.
Add component names and metadata for every new component, including display name, description, and dependencies, then add generator-specific package names. Use existing hello_lib_runtime and hello_app_runtime blocks as the reference.
Typical variables include:
- CPACK_COMPONENT_RUNTIME*
- CPACK_COMPONENT_DEV*
- CPACK_DEBIAN__RUNTIME_PACKAGE_NAME
- CPACK_DEBIAN__DEV_PACKAGE_NAME
- CPACK_RPM__RUNTIME_PACKAGE_NAME
- CPACK_RPM__DEV_PACKAGE_NAME
If the new subproject needs additional libraries, update root CMAKE_MODULE_PATH and find_package(...) usage as needed, and add the dependency with a pinned version to conanfile.txt.
Conan-generated preset names can vary by environment and generator (for
example, conan-release vs conan-default), so use explicit toolchain
configure commands in automation and portable docs.
mkdir -p build && cd build
conan install .. --build=missing -pr:b=default -s build_type=Release
cd ..
cmake -S . -B build/Release -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=build/Release/generators/conan_toolchain.cmake \
-DPOLYCPP_WARNINGS_AS_ERRORS=ON
cmake --build build/Release
ctest --test-dir build/Release --output-on-failureThis template intentionally ships only Dockerfile.dev at the repo root. If your new subproject needs a runtime image, place a subproject-specific Dockerfile under projects// and keep its build flow scoped to that subproject.