Skip to content

Commit eb8e8d3

Browse files
committed
More cleanup.
1 parent 6dd0ad3 commit eb8e8d3

File tree

6 files changed

+160
-86
lines changed

6 files changed

+160
-86
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ cmake_minimum_required(VERSION 3.20)
2929
# Project declaration - cpp_library_setup will use this name and detect version from git tags
3030
project(your-library)
3131
32-
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cpm-cache CACHE PATH "CPM cache")
32+
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm CACHE PATH "CPM cache")
3333
include(cmake/CPM.cmake)
3434
3535
# Fetch cpp-library via CPM
@@ -166,7 +166,7 @@ cmake_minimum_required(VERSION 3.20)
166166
project(enum-ops)
167167
168168
# Setup cpp-library infrastructure
169-
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cpm-cache CACHE PATH "CPM cache" FORCE)
169+
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm CACHE PATH "CPM cache" FORCE)
170170
include(cmake/CPM.cmake)
171171
172172
# Fetch cpp-library via CPM
@@ -204,7 +204,7 @@ cpp_library_setup(
204204

205205
4. **Add examples** to `examples/` (use `_fail` suffix for compile-fail tests)
206206

207-
5. **Add tests** to `tests/`
207+
5. **Add tests** to `tests/` (use `_fail` suffix for compile-fail tests)
208208

209209
6. **Build and test**:
210210
```bash

cmake/cpp-library-ci.cmake

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ function(_cpp_library_setup_ci)
1414

1515
# Only generate CI files if they don't exist (unless forcing)
1616
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows/ci.yml" OR ARG_FORCE_INIT)
17+
# Create .github/workflows directory
18+
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows")
19+
20+
# Show appropriate message
1721
if(ARG_FORCE_INIT)
1822
message(STATUS "Force regenerating .github/workflows/ci.yml")
23+
else()
24+
message(STATUS "Generating .github/workflows/ci.yml from template")
1925
endif()
20-
# Create .github/workflows directory
21-
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.github/workflows")
2226

2327
# Determine template source
2428
if(DEFINED CPP_LIBRARY_CI_TEMPLATE)

cmake/cpp-library-presets.cmake

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ function(_cpp_library_generate_presets)
1111
return()
1212
endif()
1313

14+
set(PRESETS_TEMPLATE ${CPP_LIBRARY_ROOT}/templates/CMakePresets.json.in)
15+
set(PRESETS_OUT ${CMAKE_CURRENT_SOURCE_DIR}/CMakePresets.json)
16+
17+
# Show appropriate message
1418
if(ARG_FORCE_INIT)
1519
message(STATUS "Force regenerating CMakePresets.json")
20+
else()
21+
message(STATUS "Generating CMakePresets.json from template")
1622
endif()
1723

18-
set(PRESETS_TEMPLATE ${CPP_LIBRARY_ROOT}/templates/CMakePresets.json.in)
19-
set(PRESETS_OUT ${CMAKE_CURRENT_SOURCE_DIR}/CMakePresets.json)
20-
2124
# Configure the presets template
2225
configure_file(${PRESETS_TEMPLATE} ${PRESETS_OUT} @ONLY)
2326

cmake/cpp-library-testing.cmake

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
# SPDX-License-Identifier: BSL-1.0
22
#
33
# cpp-library-testing.cmake - Testing setup with doctest
4+
#
5+
# Note: Testing logic has been consolidated into the main cpp-library.cmake file
6+
# This file is kept for backward compatibility but the actual implementation
7+
# is now in the _cpp_library_setup_executables function.
48

9+
# Legacy function - now delegates to the consolidated implementation
510
function(_cpp_library_setup_testing)
611
set(oneValueArgs
712
NAME
@@ -13,38 +18,12 @@ function(_cpp_library_setup_testing)
1318

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

16-
# Extract the clean library name for linking
17-
string(REPLACE "${ARG_NAMESPACE}-" "" CLEAN_NAME "${ARG_NAME}")
18-
19-
# Download doctest dependency via CPM
20-
if(NOT TARGET doctest::doctest)
21-
CPMAddPackage("gh:doctest/[email protected]")
22-
endif()
23-
24-
# Add test executables
25-
foreach(test IN LISTS ARG_TESTS)
26-
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/${test}.cpp")
27-
28-
# Check tests/ directory
29-
set(test_file "")
30-
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/${test}.cpp")
31-
set(test_file "tests/${test}.cpp")
32-
endif()
33-
34-
add_executable(${test} ${test_file})
35-
target_link_libraries(${test} PRIVATE ${ARG_NAMESPACE}::${CLEAN_NAME} doctest::doctest)
36-
37-
# Register the test with CTest
38-
add_test(NAME ${test} COMMAND ${test})
39-
40-
# Set test properties for better IDE integration
41-
set_tests_properties(${test} PROPERTIES
42-
LABELS "doctest"
43-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
44-
)
45-
else()
46-
message(WARNING "Test file for ${test} not found in tests/ directory")
47-
endif()
48-
endforeach()
21+
# Delegate to the consolidated implementation
22+
_cpp_library_setup_executables(
23+
NAME "${ARG_NAME}"
24+
NAMESPACE "${ARG_NAMESPACE}"
25+
TYPE "tests"
26+
EXECUTABLES "${ARG_TESTS}"
27+
)
4928

5029
endfunction()

cpp-library.cmake

Lines changed: 116 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,83 @@ include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-docs.cmake")
1818
include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-presets.cmake")
1919
include("${CPP_LIBRARY_ROOT}/cmake/cpp-library-ci.cmake")
2020

21+
# Shared function to handle examples and tests consistently
22+
function(_cpp_library_setup_executables)
23+
set(oneValueArgs
24+
NAME
25+
NAMESPACE
26+
TYPE
27+
)
28+
set(multiValueArgs
29+
EXECUTABLES
30+
)
31+
32+
cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
33+
34+
# Extract the clean library name for linking
35+
string(REPLACE "${ARG_NAMESPACE}-" "" CLEAN_NAME "${ARG_NAME}")
36+
37+
# Download doctest dependency via CPM
38+
if(NOT TARGET doctest::doctest)
39+
CPMAddPackage("gh:doctest/[email protected]")
40+
endif()
41+
42+
# Determine source directory based on type
43+
if(ARG_TYPE STREQUAL "examples")
44+
set(source_dir "examples")
45+
elseif(ARG_TYPE STREQUAL "tests")
46+
set(source_dir "tests")
47+
else()
48+
message(FATAL_ERROR "_cpp_library_setup_executables: TYPE must be 'examples' or 'tests'")
49+
endif()
50+
51+
# Add executables
52+
foreach(executable IN LISTS ARG_EXECUTABLES)
53+
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${source_dir}/${executable}.cpp")
54+
55+
# Check if this is a compile-fail test (has "_fail" in the name)
56+
string(FIND "${executable}" "_fail" fail_pos)
57+
if(fail_pos GREATER -1)
58+
# Negative compile test: this executable must fail to compile
59+
add_executable(${executable} EXCLUDE_FROM_ALL "${source_dir}/${executable}.cpp")
60+
target_link_libraries(${executable} PRIVATE ${ARG_NAMESPACE}::${CLEAN_NAME})
61+
add_test(
62+
NAME compile_${executable}
63+
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${executable}
64+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
65+
)
66+
set_tests_properties(compile_${executable} PROPERTIES WILL_FAIL TRUE)
67+
else()
68+
# Regular executable - conditionally build based on preset
69+
add_executable(${executable} "${source_dir}/${executable}.cpp")
70+
target_link_libraries(${executable} PRIVATE ${ARG_NAMESPACE}::${CLEAN_NAME} doctest::doctest)
71+
72+
# Only fully build (compile and link) in test preset
73+
# In clang-tidy preset, compile with clang-tidy but don't link
74+
if(CMAKE_CXX_CLANG_TIDY)
75+
# In clang-tidy mode, exclude from all builds but still compile
76+
set_target_properties(${executable} PROPERTIES EXCLUDE_FROM_ALL TRUE)
77+
# Don't add as a test in clang-tidy mode since we're not linking
78+
else()
79+
# In test mode, build normally and add as test
80+
add_test(NAME ${executable} COMMAND ${executable})
81+
82+
# Set test properties for better IDE integration (only for tests)
83+
if(ARG_TYPE STREQUAL "tests")
84+
set_tests_properties(${executable} PROPERTIES
85+
LABELS "doctest"
86+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
87+
)
88+
endif()
89+
endif()
90+
endif()
91+
else()
92+
message(WARNING "${ARG_TYPE} file ${source_dir}/${executable}.cpp not found")
93+
endif()
94+
endforeach()
95+
96+
endfunction()
97+
2198
# Main entry point function - users call this to set up their library
2299
function(cpp_library_setup)
23100
# Parse arguments
@@ -73,7 +150,8 @@ function(cpp_library_setup)
73150
if(NOT DEFINED ARG_FORCE_INIT)
74151
set(ARG_FORCE_INIT FALSE)
75152
endif()
76-
if(CPP_LIBRARY_FORCE_INIT)
153+
154+
if(DEFINED CPP_LIBRARY_FORCE_INIT AND CPP_LIBRARY_FORCE_INIT)
77155
set(ARG_FORCE_INIT TRUE)
78156
endif()
79157

@@ -116,8 +194,8 @@ function(cpp_library_setup)
116194
return() # Early return for lightweight consumer mode
117195
endif()
118196

119-
# Create symlink to compile_commands.json for clangd
120-
if(CMAKE_EXPORT_COMPILE_COMMANDS)
197+
# Create symlink to compile_commands.json for clangd (only when BUILD_TESTING is enabled)
198+
if(CMAKE_EXPORT_COMPILE_COMMANDS AND BUILD_TESTING)
121199
add_custom_target(clangd_compile_commands ALL
122200
COMMAND ${CMAKE_COMMAND} -E create_symlink
123201
${CMAKE_BINARY_DIR}/compile_commands.json
@@ -127,17 +205,26 @@ function(cpp_library_setup)
127205
endif()
128206

129207
# Generate CMakePresets.json
130-
_cpp_library_generate_presets(FORCE_INIT ${ARG_FORCE_INIT})
208+
if(ARG_FORCE_INIT)
209+
_cpp_library_generate_presets(FORCE_INIT)
210+
else()
211+
_cpp_library_generate_presets()
212+
endif()
131213

132214
# Copy static template files (like .clang-format, .gitignore, etc.)
133-
_cpp_library_copy_templates(FORCE_INIT ${ARG_FORCE_INIT})
215+
if(ARG_FORCE_INIT)
216+
_cpp_library_copy_templates(FORCE_INIT)
217+
else()
218+
_cpp_library_copy_templates()
219+
endif()
134220

135221
# Setup testing (if tests are specified)
136222
if(BUILD_TESTING AND ARG_TESTS)
137-
_cpp_library_setup_testing(
223+
_cpp_library_setup_executables(
138224
NAME "${ARG_NAME}"
139225
NAMESPACE "${ARG_NAMESPACE}"
140-
TESTS "${ARG_TESTS}"
226+
TYPE "tests"
227+
EXECUTABLES "${ARG_TESTS}"
141228
)
142229
endif()
143230

@@ -152,41 +239,29 @@ function(cpp_library_setup)
152239
endif()
153240

154241
# Setup CI
155-
_cpp_library_setup_ci(
156-
NAME "${ARG_NAME}"
157-
VERSION "${ARG_VERSION}"
158-
DESCRIPTION "${ARG_DESCRIPTION}"
159-
FORCE_INIT ${ARG_FORCE_INIT}
160-
)
242+
if(ARG_FORCE_INIT)
243+
_cpp_library_setup_ci(
244+
NAME "${ARG_NAME}"
245+
VERSION "${ARG_VERSION}"
246+
DESCRIPTION "${ARG_DESCRIPTION}"
247+
FORCE_INIT
248+
)
249+
else()
250+
_cpp_library_setup_ci(
251+
NAME "${ARG_NAME}"
252+
VERSION "${ARG_VERSION}"
253+
DESCRIPTION "${ARG_DESCRIPTION}"
254+
)
255+
endif()
161256

162-
# Build examples if specified
163-
if(ARG_EXAMPLES)
164-
foreach(example IN LISTS ARG_EXAMPLES)
165-
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/${example}.cpp")
166-
string(REPLACE "${ARG_NAMESPACE}-" "" CLEAN_NAME "${ARG_NAME}")
167-
168-
# Check if this is a compile-fail test (has "_fail" in the name)
169-
string(FIND "${example}" "_fail" fail_pos)
170-
if(fail_pos GREATER -1)
171-
# Negative compile test: this example must fail to compile
172-
add_executable(${example} EXCLUDE_FROM_ALL "examples/${example}.cpp")
173-
target_link_libraries(${example} PRIVATE ${ARG_NAMESPACE}::${CLEAN_NAME})
174-
add_test(
175-
NAME compile_${example}
176-
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${example}
177-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
178-
)
179-
set_tests_properties(compile_${example} PROPERTIES WILL_FAIL TRUE)
180-
else()
181-
# Regular example
182-
add_executable(${example} "examples/${example}.cpp")
183-
target_link_libraries(${example} PRIVATE ${ARG_NAMESPACE}::${CLEAN_NAME})
184-
add_test(NAME ${example} COMMAND ${example})
185-
endif()
186-
else()
187-
message(WARNING "Example file examples/${example}.cpp not found")
188-
endif()
189-
endforeach()
257+
# Build examples if specified (only when BUILD_TESTING is enabled)
258+
if(BUILD_TESTING AND ARG_EXAMPLES)
259+
_cpp_library_setup_executables(
260+
NAME "${ARG_NAME}"
261+
NAMESPACE "${ARG_NAMESPACE}"
262+
TYPE "examples"
263+
EXECUTABLES "${ARG_EXAMPLES}"
264+
)
190265
endif()
191266

192267
endfunction()

templates/CMakePresets.json.in

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"generator": "Ninja",
1010
"cacheVariables": {
1111
"CMAKE_BUILD_TYPE": "Release",
12+
"BUILD_TESTING": "OFF",
1213
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
1314
"CMAKE_CXX_EXTENSIONS": "OFF"
1415
}
@@ -31,18 +32,26 @@
3132
"displayName": "Documentation Configuration",
3233
"description": "Configuration for building documentation",
3334
"binaryDir": "${sourceDir}/build/docs",
34-
"inherits": "test",
35+
"generator": "Ninja",
3536
"cacheVariables": {
36-
"BUILD_DOCS": "ON"
37+
"CMAKE_BUILD_TYPE": "Release",
38+
"BUILD_TESTING": "OFF",
39+
"BUILD_DOCS": "ON",
40+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
41+
"CMAKE_CXX_EXTENSIONS": "OFF"
3742
}
3843
},
3944
{
4045
"name": "clang-tidy",
4146
"displayName": "Clang-Tidy Configuration",
4247
"description": "Configuration for running clang-tidy static analysis",
4348
"binaryDir": "${sourceDir}/build/clang-tidy",
44-
"inherits": "test",
49+
"generator": "Ninja",
4550
"cacheVariables": {
51+
"CMAKE_BUILD_TYPE": "Debug",
52+
"BUILD_TESTING": "ON",
53+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
54+
"CMAKE_CXX_EXTENSIONS": "OFF",
4655
"CMAKE_CXX_CLANG_TIDY": "clang-tidy"
4756
}
4857
},
@@ -51,8 +60,12 @@
5160
"displayName": "Initialize Templates",
5261
"description": "Force regeneration of template files (CMakePresets.json, CI, etc.)",
5362
"binaryDir": "${sourceDir}/build/init",
54-
"inherits": "test",
63+
"generator": "Ninja",
5564
"cacheVariables": {
65+
"CMAKE_BUILD_TYPE": "Release",
66+
"BUILD_TESTING": "OFF",
67+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
68+
"CMAKE_CXX_EXTENSIONS": "OFF",
5669
"CPP_LIBRARY_FORCE_INIT": "ON"
5770
}
5871
}

0 commit comments

Comments
 (0)