Skip to content

Commit 9929435

Browse files
committed
Getting close to v1.
1 parent e475cf9 commit 9929435

File tree

6 files changed

+349
-7
lines changed

6 files changed

+349
-7
lines changed

cmake/cpp-library-ci.cmake

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-License-Identifier: BSL-1.0
2+
#
3+
# cpp-library-ci.cmake - CI setup functionality
4+
5+
function(_cpp_library_setup_ci)
6+
set(options
7+
CI_DEPLOY_DOCS
8+
)
9+
set(oneValueArgs
10+
NAME
11+
VERSION
12+
DESCRIPTION
13+
)
14+
set(multiValueArgs
15+
CI_PLATFORMS
16+
CI_COMPILERS
17+
)
18+
19+
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
20+
21+
# Set defaults
22+
if(NOT ARG_CI_PLATFORMS)
23+
set(ARG_CI_PLATFORMS "ubuntu-latest" "macos-latest" "windows-latest")
24+
endif()
25+
if(NOT ARG_CI_COMPILERS)
26+
set(ARG_CI_COMPILERS "gcc" "clang" "msvc")
27+
endif()
28+
29+
# Only generate CI files if they don't exist
30+
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows/ci.yml")
31+
# Create .github/workflows directory
32+
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows")
33+
34+
# Determine template source
35+
if(DEFINED CPP_LIBRARY_CI_TEMPLATE)
36+
# Embedded template (packaged version)
37+
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cpp-library-ci.yml.in" "${CPP_LIBRARY_CI_TEMPLATE}")
38+
set(TEMPLATE_FILE "${CMAKE_CURRENT_BINARY_DIR}/cpp-library-ci.yml.in")
39+
else()
40+
# External template file (development version)
41+
set(TEMPLATE_FILE "${CPP_LIBRARY_ROOT}/templates/.github/workflows/ci.yml.in")
42+
endif()
43+
44+
# Configure template variables
45+
set(PROJECT_NAME "${ARG_NAME}")
46+
set(PROJECT_VERSION "${ARG_VERSION}")
47+
set(PROJECT_DESCRIPTION "${ARG_DESCRIPTION}")
48+
if(ARG_CI_DEPLOY_DOCS)
49+
set(ENABLE_DOCS_DEPLOYMENT "true")
50+
else()
51+
set(ENABLE_DOCS_DEPLOYMENT "false")
52+
endif()
53+
54+
configure_file(
55+
"${TEMPLATE_FILE}"
56+
"${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows/ci.yml"
57+
@ONLY
58+
)
59+
60+
message(STATUS "Generated .github/workflows/ci.yml for ${ARG_NAME}")
61+
endif()
62+
63+
endfunction()

cmake/cpp-library-setup.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ function(_cpp_library_setup_core)
1010
NAMESPACE
1111
HEADER_DIR
1212
REQUIRES_CPP_VERSION
13+
TOP_LEVEL
1314
)
1415
set(multiValueArgs
1516
HEADERS
@@ -45,7 +46,7 @@ function(_cpp_library_setup_core)
4546
endif()
4647

4748
# Only set up full installation when building as top-level project
48-
if(PROJECT_IS_TOP_LEVEL)
49+
if(ARG_TOP_LEVEL)
4950
include(GNUInstallDirs)
5051
include(CMakePackageConfigHelpers)
5152

cpp-library.cmake

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-setup.cmake")
1616
include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-testing.cmake")
1717
include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-docs.cmake")
1818
include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-presets.cmake")
19+
include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-ci.cmake")
1920

2021
# Main entry point function - users call this to set up their library
2122
function(cpp_library_setup)
2223
# Parse arguments
2324
set(options
2425
CUSTOM_INSTALL # Skip default installation
2526
NO_PRESETS # Skip CMakePresets.json generation
27+
NO_CI # Skip CI generation (CI enabled by default)
2628
)
2729
set(oneValueArgs
2830
NAME # Project name (e.g., "stlab-enum-ops")
@@ -64,7 +66,7 @@ function(cpp_library_setup)
6466
set(ARG_REQUIRES_CPP_VERSION 17)
6567
endif()
6668

67-
# Call component setup functions
69+
# Create the basic library target (always done)
6870
_cpp_library_setup_core(
6971
NAME "${ARG_NAME}"
7072
VERSION "${ARG_VERSION}"
@@ -73,21 +75,30 @@ function(cpp_library_setup)
7375
HEADERS "${ARG_HEADERS}"
7476
HEADER_DIR "${ARG_HEADER_DIR}"
7577
REQUIRES_CPP_VERSION "${ARG_REQUIRES_CPP_VERSION}"
78+
TOP_LEVEL "${PROJECT_IS_TOP_LEVEL}"
7679
)
7780

78-
if(NOT ARG_NO_PRESETS AND PROJECT_IS_TOP_LEVEL)
81+
# Only setup development infrastructure when building as top-level project
82+
if(NOT PROJECT_IS_TOP_LEVEL)
83+
return() # Early return for lightweight consumer mode
84+
endif()
85+
86+
# Generate CMakePresets.json (unless disabled)
87+
if(NOT ARG_NO_PRESETS)
7988
_cpp_library_generate_presets()
8089
endif()
8190

82-
if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL AND ARG_TESTS)
91+
# Setup testing (if tests are specified)
92+
if(BUILD_TESTING AND ARG_TESTS)
8393
_cpp_library_setup_testing(
8494
NAME "${ARG_NAME}"
8595
NAMESPACE "${ARG_NAMESPACE}"
8696
TESTS "${ARG_TESTS}"
8797
)
8898
endif()
8999

90-
if(BUILD_DOCS AND PROJECT_IS_TOP_LEVEL)
100+
# Setup documentation (always for top-level)
101+
if(BUILD_DOCS)
91102
_cpp_library_setup_docs(
92103
NAME "${ARG_NAME}"
93104
VERSION "${ARG_VERSION}"
@@ -96,8 +107,18 @@ function(cpp_library_setup)
96107
)
97108
endif()
98109

99-
# Build examples if specified
100-
if(PROJECT_IS_TOP_LEVEL AND ARG_EXAMPLES)
110+
# Setup CI (unless disabled)
111+
if(NOT ARG_NO_CI)
112+
_cpp_library_setup_ci(
113+
NAME "${ARG_NAME}"
114+
VERSION "${ARG_VERSION}"
115+
DESCRIPTION "${ARG_DESCRIPTION}"
116+
CI_DEPLOY_DOCS YES # Always enable docs deployment
117+
)
118+
endif()
119+
120+
# Build examples if specified
121+
if(ARG_EXAMPLES)
101122
foreach(example IN LISTS ARG_EXAMPLES)
102123
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/example/${example}.cpp")
103124
string(REPLACE "${ARG_NAMESPACE}-" "" CLEAN_NAME "${ARG_NAME}")

dist/cpp-library.cmake

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,92 @@ HTML_EXTRA_FILES = @AWESOME_CSS_PATH@/doxygen-awesome-darkmode-toggle.js \
8484
HTML_HEADER =
8585
USE_MDFILE_AS_MAINPAGE = README.md
8686
")
87+
set(CPP_LIBRARY_CI_TEMPLATE "name: CI
88+
89+
on:
90+
push:
91+
branches: [ main, develop ]
92+
pull_request:
93+
branches: [ main ]
94+
95+
jobs:
96+
test:
97+
strategy:
98+
matrix:
99+
os: [ubuntu-latest, macos-latest, windows-latest]
100+
compiler: [gcc, clang, msvc]
101+
exclude:
102+
- os: ubuntu-latest
103+
compiler: msvc
104+
- os: macos-latest
105+
compiler: msvc
106+
- os: macos-latest
107+
compiler: gcc
108+
- os: windows-latest
109+
compiler: gcc
110+
- os: windows-latest
111+
compiler: clang
112+
113+
runs-on: ${{ matrix.os }}
114+
115+
steps:
116+
- uses: actions/checkout@v4
117+
118+
- name: Setup Ninja
119+
uses: ashutoshvarma/setup-ninja@master
120+
121+
- name: Setup GCC
122+
if: matrix.compiler == 'gcc'
123+
uses: egor-tensin/setup-gcc@v1
124+
with:
125+
version: latest
126+
127+
- name: Setup Clang
128+
if: matrix.compiler == 'clang' && matrix.os == 'ubuntu-latest'
129+
uses: egor-tensin/setup-clang@v1
130+
with:
131+
version: latest
132+
133+
- name: Setup MSVC
134+
if: matrix.compiler == 'msvc'
135+
uses: ilammy/msvc-dev-cmd@v1
136+
137+
- name: Configure CMake
138+
run: cmake --preset=test
139+
140+
- name: Build
141+
run: cmake --build --preset=test
142+
143+
- name: Test
144+
run: ctest --preset=test
145+
146+
docs:
147+
runs-on: ubuntu-latest
148+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
149+
150+
steps:
151+
- uses: actions/checkout@v4
152+
153+
- name: Setup Ninja
154+
uses: ashutoshvarma/setup-ninja@master
155+
156+
- name: Install Doxygen
157+
run: sudo apt-get update && sudo apt-get install -y doxygen graphviz
158+
159+
- name: Configure CMake
160+
run: cmake --preset=docs
161+
162+
- name: Build Documentation
163+
run: cmake --build --preset=docs
164+
165+
- name: Deploy to GitHub Pages
166+
if: success() && '@ENABLE_DOCS_DEPLOYMENT@' == 'true'
167+
uses: peaceiris/actions-gh-pages@v3
168+
with:
169+
github_token: ${{ secrets.GITHUB_TOKEN }}
170+
publish_dir: ./build/docs/html
171+
destination_dir: @PROJECT_NAME@
172+
")
87173

88174
# === cpp-library-setup.cmake ===
89175
function(_cpp_library_setup_core)
@@ -339,13 +425,77 @@ function(_cpp_library_generate_presets)
339425
endfunction()
340426

341427

428+
# === cpp-library-ci.cmake ===
429+
function(_cpp_library_setup_ci)
430+
set(options
431+
CI_DEPLOY_DOCS
432+
)
433+
set(oneValueArgs
434+
NAME
435+
VERSION
436+
DESCRIPTION
437+
)
438+
set(multiValueArgs
439+
CI_PLATFORMS
440+
CI_COMPILERS
441+
)
442+
443+
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
444+
445+
# Set defaults
446+
if(NOT ARG_CI_PLATFORMS)
447+
set(ARG_CI_PLATFORMS "ubuntu-latest" "macos-latest" "windows-latest")
448+
endif()
449+
if(NOT ARG_CI_COMPILERS)
450+
set(ARG_CI_COMPILERS "gcc" "clang" "msvc")
451+
endif()
452+
453+
# Only generate CI files if they don't exist
454+
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows/ci.yml")
455+
# Create .github/workflows directory
456+
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows")
457+
458+
# Determine template source
459+
if(DEFINED CPP_LIBRARY_CI_TEMPLATE)
460+
# Embedded template (packaged version)
461+
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cpp-library-ci.yml.in" "${CPP_LIBRARY_CI_TEMPLATE}")
462+
set(TEMPLATE_FILE "${CMAKE_CURRENT_BINARY_DIR}/cpp-library-ci.yml.in")
463+
else()
464+
# External template file (development version)
465+
set(TEMPLATE_FILE "${CPP_LIBRARY_ROOT}/templates/.github/workflows/ci.yml.in")
466+
endif()
467+
468+
# Configure template variables
469+
set(PROJECT_NAME "${ARG_NAME}")
470+
set(PROJECT_VERSION "${ARG_VERSION}")
471+
set(PROJECT_DESCRIPTION "${ARG_DESCRIPTION}")
472+
if(ARG_CI_DEPLOY_DOCS)
473+
set(ENABLE_DOCS_DEPLOYMENT "true")
474+
else()
475+
set(ENABLE_DOCS_DEPLOYMENT "false")
476+
endif()
477+
478+
configure_file(
479+
"${TEMPLATE_FILE}"
480+
"${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows/ci.yml"
481+
@ONLY
482+
)
483+
484+
message(STATUS "Generated .github/workflows/ci.yml for ${ARG_NAME}")
485+
endif()
486+
487+
endfunction()
488+
489+
342490
# === Main cpp_library_setup function ===
343491
# Main entry point function - users call this to set up their library
344492
function(cpp_library_setup)
345493
# Parse arguments
346494
set(options
347495
CUSTOM_INSTALL # Skip default installation
348496
NO_PRESETS # Skip CMakePresets.json generation
497+
ENABLE_CI # Generate CI files
498+
CI_DEPLOY_DOCS # Enable docs deployment in CI
349499
)
350500
set(oneValueArgs
351501
NAME # Project name (e.g., "stlab-enum-ops")
@@ -361,6 +511,8 @@ function(cpp_library_setup)
361511
TESTS # Test executables to build
362512
DOCS_EXCLUDE_SYMBOLS # Symbols to exclude from docs
363513
ADDITIONAL_DEPS # Extra CPM dependencies
514+
CI_PLATFORMS # CI platforms (default: ubuntu-latest, macos-latest, windows-latest)
515+
CI_COMPILERS # CI compilers (default: gcc, clang, msvc)
364516
)
365517

366518
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@@ -419,6 +571,17 @@ function(cpp_library_setup)
419571
)
420572
endif()
421573

574+
if(ARG_ENABLE_CI AND PROJECT_IS_TOP_LEVEL)
575+
_cpp_library_setup_ci(
576+
NAME "${ARG_NAME}"
577+
VERSION "${ARG_VERSION}"
578+
DESCRIPTION "${ARG_DESCRIPTION}"
579+
CI_PLATFORMS "${ARG_CI_PLATFORMS}"
580+
CI_COMPILERS "${ARG_CI_COMPILERS}"
581+
CI_DEPLOY_DOCS "${ARG_CI_DEPLOY_DOCS}"
582+
)
583+
endif()
584+
422585
# Build examples if specified
423586
if(PROJECT_IS_TOP_LEVEL AND ARG_EXAMPLES)
424587
foreach(example IN LISTS ARG_EXAMPLES)

0 commit comments

Comments
 (0)