Skip to content

Commit 116737d

Browse files
committed
Merge branch 'master' into features/oi
2 parents 8997efc + 6240e45 commit 116737d

35 files changed

Lines changed: 1016 additions & 167 deletions

.gitattributes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# VERSION.txt holds a `$Format:...$` placeholder that stays literal in a working
2+
# tree and is expanded by `git archive`. This is what gives a version to source
3+
# tarballs (GitHub "Download ZIP", release tarballs, CMake FetchContent URL
4+
# downloads), which carry no .git directory and no sdist metadata.
5+
VERSION.txt export-subst

conda/win.yml renamed to .github/environments/win.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: pyinterp
22
dependencies:
33
- libboost-headers >= 1.90
44
- cmake
5+
- ninja
56
- dask
67
- numcodecs
78
- numpy

.github/workflows/ci.yaml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
create-args: |
5252
python=3.12
5353
environment-name: pyinterp
54-
environment-file: conda/linux.yml
54+
environment-file: .github/environments/linux.yml
5555
init-shell: bash
5656

5757
- name: Generate coverage data
@@ -94,7 +94,7 @@ jobs:
9494
create-args: |
9595
python=${{ matrix.python-version }}
9696
environment-name: pyinterp
97-
environment-file: conda/linux.yml
97+
environment-file: .github/environments/linux.yml
9898
init-shell: bash
9999

100100
- name: Build extension
@@ -189,7 +189,7 @@ jobs:
189189
create-args: |
190190
python=3.14
191191
environment-name: pyinterp
192-
environment-file: conda/osx.yml
192+
environment-file: .github/environments/osx.yml
193193
init-shell: bash
194194

195195
- name: Build extension
@@ -245,11 +245,24 @@ jobs:
245245
create-args: |
246246
python=3.14
247247
environment-name: pyinterp
248-
environment-file: conda/win.yml
248+
environment-file: .github/environments/win.yml
249+
250+
# The windows-2025 image now ships Visual Studio 18 (2026), so the pinned
251+
# "Visual Studio 17 2022" CMake generator no longer finds an instance.
252+
# Activate the MSVC developer environment (cl.exe + Ninja on PATH) and build
253+
# with the version-independent Ninja generator instead (see CMAKE_GEN).
254+
- name: Set up MSVC toolchain
255+
uses: ilammy/msvc-dev-cmd@v1
256+
with:
257+
arch: x64
249258

250259
- name: Building Testing Python Package
251260
shell: bash -l {0}
261+
env:
262+
CMAKE_GEN: Ninja
252263
run: |
253-
python setup.py build_ext --cmake-args="-DBoost_INCLUDE_DIRS=$CONDA_PREFIX/Library/include"
264+
# Convert the backslashes in $CONDA_PREFIX to forward slashes; otherwise
265+
# they are stripped when the argument is forwarded to CMake.
266+
python setup.py build_ext --cmake-args="-DBoost_INCLUDE_DIRS=${CONDA_PREFIX//\\//}/Library/include"
254267
python setup.py build
255268
pytest -v -ra

.github/workflows/wheels.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,25 @@ jobs:
5454
prefix="${MAMBA_ROOT_PREFIX//\\//}/envs/boost-deps/Library"
5555
echo "BOOST_PREFIX=${prefix}" >> "$GITHUB_ENV"
5656
57+
# The windows-2025 image now ships Visual Studio 18 (2026), so the pinned
58+
# "Visual Studio 17 2022" CMake generator no longer finds an instance.
59+
# Activate the MSVC developer environment (cl.exe + Ninja on PATH) before
60+
# cibuildwheel runs; its exported variables propagate to the isolated
61+
# build subprocesses, which build with the Ninja generator (CMAKE_GEN).
62+
- name: Set up MSVC toolchain (Windows)
63+
if: runner.os == 'Windows'
64+
uses: ilammy/msvc-dev-cmd@v1
65+
with:
66+
arch: x64
67+
5768
- name: Build wheels
5869
uses: pypa/cibuildwheel@v3.0
5970
env:
60-
# Windows: point CMake at the conda-forge Boost headers
71+
# Windows: point CMake at the conda-forge Boost headers and build with
72+
# the version-independent Ninja generator (VS 18 broke the VS 17 one).
6173
CIBW_ENVIRONMENT_WINDOWS: >-
6274
CMAKE_PREFIX_PATH="${{ env.BOOST_PREFIX }}"
75+
CMAKE_GEN="Ninja"
6376
# macOS: arm64 only (free Intel runners are deprecated).
6477
CIBW_ARCHS_MACOS: ${{ matrix.cibw_archs_macos }}
6578
# Sanity-check every built wheel imports and exposes its version.

.pre-commit-config.yaml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ repos:
55
- id: check-case-conflict
66
- id: check-docstring-first
77
- id: check-yaml
8-
exclude: "(conda/meta.yaml|.clang\\-format)$"
8+
exclude: "\\.clang\\-format$"
99
- id: debug-statements
1010
- id: end-of-file-fixer
1111
- id: mixed-line-ending
@@ -18,7 +18,7 @@ repos:
1818
- id: pyupgrade
1919
args: [--py311-plus]
2020
- repo: https://github.com/astral-sh/ruff-pre-commit
21-
rev: v0.15.14
21+
rev: v0.15.22
2222
hooks:
2323
- id: ruff
2424
args: [--fix]
@@ -37,18 +37,20 @@ repos:
3737
types: [file]
3838
files: CMakeLists.txt
3939
- repo: https://github.com/codespell-project/codespell
40-
rev: "v2.4.2"
40+
rev: "v2.4.3"
4141
hooks:
4242
- id: codespell
4343
exclude: "(cf.py|pyinterp/.*json)$"
4444
args: [--ignore-words-list, "degreee"] # degreeE is a valid axis unit
4545
- repo: https://github.com/pre-commit/mirrors-clang-format
46-
rev: v22.1.5
46+
rev: v22.1.8
4747
hooks:
4848
- id: clang-format
49-
exclude: "(dataset.*json)$"
49+
# *.hpp.in templates hold @VAR@ placeholders that clang-format, which
50+
# parses its input as C++, cannot handle.
51+
exclude: "(dataset.*json|\\.in)$"
5052
- repo: https://github.com/pre-commit/mirrors-mypy
51-
rev: v2.1.0
53+
rev: v2.3.0
5254
hooks:
5355
- id: mypy
5456
exclude: (examples|docs)/

CMakeLists.txt

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,41 @@ endif()
2222
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
2323
"${CMAKE_MODULE_PATH}")
2424

25+
# ##############################################################################
26+
# Resolve the project version
27+
# ##############################################################################
28+
# Must run before project(), which needs the numeric version up front. See
29+
# cmake/PyinterpVersion.cmake for the list of sources and their precedence.
30+
include(PyinterpVersion)
31+
pyinterp_resolve_version("${CMAKE_CURRENT_SOURCE_DIR}")
32+
2533
# ##############################################################################
2634
# Project settings
2735
# ##############################################################################
28-
project(pyinterp LANGUAGES CXX)
36+
project(
37+
pyinterp
38+
VERSION ${PYINTERP_VERSION_STRING}
39+
LANGUAGES CXX)
40+
41+
# Export the version to a parent project (add_subdirectory, FetchContent).
42+
pyinterp_publish_version()
43+
44+
# ##############################################################################
45+
# Sub-project detection
46+
# ##############################################################################
47+
# When pyinterp is consumed as a CMake sub-project, the caller wants the C++
48+
# library, not the Python extension: building the bindings would drag in Python,
49+
# nanobind and the stub generation for nothing. PROJECT_IS_TOP_LEVEL needs CMake
50+
# 3.21, so derive it by hand to keep the 3.19 requirement.
51+
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
52+
set(PYINTERP_IS_TOP_LEVEL ON)
53+
else()
54+
set(PYINTERP_IS_TOP_LEVEL OFF)
55+
endif()
56+
57+
option(PYINTERP_BUILD_PYTHON_BINDINGS
58+
"Build the pyinterp.core Python extension" ${PYINTERP_IS_TOP_LEVEL})
59+
option(PYINTERP_BUILD_TESTS "Build the C++ unit tests" ${PYINTERP_IS_TOP_LEVEL})
2960

3061
# ##############################################################################
3162
# CMake policies
@@ -277,7 +308,9 @@ if(NOT WIN32)
277308
endif()
278309

279310
# Python
280-
if(CMAKE_CROSSCOMPILING OR DEFINED ENV{CONDA_BUILD_CROSS_COMPILATION})
311+
if(NOT PYINTERP_BUILD_PYTHON_BINDINGS)
312+
# Nothing to do: the Python extension is not being built.
313+
elseif(CMAKE_CROSSCOMPILING OR DEFINED ENV{CONDA_BUILD_CROSS_COMPILATION})
281314
if(NOT DEFINED PYTHON_ROOT_DIR AND DEFINED ENV{PREFIX})
282315
set(PYTHON_ROOT_DIR "$ENV{PREFIX}")
283316
endif()
@@ -342,7 +375,9 @@ else()
342375
OPTIONAL_COMPONENTS Development.SABIModule
343376
REQUIRED)
344377
endif()
345-
include_directories(SYSTEM PRIVATE ${Python_INCLUDE_DIRS})
378+
if(PYINTERP_BUILD_PYTHON_BINDINGS)
379+
include_directories(SYSTEM ${Python_INCLUDE_DIRS})
380+
endif()
346381

347382
# BLAS
348383
#
@@ -372,7 +407,7 @@ if(BLAS_FOUND)
372407
if(MKL_INCLUDE_DIR)
373408
add_definitions(-DEIGEN_USE_MKL_ALL)
374409
add_definitions(-DMKL_LP64)
375-
include_directories(SYSTEM PRIVATE ${MKL_INCLUDE_DIR})
410+
include_directories(SYSTEM ${MKL_INCLUDE_DIR})
376411
endif()
377412
endif()
378413
else()
@@ -398,12 +433,13 @@ else()
398433
endif()
399434

400435
# Eigen3
401-
include_directories(SYSTEM PRIVATE
402-
${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen)
436+
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen)
403437

404438
# GoogleTest
405-
include(CTest)
406-
find_package(GTest)
439+
if(PYINTERP_BUILD_TESTS)
440+
include(CTest)
441+
find_package(GTest)
442+
endif()
407443

408444
# ##############################################################################
409445
# Parse FFT implementation configuration
@@ -431,8 +467,7 @@ endif()
431467

432468
# MKL does not provide a Discrete Cosine Transform (DCT). Always use pocketfft
433469
# for DCTs even when MKL is chosen as the FFT backend.
434-
include_directories(SYSTEM PRIVATE
435-
${CMAKE_CURRENT_SOURCE_DIR}/third_party/pocketfft)
470+
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/pocketfft)
436471
if(FFT_IMPLEMENTATION STREQUAL "pocketfft")
437472
set(FFT_LIBRARIES)
438473
endif()
@@ -475,9 +510,11 @@ endif()
475510
# ##############################################################################
476511
# Add subdirectories
477512
# ##############################################################################
478-
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/nanobind)
479-
include_directories(SYSTEM
480-
${CMAKE_CURRENT_SOURCE_DIR}/third_party/nanobind/include)
513+
if(PYINTERP_BUILD_PYTHON_BINDINGS)
514+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/nanobind)
515+
include_directories(SYSTEM
516+
${CMAKE_CURRENT_SOURCE_DIR}/third_party/nanobind/include)
517+
endif()
481518

482519
# ##############################################################################
483520
# External dependencies
@@ -545,14 +582,14 @@ if(NOT Boost_FOUND)
545582
check_boost_version("${Boost_INCLUDE_DIRS}" "1.90.0")
546583
endif()
547584

548-
include_directories(SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
585+
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
549586

550587
add_subdirectory(cxx)
551588

552589
# ##############################################################################
553590
# Disable clang-tidy for third-party targets (after add_subdirectory)
554591
# ##############################################################################
555-
if(ENABLE_CLANG_TIDY)
592+
if(ENABLE_CLANG_TIDY AND TARGET nanobind-static)
556593
set_target_properties(nanobind-static PROPERTIES CXX_CLANG_TIDY "")
557594
endif()
558595

@@ -587,6 +624,8 @@ format_enabled(ENABLE_CLANG_TIDY CLANG_TIDY_LINE)
587624

588625
set(CONFIG_LINES
589626
"==================[ PyInterp Configuration Summary ]=================="
627+
"Version: ${PYINTERP_VERSION_FULL}"
628+
"Version source: ${PYINTERP_VERSION_SOURCE}"
590629
"Platform: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_PROCESSOR}"
591630
"Build type: ${CMAKE_BUILD_TYPE}"
592631
"CMake Version: ${CMAKE_VERSION}"

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ recursive-include docs *
33
recursive-include cxx *
44
recursive-include pyinterp *.pyi
55
recursive-include third_party *
6+
recursive-include cmake *.cmake
67
recursive-exclude scripts *
8+
include scripts/generate_geometry_stubs.py
9+
include scripts/resolve_version.py
710
include pyinterp/_version.py
11+
include VERSION.txt
812
include CMakeLists.txt
913
include CODE_OF_CONDUCT.md
1014
include LICENSE

VERSION.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$Format:%(describe:tags=true)$

0 commit comments

Comments
 (0)