Skip to content

Commit

Permalink
feat: move to scikit-build-core (#887)
Browse files Browse the repository at this point in the history
* feat: move to scikit-build-core

Signed-off-by: Henry Schreiner <[email protected]>

* Update emscripten.yaml

* Update .github/workflows/emscripten.yaml

* fix: modernize CMake usage

Signed-off-by: Henry Schreiner <[email protected]>

* fix: use CMake 3.24 & smart downloading

Signed-off-by: Henry Schreiner <[email protected]>

* fix: a few mistakes

Signed-off-by: Henry Schreiner <[email protected]>

* style: pre-commit fixes

* Update tests.yml

* Update tests.yml

* style: pre-commit fixes

* Update tests.yml

* ci: split up win job

Signed-off-by: Henry Schreiner <[email protected]>

* fix: add features from setup.py to CMake

Signed-off-by: Henry Schreiner <[email protected]>

* Update dev-requirements.txt

* Update CMakeLists.txt

* fix: better build options

Signed-off-by: Henry Schreiner <[email protected]>

* ci: nicer setup

Signed-off-by: Henry Schreiner <[email protected]>

---------

Signed-off-by: Henry Schreiner <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
henryiii and pre-commit-ci[bot] authored Mar 31, 2024
1 parent c88b660 commit 64d41af
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 255 deletions.
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

0 comments on commit 64d41af

Please sign in to comment.