Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: move to scikit-build-core #887

Merged
merged 17 commits into from
Mar 31, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/emscripten.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ jobs:
actions-cache-folder: emsdk-cache

- name: Build
run: CFLAGS=-fexceptions LDFLAGS=-fexceptions pyodide build
run: CFLAGS=-fexceptions LDFLAGS=-fexceptions pyodide build --exports whole_archive

- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20

- name: Set up Pyodide virtual environment
run: |
Expand Down
49 changes: 37 additions & 12 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
clang-tidy:
name: Clang-Tidy
runs-on: ubuntu-latest
container: silkeh/clang:15-bullseye
container: silkeh/clang:18-bookworm

steps:
- name: Install requirements
Expand All @@ -31,10 +31,10 @@ jobs:
submodules: true

- name: Install extra requirements
run: python3 -m pip install setuptools_scm
run: python3 -m pip install setuptools_scm --break-system-packages

- name: Configure
run: cmake -S . -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--warnings-as-errors=*"
run: cmake -S. -Bbuild -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--warnings-as-errors=*"

- name: Build
run: cmake --build build -j 2
Expand All @@ -55,6 +55,7 @@ jobs:
pipx run nox -s pylint

cmake:
name: CMake 🐍 ${{ matrix.python-version }}
runs-on: ubuntu-latest
env:
PIP_ONLY_BINARY: numpy
Expand All @@ -66,8 +67,6 @@ jobs:
- python-version: "3.8"
cmake-extras: "-DCMAKE_CXX_STANDARD=17"

name: CMake Python ${{ matrix.python-version }}

steps:
- uses: actions/checkout@v4
with:
Expand All @@ -80,10 +79,10 @@ jobs:
allow-prereleases: true

- name: Install python tools
run: python -m pip install -r dev-requirements.txt pytest-github-actions-annotate-failures numpy>=2.0a1
run: python -m pip install -r dev-requirements.txt pytest-github-actions-annotate-failures numpy>=2.0.0rc1

- name: Configure
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DBOOST_HISTOGRAM_ERRORS=ON ${{ matrix.cmake-extras }}
run: cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Debug -DBOOST_HISTOGRAM_ERRORS=ON ${{ matrix.cmake-extras }}

- name: Build
run: cmake --build build -j 2
Expand All @@ -93,30 +92,56 @@ jobs:
run: python -m pytest -ra

build_wheels:
name: Wheels on ${{ matrix.os }}
name: ${{ matrix.build }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-2019, macos-latest]
include:
- os: ubuntu-latest
build: cp312-manylinux_x86_64
- os: windows-2019
build: cp38-win32
- os: windows-2019
build: cp37-win_amd64
- os: macos-13
build: cp39-macosx_x86_64
- os: macos-14
build: cp39-macosx_arm64

steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0

- uses: actions/setup-python@v5
with:
python-version: "3.x"

- uses: pypa/[email protected]
env:
CIBW_BUILD: cp38-win32 cp312-manylinux_x86_64 cp37-macosx_x86_64
CIBW_BUILD: "${{ matrix.build }}"
CIBW_BUILD_VERBOSITY: 1
CIBW_ENVIRONMENT: "PIP_ONLY_BINARY=:all:"

- uses: actions/upload-artifact@v4
with:
path: wheelhouse/*
name: test-wheels-${{ strategy.job-index }}

# Pipx is either missing or broken on macos-14 runners ATM
- name: Install twine
run: pip install twine

- name: Check wheels
run: pipx run twine check wheelhouse/*
run: twine check wheelhouse/*
shell: bash

pass:
if: always()
needs: [clang-tidy, pylint, cmake, build_wheels]
runs-on: ubuntu-latest
steps:
- uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
21 changes: 14 additions & 7 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ concurrency:

env:
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ github.event.inputs.overrideVersion }}
CIBW_ENVIRONMENT: "PIP_PREFER_BINARY=1"

jobs:
build_sdist:
Expand Down Expand Up @@ -76,15 +75,23 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [windows-2019, macos-latest]
arch: [auto64]
build: ["*"]

include:
- os: macos-latest
arch: universal2
- os: macos-13
arch: auto64
build: "*"

- os: macos-14
arch: auto64
build: "*"

- os: windows-2019
arch: auto64
build: "cp*"

- os: windows-2019
arch: auto64
build: "pp*"

- os: windows-2019
arch: auto32
build: "*"
Expand Down
109 changes: 58 additions & 51 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
cmake_minimum_required(VERSION 3.10...3.26)
cmake_minimum_required(VERSION 3.24...3.29)

project(BOOST_HISTOGRAM LANGUAGES CXX)
# Version is added later

include(FetchContent)

# Boost histogram requires C++14
set(CMAKE_CXX_STANDARD
14
Expand Down Expand Up @@ -35,14 +37,24 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"RelWithDebInfo")
endif()

# Display versions
message(STATUS "CMake ${CMAKE_VERSION}")

# Adding pybind11 and setting up Python
# Will display pybind11 version
add_subdirectory(extern/pybind11)
set(PYBIND11_FINDPYTHON TRUE)
set(Python_ARTIFACTS_INTERACTIVE TRUE)

message(STATUS "Python ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG 3e9dfa2866941655c56877882565e7577de6fc7b # v2.12.0
FIND_PACKAGE_ARGS NAMES pybind11)
FetchContent_MakeAvailable(pybind11)

# Display versions
message(STATUS "CMake ${CMAKE_VERSION}")
message(STATUS "Python ${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}")
if(DEFINED pybind11_VERSION)
message(STATUS "pybind11 ${pybind11_VERSION}")
endif()

# This is completely optional and just adds hints to IDEs - no affect on build at all.
file(GLOB_RECURSE BOOST_HIST_FILES "extern/histogram/include/*.hpp")
Expand All @@ -53,7 +65,7 @@ file(GLOB_RECURSE BOOST_HIST_PY_HEADERS "include/bh_python/*.hpp")
file(GLOB BOOST_HIST_PY_SRC CONFIGURE_DEPENDS src/*.cpp)

# This is the Python module
pybind11_add_module(_core SHARED ${BOOST_HIST_PY_HEADERS} ${BOOST_HIST_PY_SRC} ${BOOST_HIST_FILES})
pybind11_add_module(_core MODULE ${BOOST_HIST_PY_HEADERS} ${BOOST_HIST_PY_SRC} ${BOOST_HIST_FILES})

# Add the include directory for boost/histogram/python
target_include_directories(_core PRIVATE include)
Expand All @@ -69,9 +81,16 @@ target_include_directories(
extern/throw_exception/include
extern/variant2/include)

# Useful flags
target_compile_options(_core
PRIVATE $<IF:$<CXX_COMPILER_ID:MSVC>,/fp:fast,-funsafe-math-optimizations>)
# Support older Windows from newer MSVC
target_compile_options(_core PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/d2FH4->)

# Better error messages
target_compile_definitions(_core PRIVATE PYBIND11_DETAILED_ERROR_MESSAGES)

# Atomic is required for armv7l
if(CMAKE_SYSTEM_PROCESSOR MATCHES "armv7l")
target_link_libraries(_core PRIVATE atomic)
endif()

# This makes IDE's like XCode mimic the Boost Histogram structure
source_group(
Expand Down Expand Up @@ -126,38 +145,37 @@ endif()
# which confuses Python.
set_property(TARGET _core PROPERTY LIBRARY_OUTPUT_DIRECTORY "$<1:boost_histogram>")

# Collect all the python files and symlink them (3.14+) or copy them (3.12-3.13)
# into the build directory
# Collect all the python files and symlink them into the build directory
# Protects from in-source builds (don't do this, please)
if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" AND NOT DEFINED
SKBUILD)
file(
GLOB_RECURSE BOOST_HIST_PY_FILES
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src"
CONFIGURE_DEPENDS "src/boost_histogram/*.py")
foreach(F IN LISTS BOOST_HIST_PY_FILES)
if(CMAKE_VERSION VERSION_LESS 3.14)
get_filename_component(FDIR "${F}" DIRECTORY)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/src/${F}"
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${FDIR}")
else()
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${F}")
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/src/${F}" "${CMAKE_CURRENT_BINARY_DIR}/${F}"
COPY_ON_ERROR SYMBOLIC)
endif()
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${F}")
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/src/${F}" "${CMAKE_CURRENT_BINARY_DIR}/${F}"
COPY_ON_ERROR SYMBOLIC)
endforeach()
endif()

# Support installing
install(DIRECTORY "src/boost_histogram" DESTINATION ".")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/boost_histogram/version.py"
DESTINATION "boost_histogram")
install(TARGETS _core DESTINATION "boost_histogram")

# Tests (Requires pytest to be available to run)
include(CTest)
if(NOT DEFINED SKBUILD)
install(DIRECTORY "src/boost_histogram" DESTINATION ".")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/boost_histogram/version.py"
DESTINATION "boost_histogram")

if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/boost_histogram/version.py")
# Tests (Requires pytest to be available to run)
include(CTest)
endif()

if(DEFINED SKBUILD)
# Don't worry about the version
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/boost_histogram/version.py")
set(VERSION_REGEX [=[version[ \t]*=[ \t]*["']([0-9]+\.[0-9]+\.[0-9]+)]=])

# Read in the line containing the version
Expand All @@ -170,37 +188,26 @@ else()
pybind11_find_import(setuptools_scm REQUIRED)

execute_process(
COMMAND
${PYTHON_EXECUTABLE} -c
"from setuptools_scm import get_version; print(get_version(root='${CMAKE_CURRENT_SOURCE_DIR}'))"
RESULT_VARIABLE VERSION_PRESENT
COMMAND ${Python_EXECUTABLE} -c "from setuptools_scm import get_version; print(get_version())"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE VERSION_FULL_STRING
ERROR_VARIABLE VERSION_ERROR)
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)

if(ERROR_VARIABLE)
message(STATUS "Warning from setuptools_scm:\n${ERROR_VARIABLE}")
endif()

if(NOT VERSION_PRESENT EQUAL 0)
message(
FATAL_ERROR
"Cannot detect ${VERSION_PRESENT} the version from setuptools_scm\n${VERSION_STRING}")
endif()

string(STRIP "${VERSION_FULL_STRING}" VERSION_FULL_STRING)
string(REGEX MATCH [=[^[0-9]+\.[0-9]+\.[0-9]+]=] VERSION_STRING "${VERSION_FULL_STRING}")
string(REPLACE "-" "." VERSION_STRING "${VERSION_STRING}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/boost_histogram/version.py"
"version = '${VERSION_FULL_STRING}'")
message(STATUS "Full version output: ${VERSION_FULL_STRING}")
endif()

project(
BOOST_HISTOGRAM
LANGUAGES CXX
VERSION ${VERSION_STRING})
message(STATUS "boost-histogram ${BOOST_HISTOGRAM_VERSION}")
if(NOT DEFINED SKBUILD)
project(
BOOST_HISTOGRAM
LANGUAGES CXX
VERSION ${VERSION_STRING})
message(STATUS "boost-histogram ${BOOST_HISTOGRAM_VERSION}")

if(BUILD_TESTING)
add_subdirectory(tests)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
endif()
26 changes: 0 additions & 26 deletions MANIFEST.in

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ platforms have wheels provided in boost-histogram:
| ManyLinux2014 | 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.7, 3.8, 3.9, 3.10 |
| ManyLinux2014 | ARM64 | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.7, 3.8, 3.9, 3.10 |
| MuslLinux_1_1 | 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | |
| macOS 10.9+ | 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.7, 3.8, 3.9, 3.10 |
| macOS 10.9+ | 64-bit | 3.7 | 3.7, 3.8, 3.9, 3.10 |
| macOS Universal2 | Arm64 | 3.8, 3.9, 3.10, 3.11, 3.12 | |
| Windows | 32 & 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | |
| Windows | 64-bit | | 3.7, 3.8, 3.9, 3.10 |
Expand Down
2 changes: 0 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
cloudpickle
dataclasses; python_version<'3.7'
hypothesis >=6.0
numpy
pytest >=6,!=6.1.0,!=7.1.0
pytest-benchmark
setuptools >=42
setuptools_scm[toml] >=3.4,!=4.0.0
typing_extensions; python_version<'3.8'
uproot
1 change: 0 additions & 1 deletion extern/pybind11
Submodule pybind11 deleted from 3e9dfa
Loading
Loading