Skip to content

Commit 05a6a03

Browse files
henryiiiCopilot
andauthored
chore(cmake): add CMake presets (#5655)
* chore(cmake): add CMake presets Signed-off-by: Henry Schreiner <[email protected]> * Update .github/workflows/ci.yml * fix: don't autodetect `.venv` if inside a VIRTUALENV already Signed-off-by: Henry Schreiner <[email protected]> * Update CMakeLists.txt Co-authored-by: Copilot <[email protected]> --------- Signed-off-by: Henry Schreiner <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 853bafa commit 05a6a03

File tree

4 files changed

+149
-32
lines changed

4 files changed

+149
-32
lines changed

.github/workflows/ci.yml

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -220,25 +220,20 @@ jobs:
220220
with:
221221
fetch-depth: 0
222222

223-
- name: Prepare venv
224-
run: python3.13t -m venv .venv
223+
- name: Prepare uv's path
224+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
225225

226-
- name: Install Python deps
227-
run: .venv/bin/pip install -r tests/requirements.txt
226+
- name: Install ninja
227+
run: uv tool install ninja
228228

229-
- name: Configure C++11
230-
run: >
231-
cmake -S. -Bbuild
232-
-DPYBIND11_WERROR=ON
233-
-DDOWNLOAD_CATCH=ON
234-
-DDOWNLOAD_EIGEN=ON
235-
-DPython_ROOT_DIR=.venv
229+
- name: Configure via preset
230+
run: cmake --preset venv -DPYBIND11_CREATE_WITH_UV=python3.13t
236231

237232
- name: Build C++11
238-
run: cmake --build build -j2
233+
run: cmake --build --preset venv
239234

240235
- name: Python tests C++11
241-
run: cmake --build build --target pytest -j2
236+
run: cmake --build --preset testsvenv -t pytest
242237

243238
deadsnakes:
244239
strategy:
@@ -292,33 +287,27 @@ jobs:
292287
run: |
293288
sudo make install
294289
sudo apt-get update
295-
sudo apt-get install libc6-dbg # Needed by Valgrind
290+
sudo apt-get install ninja-build libc6-dbg
296291
297292
- name: Prepare env
298293
run: |
299294
python -m pip install -r tests/requirements.txt
300295
301296
- name: Configure
302-
run: >
303-
cmake -S . -B build
304-
-DCMAKE_BUILD_TYPE=Debug
305-
-DPYBIND11_WERROR=ON
306-
-DDOWNLOAD_CATCH=ON
307-
-DDOWNLOAD_EIGEN=ON
308-
-DCMAKE_CXX_STANDARD=17
297+
run: cmake --preset default -DCMAKE_CXX_STANDARD=17
309298

310299
- name: Build
311-
run: cmake --build build -j 2
300+
run: cmake --build --preset default
312301

313302
- name: Python tests
314-
run: cmake --build build --target pytest
303+
run: cmake --build --preset default --target pytest
315304

316305
- name: C++ tests
317-
run: cmake --build build --target cpptest
306+
run: cmake --build --preset default --target cpptest
318307

319308
- name: Run Valgrind on Python tests
320309
if: matrix.valgrind
321-
run: cmake --build build --target memcheck
310+
run: cmake --build --preset default --target memcheck
322311

323312

324313
# Testing on clang using the excellent silkeh clang docker images

CMakeLists.txt

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,60 @@ set(PYBIND11_FINDPYTHON
113113
${_pybind11_findpython_default}
114114
CACHE STRING "Force new FindPython - NEW, OLD, COMPAT")
115115

116-
# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
117-
# (makes transition easier while we support both modes).
118-
if(PYBIND11_MASTER_PROJECT
119-
AND PYBIND11_FINDPYTHON
120-
AND DEFINED PYTHON_EXECUTABLE
121-
AND NOT DEFINED Python_EXECUTABLE)
122-
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
116+
if(PYBIND11_MASTER_PROJECT)
117+
118+
# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
119+
# (makes transition easier while we support both modes).
120+
if(PYBIND11_FINDPYTHON
121+
AND DEFINED PYTHON_EXECUTABLE
122+
AND NOT DEFINED Python_EXECUTABLE)
123+
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
124+
endif()
125+
126+
if(NOT DEFINED Python3_EXECUTABLE
127+
AND NOT DEFINED Python_EXECUTABLE
128+
AND NOT DEFINED Python_ROOT_DIR
129+
AND NOT DEFINED ENV{VIRTUALENV}
130+
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
131+
message(STATUS "Autodetecting Python in virtual environment")
132+
set(Python_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
133+
endif()
134+
135+
# This is a shortcut that is primarily for the venv cmake preset,
136+
# but can be used to quickly setup tests manually, too
137+
set(PYBIND11_CREATE_WITH_UV
138+
""
139+
CACHE STRING "Create a virtualenv in Python_ROOT_DIR with uv if it doesn't exist")
140+
141+
if(NOT PYBIND11_CREATE_WITH_UV STREQUAL "")
142+
if(NOT DEFINED Python_ROOT_DIR)
143+
message(FATAL_ERROR "Python_ROOT_DIR must be defined to use PYBIND11_CREATE_WITH_UV")
144+
endif()
145+
if(EXISTS "${Python_ROOT_DIR}")
146+
message(STATUS "Using existing venv at ${Python_ROOT_DIR}, remove to recreate")
147+
else()
148+
find_program(UV uv REQUIRED)
149+
# CMake 3.19+ would be able to use COMMAND_ERROR_IS_FATAL
150+
message(
151+
STATUS "Creating venv with ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} '${Python_ROOT_DIR}'")
152+
execute_process(COMMAND ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} "${Python_ROOT_DIR}"
153+
RESULT_VARIABLE _venv_result)
154+
if(_venv_result AND NOT _venv_result EQUAL 0)
155+
message(FATAL_ERROR "uv venv failed with '${_venv_result}'")
156+
endif()
157+
message(
158+
STATUS
159+
"Installing deps with ${UV} pip install -p '${Python_ROOT_DIR}' -r tests/requirements.txt"
160+
)
161+
execute_process(
162+
COMMAND ${UV} pip install -p "${Python_ROOT_DIR}" -r
163+
"${CMAKE_CURRENT_SOURCE_DIR}/tests/requirements.txt" RESULT_VARIABLE _pip_result)
164+
if(_pip_result AND NOT _pip_result EQUAL 0)
165+
message(FATAL_ERROR "uv pip install failed with '${_pip_result}'")
166+
endif()
167+
endif()
168+
endif()
169+
123170
endif()
124171

125172
# NB: when adding a header don't forget to also add it to setup.py

CMakePresets.json

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"version": 6,
3+
"configurePresets": [
4+
{
5+
"name": "default",
6+
"displayName": "Default",
7+
"binaryDir": "build",
8+
"generator": "Ninja",
9+
"errors": {
10+
"dev": true,
11+
"deprecated": true
12+
},
13+
"cacheVariables": {
14+
"CMAKE_BUILD_TYPE": "Debug",
15+
"PYBIND11_FINDPYTHON": "NEW",
16+
"PYBIND11_WERROR": true,
17+
"DOWNLOAD_CATCH": true,
18+
"DOWNLOAD_EIGEN": true
19+
}
20+
},
21+
{
22+
"name": "venv",
23+
"displayName": "Venv",
24+
"inherits": "default",
25+
"cacheVariables": {
26+
"CMAKE_BUILD_TYPE": "Debug",
27+
"PYBIND11_CREATE_WITH_UV": "python3",
28+
"Python_ROOT_DIR": ".venv",
29+
"PYBIND11_WERROR": true,
30+
"PYBIND11_FINDPYTHON": "NEW",
31+
"DOWNLOAD_CATCH": true,
32+
"DOWNLOAD_EIGEN": true
33+
}
34+
}
35+
],
36+
"buildPresets": [
37+
{
38+
"name": "default",
39+
"displayName": "Default Build",
40+
"configurePreset": "default"
41+
},
42+
{
43+
"name": "venv",
44+
"displayName": "Venv Build",
45+
"configurePreset": "venv"
46+
},
47+
{
48+
"name": "tests",
49+
"displayName": "Tests (for workflow)",
50+
"configurePreset": "default",
51+
"targets": ["pytest", "cpptest", "test_cmake_build"]
52+
},
53+
{
54+
"name": "testsvenv",
55+
"displayName": "Tests Venv (for workflow)",
56+
"configurePreset": "venv",
57+
"targets": ["pytest", "cpptest", "test_cmake_build"]
58+
}
59+
],
60+
"workflowPresets": [
61+
{
62+
"name": "default",
63+
"displayName": "Default Workflow",
64+
"steps": [
65+
{ "type": "configure", "name": "default" },
66+
{ "type": "build", "name": "default" },
67+
{ "type": "build", "name": "tests" }
68+
]
69+
},
70+
{
71+
"name": "venv",
72+
"displayName": "Default Workflow",
73+
"steps": [
74+
{ "type": "configure", "name": "venv" },
75+
{ "type": "build", "name": "venv" },
76+
{ "type": "build", "name": "testsvenv" }
77+
]
78+
}
79+
]
80+
}

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ignore = [
1313
"pybind11/include/**",
1414
"pybind11/share/**",
1515
"CMakeLists.txt",
16+
"CMakePresets.json",
1617
"noxfile.py",
1718
]
1819

0 commit comments

Comments
 (0)