Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jobs:
runs-on: ubuntu-latest

steps:
# [DEPENDENCY] https://github.com/actions/checkout/releases
- uses: actions/checkout@v6

- name: Run dependency mapping tests
Expand All @@ -27,6 +28,7 @@ jobs:
runs-on: ubuntu-latest

steps:
# [DEPENDENCY] https://github.com/actions/checkout/releases
- uses: actions/checkout@v6

- name: Download CPM.cmake
Expand Down Expand Up @@ -136,6 +138,7 @@ jobs:
runs-on: ubuntu-latest

steps:
# [DEPENDENCY] https://github.com/actions/checkout/releases
- uses: actions/checkout@v6

- name: Check README examples
Expand Down
33 changes: 30 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,17 @@ cmake --build --preset=init

## Manual Setup

If you prefer to set up your project manually, or need to integrate cpp-library into an existing project, follow these steps.
If you prefer to set up your project manually or need to integrate the cpp-library into an existing project, follow these steps.

### Usage

Install [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake):

```bash
mkdir -p cmake
curl -L -o cmake/CPM.cmake "https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake"
```

Use `CPMAddPackage` to fetch cpp-library directly in your `CMakeLists.txt`:

```cmake
Expand Down Expand Up @@ -130,8 +137,6 @@ cpp_library_setup(
)
```

**Requirements:** CMake 3.24+, C++17+ compiler (GCC 7+, Clang 5+, MSVC 2017+, or Apple Clang 9+)

### Consuming Libraries Built with cpp-library

#### Using CPMAddPackage (recommended)
Expand Down Expand Up @@ -171,6 +176,13 @@ cmake --install build/install --prefix /opt/mylib
```
The `install` preset enables `CPM_USE_LOCAL_PACKAGES`, which verifies your generated Config.cmake works correctly. See the [CPM.cmake documentation](https://github.com/cpm-cmake/CPM.cmake#cpm_use_local_packages) for more about using installed packages.

**Controlling installation**: The `${NAMESPACE}_INSTALL` option controls whether installation is enabled (defaults to `PROJECT_IS_TOP_LEVEL`). Use `-D${NAMESPACE}_INSTALL=ON/OFF` to override:

```bash
cmake -DSTLAB_INSTALL=OFF -B build # Disable install for top-level project
cmake -DSTLAB_INSTALL=ON -B build # Enable install for non-top-level (e.g., via CPM)
```

**Re-exporting CPM dependencies:** When re-exporting dependencies from `CPMAddPackage`, wrap them in `BUILD_INTERFACE` to avoid export errors (CPM creates non-IMPORTED targets that can't be exported):

```cmake
Expand Down Expand Up @@ -333,6 +345,7 @@ cpp_library_setup(
- The project name is automatically taken from `PROJECT_NAME` (set by the `project()` command). You must call `project(your-library)` before `cpp_library_setup()`.
- **If you specify `TESTS` or `EXAMPLES`**, call `include(CTest)` after `project()` and before `cpp_library_setup()`.
- Version is automatically detected from git tags (see [Version Management](#version-management) for overrides).
- Installation is controlled by the `${NAMESPACE}_INSTALL` option, which defaults to `PROJECT_IS_TOP_LEVEL`.

### Target Naming

Expand Down Expand Up @@ -517,6 +530,20 @@ The dependency provider (CMake 3.24+) tracks `find_package()` and `CPMAddPackage

## Development

To use a local copy of cpp-library:

```
CPMAddPackage(
NAME cpp-library
SOURCE_DIR "${CMAKE_SOURCE_DIR}/../cpp-library"
)
```

To use cpp-library from a specific commit:
```
CPMAddPackage("gh:stlab/cpp-library#65dbed9fff9a0331355bd51dc1e8156262390154")
```

To run cpp-library's unit tests for dependency mapping and installation:

```bash
Expand Down
16 changes: 16 additions & 0 deletions cmake/cpp-library-ci.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@
# - Postcondition: .github/workflows/ci.yml created from template if not present
# - With force_init: overwrites existing workflow file
function(_cpp_library_setup_ci PACKAGE_NAME force_init)
# GitHub Actions refs (versions and source links) - update here to bump CI deps
# [DEPENDENCY] https://github.com/actions/checkout/releases
set(CI_ACTION_CHECKOUT "actions/checkout@v6")
# [DEPENDENCY] https://github.com/ilammy/msvc-dev-cmd/releases
# @1.13.0
set(CI_ACTION_MSVC_DEV_CMD "ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756")
# [DEPENDENCY] https://github.com/ssciwr/doxygen-install/releases
# @2.0.1
set(CI_ACTION_DOXYGEN_INSTALL "ssciwr/doxygen-install@329d88f5a303066a5bd006db7516b1925b86350e")
# [DEPENDENCY] https://github.com/actions/configure-pages/releases
set(CI_ACTION_CONFIGURE_PAGES "actions/configure-pages@v6")
# [DEPENDENCY] https://github.com/actions/upload-pages-artifact/releases
set(CI_ACTION_UPLOAD_PAGES_ARTIFACT "actions/upload-pages-artifact@v5")
# [DEPENDENCY] https://github.com/actions/deploy-pages/releases
set(CI_ACTION_DEPLOY_PAGES "actions/deploy-pages@v5")

set(ci_template "${CPP_LIBRARY_ROOT}/templates/.github/workflows/ci.yml.in")
set(ci_dest "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows/ci.yml")

Expand Down
3 changes: 2 additions & 1 deletion cmake/cpp-library-docs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ function(_cpp_library_setup_docs)
# Download doxygen-awesome-css theme via CPM
# https://github.com/jothepro/doxygen-awesome-css
CPMAddPackage(
URI gh:jothepro/doxygen-awesome-css@2.4.1
# [DEPENDENCY] https://github.com/jothepro/doxygen-awesome-css/releases
URI gh:jothepro/doxygen-awesome-css@2.4.2
DOWNLOAD_ONLY YES
)

Expand Down
21 changes: 17 additions & 4 deletions cmake/cpp-library-install.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ endfunction()
# - Precondition: NAME, PACKAGE_NAME, VERSION, and NAMESPACE specified; target NAME exists
# - Postcondition: install rules created for target, config files, and export with NAMESPACE:: prefix
# - Supports header-only (INTERFACE) and compiled libraries, uses SameMajorVersion compatibility
# - Installation can be controlled via ${NAMESPACE}_INSTALL option (defaults to PROJECT_IS_TOP_LEVEL)
function(_cpp_library_setup_install)
set(oneValueArgs
NAME # Target name (e.g., "stlab-enum-ops")
Expand All @@ -422,10 +423,6 @@ function(_cpp_library_setup_install)

cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

# Include required CMake modules (deferred from top-level to avoid requiring project() before include)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

# Validate required arguments
if(NOT ARG_NAME)
message(FATAL_ERROR "_cpp_library_setup_install: NAME is required")
Expand All @@ -440,6 +437,22 @@ function(_cpp_library_setup_install)
message(FATAL_ERROR "_cpp_library_setup_install: NAMESPACE is required")
endif()

# Define installation option with PROJECT_IS_TOP_LEVEL as default
# This allows explicit control: -D${NAMESPACE}_INSTALL=ON/OFF
# Upper-case the namespace for the option name
string(TOUPPER "${ARG_NAMESPACE}" NAMESPACE_UPPER)
option(${NAMESPACE_UPPER}_INSTALL "Enable installation of ${ARG_PACKAGE_NAME}" ${PROJECT_IS_TOP_LEVEL})

# Check if installation is enabled
if(NOT ${NAMESPACE_UPPER}_INSTALL)
message(STATUS "cpp-library: Installation disabled for ${ARG_PACKAGE_NAME} (${NAMESPACE_UPPER}_INSTALL=OFF)")
return()
endif()

# Include required CMake modules (deferred from top-level to avoid requiring project() before include)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

# Install the library target
# For header-only libraries (INTERFACE), this installs the target metadata
# For compiled libraries, this installs the library files and headers
Expand Down
25 changes: 10 additions & 15 deletions cmake/cpp-library-setup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ endfunction()

# Creates library target (INTERFACE or compiled) with headers and proper configuration.
# - Precondition: NAME, NAMESPACE, PACKAGE_NAME, CLEAN_NAME, and REQUIRES_CPP_VERSION specified
# - Postcondition: library target created with alias NAMESPACE::CLEAN_NAME, install configured if TOP_LEVEL
# - Postcondition: library target created with alias NAMESPACE::CLEAN_NAME; install rules when ${NAMESPACE}_INSTALL is ON
function(_cpp_library_setup_core)
set(oneValueArgs
NAME
Expand All @@ -65,7 +65,6 @@ function(_cpp_library_setup_core)
PACKAGE_NAME
CLEAN_NAME
REQUIRES_CPP_VERSION
TOP_LEVEL
)
set(multiValueArgs
HEADERS
Expand All @@ -80,9 +79,6 @@ function(_cpp_library_setup_core)
set(ARG_VERSION "${GIT_VERSION}")
endif()

# Note: Project declaration is now handled in the main cpp_library_setup function
# No need to check ARG_TOP_LEVEL here for project declaration

if(ARG_SOURCES)
# Create a library with sources (respects BUILD_SHARED_LIBS variable)
add_library(${ARG_NAME} ${ARG_SOURCES})
Expand Down Expand Up @@ -119,16 +115,15 @@ function(_cpp_library_setup_core)
endif()
endif()

# Setup installation when building as top-level project
if(ARG_TOP_LEVEL)
_cpp_library_setup_install(
NAME "${ARG_NAME}"
PACKAGE_NAME "${ARG_PACKAGE_NAME}"
VERSION "${ARG_VERSION}"
NAMESPACE "${ARG_NAMESPACE}"
HEADERS "${ARG_HEADERS}"
)
endif()
# Setup installation (controlled by ${NAMESPACE}_INSTALL option, defaults to PROJECT_IS_TOP_LEVEL)
# The option is defined and checked inside _cpp_library_setup_install()
_cpp_library_setup_install(
NAME "${ARG_NAME}"
PACKAGE_NAME "${ARG_PACKAGE_NAME}"
VERSION "${ARG_VERSION}"
NAMESPACE "${ARG_NAMESPACE}"
HEADERS "${ARG_HEADERS}"
)
Comment thread
cursor[bot] marked this conversation as resolved.

endfunction()

Expand Down
7 changes: 4 additions & 3 deletions cpp-library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ endfunction()
# Sets up a C++ header-only or compiled library with testing, docs, and install support.
# - Precondition: PROJECT_NAME defined via project(), at least one HEADERS specified
# - Postcondition: library target created, version set from git tags, optional tests/docs/examples configured
# - When PROJECT_IS_TOP_LEVEL: also configures templates, testing, docs, and installation
# - When PROJECT_IS_TOP_LEVEL: also configures templates, testing, and docs
# - Installation is controlled by ${NAMESPACE}_INSTALL (defaults to PROJECT_IS_TOP_LEVEL)
function(cpp_library_setup)
# Parse arguments
set(oneValueArgs
Expand Down Expand Up @@ -270,7 +271,6 @@ function(cpp_library_setup)
HEADERS "${GENERATED_HEADERS}"
SOURCES "${GENERATED_SOURCES}"
REQUIRES_CPP_VERSION "${ARG_REQUIRES_CPP_VERSION}"
TOP_LEVEL "${PROJECT_IS_TOP_LEVEL}"
)

# Only setup development infrastructure when building as top-level project
Expand All @@ -289,7 +289,8 @@ function(cpp_library_setup)
# This must happen during normal configuration (not deferred) because CPMAddPackage uses add_subdirectory
if(BUILD_TESTING AND (ARG_TESTS OR ARG_EXAMPLES))
if(NOT TARGET doctest::doctest)
CPMAddPackage("gh:doctest/doctest@2.4.12")
# [DEPENDENCY] https://github.com/doctest/doctest/releases
CPMAddPackage("gh:doctest/doctest@2.5.2")
endif()
endif()

Expand Down
18 changes: 10 additions & 8 deletions templates/.github/workflows/ci.yml.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Auto-generated from cpp-library (https://github.com/stlab/cpp-library)
# Do not edit this file directly - it will be overwritten when templates are regenerated
# Dependency versions are defined in cmake/cpp-library-ci.cmake (with source links)

name: CI

Expand Down Expand Up @@ -34,7 +35,9 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v6
- uses: @CI_ACTION_CHECKOUT@
- if: ${{ startsWith(matrix.os, 'windows') }}
uses: @CI_ACTION_MSVC_DEV_CMD@

- name: Configure CMake
run: cmake --preset=test
Expand Down Expand Up @@ -97,7 +100,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: @CI_ACTION_CHECKOUT@

- name: Configure CMake with clang-tidy
run: cmake --preset=clang-tidy
Expand All @@ -117,11 +120,10 @@ jobs:
contents: read

steps:
- uses: actions/checkout@v6
- uses: @CI_ACTION_CHECKOUT@

# ssciwr/doxygen-install@1.6.4
- name: Install Doxygen
uses: ssciwr/doxygen-install@501e53b879da7648ab392ee226f5b90e42148449
uses: @CI_ACTION_DOXYGEN_INSTALL@

- name: Configure CMake
run: cmake --preset=docs
Expand All @@ -130,13 +132,13 @@ jobs:
run: cmake --build --preset=docs

- name: Setup Pages
uses: actions/configure-pages@v5
uses: @CI_ACTION_CONFIGURE_PAGES@

- name: Upload artifact
uses: actions/upload-pages-artifact@v4
uses: @CI_ACTION_UPLOAD_PAGES_ARTIFACT@
with:
path: build/docs/html

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: @CI_ACTION_DEPLOY_PAGES@
7 changes: 7 additions & 0 deletions templates/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,10 @@ DISTRIBUTE_GROUP_DOC = YES
MAX_INITIALIZER_LINES = 0
MULTILINE_CPP_IS_BRIEF = YES
WARN_AS_ERROR = YES
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
DIRECTORY_GRAPH = NO
CLASS_GRAPH = NO
COLLABORATION_GRAPH = NO
GRAPHICAL_HIERARCHY = NO
GROUP_GRAPHS = NO