From 94c957c7d2f362ec26a51497418ca332a83235e6 Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Fri, 9 Feb 2024 16:06:00 +0100 Subject: [PATCH 01/10] WIP: use scikit-build-core --- pyproject.toml | 39 +++++++++-- setup.cfg | 24 ------- setup.py | 130 ------------------------------------ src/CMakeLists.txt | 7 ++ src/PROPOSAL/CMakeLists.txt | 2 - 5 files changed, 40 insertions(+), 162 deletions(-) delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml index 246260a6c..00ac403d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,35 @@ [build-system] -requires = [ - "setuptools>=45", - "wheel", - "cmake>=3.16", - "conan>=2.0.0", +requires = ["scikit-build-core[pyproject]", "pybind11", "setuptools_scm[toml]"] +build-backend = "scikit_build_core.build" + +[project] +name = "proposal" +version = "7.6.3" +description = "Python bindings for PROPOSAL" +readme = "README.md" +requires-pyton = ">= 3.9" +license = {text = "BSD-3-Clause"} +maintainers = [ + {name = "Jean-Marco Alamedine", email = "jean-marco.alameddine@tu-dortmund.de"}, +] + +[project.urls] +repository = "https://github.com/tudo-astroparticlephysics/PROPOSAL" + + +[project.optional-dependencies] +tests = [ + "pytest", +] + +all = ["proposal[tests]"] + + +[tool.scikit-build] +sdist.cmake = true +cmake.targets = ["pyPROPOSAL"] +cmake.args = [ + "-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON", + "-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=ON", + "-DBUILD_PYTHON=ON", ] -build-backend = "setuptools.build_meta" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 6816e5362..000000000 --- a/setup.cfg +++ /dev/null @@ -1,24 +0,0 @@ -[metadata] -name = proposal -url = https://github.com/tudo-astroparticlephysics/PROPOSAL -author = PROPOSAL Development Team -author_email = jean-marco.alameddine@tu-dortmund.de -classifiers= - Intended Audience :: Science/Research - License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Physics - Development Status :: 5 - Production/Stable - -license = LGPLv3 -description = Monte Carlo simulation library to propagate leptons and gamma rays -long_description = file: README.md -long_description_content_type = text/markdown; charset=UTF-8 -platforms = unix diff --git a/setup.py b/setup.py deleted file mode 100644 index 0442b61f6..000000000 --- a/setup.py +++ /dev/null @@ -1,130 +0,0 @@ -# see https://stackoverflow.com/a/48015772/3838691 -import os -import sys -import sysconfig -import pathlib -import subprocess as sp -import re - -from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext - - -SETUP_DIR = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(SETUP_DIR, "CMakeLists.txt")) as f: - f_read = f.read() - res = re.search(r"PROPOSAL_VERSION_MAJOR (\d)", f_read) - v_major = res.group(1) - res = re.search(r"PROPOSAL_VERSION_MINOR (\d)", f_read) - v_minor = res.group(1) - res = re.search(r"PROPOSAL_VERSION_PATCH (\d)", f_read) - v_patch = res.group(1) - version = v_major + "." + v_minor + "." + v_patch - - -def get_cmake(): - """ On centos 7, cmake is cmake 2.x but we need > 3.8""" - for exe in ["cmake3", "cmake"]: - try: - ret = sp.run([exe, "--version"], stdout=sp.PIPE, stderr=sp.PIPE) - except Exception: - continue - - if ret.returncode == 0: - return exe - raise OSError("You need cmake >= 3.23") - -def exists_conan_default_file(): - profiles = sp.check_output(["conan", "profile", "list"], encoding="UTF-8").split() - if "default" in profiles: - return True - return False - -def create_conan_profile(): - cmd = ["conan", "profile", "detect"] - r = sp.run(cmd) - if r.returncode != 0: - raise RuntimeError( - "conan was not able to create a new default profile." - ) - - -class CMakeExtension(Extension): - def __init__(self, name, source_dir=None, target=None, **kwargs): - if source_dir is None: - self.source_dir = SETUP_DIR - else: - self.source_dir = os.path.join(SETUP_DIR, source_dir) - self.target = target - # don't invoke the original build_ext for this special extension - super().__init__(name, sources=[], **kwargs) - - -class build_ext_cmake(build_ext): - def run(self): - for ext in self.extensions: - self.build_cmake(ext) - - def build_cmake(self, ext): - extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) - if not extdir.endswith(os.path.sep): - extdir += os.path.sep - - for d in (self.build_temp, extdir): - os.makedirs(d, exist_ok=True) - - cfg = 'Debug' if self.debug else 'Release' - cmake = get_cmake() - - rpath = '@loader_path' if sys.platform == 'darwin' else '$ORIGIN' - if not os.getenv("NO_CONAN", False): - print( - "Using conan to install dependencies. Set environment variable NO_CONAN to skip conan." - ) - - if not exists_conan_default_file(): - create_conan_profile() - - conan_call = [ - 'conan', - 'install', - ext.source_dir, - '-o with_python=True', - '-o with_testing=False', - '--build=missing' - ] - sp.run(conan_call, cwd=self.build_temp, check=True) - cmake_call = [ - cmake, - - ext.source_dir, - '-DCMAKE_TOOLCHAIN_FILE={}/build/conan_toolchain.cmake'.format(ext.source_dir), - '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, - '-DCMAKE_BUILD_TYPE=' + cfg, - '-DPython_EXECUTABLE=' + sys.executable, - '-DCMAKE_INSTALL_RPATH={}'.format(rpath), - '-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON', - '-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=OFF', - ] - sp.run(cmake_call, cwd=self.build_temp, check=True) - build_call = [ - cmake, - '--build', '.', - '--config', cfg, - '--', '-j{}'.format(os.getenv('BUILD_CORES', 2)) - ] - if ext.target is not None: - build_call.extend(['--target', ext.target]) - sp.run(build_call, cwd=self.build_temp, check=True) - - -setup( - version=version, - ext_modules=[ - CMakeExtension('proposal'), - ], - cmdclass={ - 'build_ext': build_ext_cmake, - }, - zip_safe=False, -) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c03c96fc6..c3d64969c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,10 @@ +include(GNUInstallDirs) + +if(SKBUILD) + message(STATUS "SKBUILD") + set(CMAKE_INSTALL_LIBDIR ".") + set(CMAKE_INSTALL_INCLUDEDIR "proposal/include") +endif() add_subdirectory(PROPOSAL) if(BUILD_PYTHON) diff --git a/src/PROPOSAL/CMakeLists.txt b/src/PROPOSAL/CMakeLists.txt index 10cae9a9d..718a339a9 100644 --- a/src/PROPOSAL/CMakeLists.txt +++ b/src/PROPOSAL/CMakeLists.txt @@ -1,5 +1,3 @@ -include(GNUInstallDirs) - add_library(PROPOSAL) add_library(PROPOSAL::PROPOSAL ALIAS PROPOSAL) From bced3e0820226b9aa00a71d2f1261c7243a150af Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Fri, 9 Feb 2024 16:18:12 +0100 Subject: [PATCH 02/10] Call conan in ci --- .github/workflows/python.yml | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 790f62f56..45c0e2e81 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,6 +1,15 @@ name: Check 🐍 pkg PROPOSAL. -on: [push] +on: + push: + branches: + - main + tags: + - "**" + pull_request: + +env: + CMAKE_TOOLCHAIN_FILE: build/conan_toolchain.cmake jobs: build: @@ -10,6 +19,7 @@ jobs: include: - os : "ubuntu-latest" - os : "macos-latest" + steps: - uses: actions/checkout@v4 - name: Cache conan @@ -19,10 +29,15 @@ jobs: path: ~/.conan key: ${{ runner.os }}-cache-conan-${{ matrix.compiler }}-${{ hashFiles('conanfile.py') }}-key - name: Install conan - run: python3 -m pip install --break-system-packages conan + run: | + python3 -m pip install conan + conan profile detect + + - name: Install C++ dependencies using conan + run: conan install . -o with_python=True -o with_testing=False --build=missing + - name: Install Python 🐍 distributions 📦 - run: python3 -m pip install --break-system-packages . - - name: Install pytest - run: python3 -m pip install --break-system-packages pytest + run: python3 -m pip install .[tests] + - name: run pytest run: python3 -m pytest tests/python -v From 10000b47684e9d229fe14ab3429a5aa660020fac Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 08:20:54 +0100 Subject: [PATCH 03/10] Use setup-python step --- .github/workflows/python.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 45c0e2e81..b20a52e99 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -21,23 +21,26 @@ jobs: - os : "macos-latest" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: "3.12" - name: Cache conan id: cache-conan - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.conan key: ${{ runner.os }}-cache-conan-${{ matrix.compiler }}-${{ hashFiles('conanfile.py') }}-key - name: Install conan run: | - python3 -m pip install conan + python -m pip install conan conan profile detect - name: Install C++ dependencies using conan run: conan install . -o with_python=True -o with_testing=False --build=missing - name: Install Python 🐍 distributions 📦 - run: python3 -m pip install .[tests] + run: python -m pip install .[tests] - name: run pytest - run: python3 -m pytest tests/python -v + run: python -m pytest tests/python -v From bfe1aab887c1b0863bf18262e771e2a348e38567 Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 08:25:32 +0100 Subject: [PATCH 04/10] Fix key in pyproject --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 00ac403d2..2a637320a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "proposal" version = "7.6.3" description = "Python bindings for PROPOSAL" readme = "README.md" -requires-pyton = ">= 3.9" +requires-python = ">= 3.9" license = {text = "BSD-3-Clause"} maintainers = [ {name = "Jean-Marco Alamedine", email = "jean-marco.alameddine@tu-dortmund.de"}, From 80f923c78476b33ee5b1db5de4ff176ba3b9e8ea Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 08:28:36 +0100 Subject: [PATCH 05/10] Update cmake version range --- CMakeLists.txt | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cbda47094..6f6b39ab2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.17...3.31) set(PROPOSAL_VERSION_MAJOR 7) set(PROPOSAL_VERSION_MINOR 6) diff --git a/pyproject.toml b/pyproject.toml index 2a637320a..5bf0d9054 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ all = ["proposal[tests]"] [tool.scikit-build] sdist.cmake = true -cmake.targets = ["pyPROPOSAL"] +build.targets = ["pyPROPOSAL"] cmake.args = [ "-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON", "-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=ON", From e6bcfe7aaa0bd6449fb35abc545b913346d45097 Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 08:32:56 +0100 Subject: [PATCH 06/10] Adjust cmake version range in pyproposal --- src/pyPROPOSAL/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyPROPOSAL/CMakeLists.txt b/src/pyPROPOSAL/CMakeLists.txt index b0f95cd6d..7cbea25cb 100644 --- a/src/pyPROPOSAL/CMakeLists.txt +++ b/src/pyPROPOSAL/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.17...3.31) project(pyPROPOSAL LANGUAGES CXX) From 2b0f616ec38916aa3548a9057989764889be5d90 Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 08:50:14 +0100 Subject: [PATCH 07/10] WIP: Skip installing files if empty --- src/PROPOSAL/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PROPOSAL/CMakeLists.txt b/src/PROPOSAL/CMakeLists.txt index 718a339a9..dfc52e4c5 100644 --- a/src/PROPOSAL/CMakeLists.txt +++ b/src/PROPOSAL/CMakeLists.txt @@ -58,4 +58,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PROPOSALConfig.cmake ) file(GLOB CMAKE_FILES "${CMAKE_BINARY_DIR}/*.cmake") -install(FILES ${CMAKE_FILES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PROPOSAL) +message(STATUS "CMAKE_FILES=${CMAKE_FILES}") +if(${CMAKE_FILES}) + install(FILES ${CMAKE_FILES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PROPOSAL) +endif() From 01056e9c2b71dba53a9b77d1d03e70e18ee3869b Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 14:12:58 +0100 Subject: [PATCH 08/10] Add conda based tests --- .github/workflows/python.yml | 86 ++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index b20a52e99..046a45c9a 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -12,35 +12,57 @@ env: CMAKE_TOOLCHAIN_FILE: build/conan_toolchain.cmake jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - include: - - os : "ubuntu-latest" - - os : "macos-latest" - - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - name: Cache conan - id: cache-conan - uses: actions/cache@v5 - with: - path: ~/.conan - key: ${{ runner.os }}-cache-conan-${{ matrix.compiler }}-${{ hashFiles('conanfile.py') }}-key - - name: Install conan - run: | - python -m pip install conan - conan profile detect - - - name: Install C++ dependencies using conan - run: conan install . -o with_python=True -o with_testing=False --build=missing - - - name: Install Python 🐍 distributions 📦 - run: python -m pip install .[tests] - - - name: run pytest - run: python -m pytest tests/python -v + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: "ubuntu-latest" + install: pip + - os: "ubuntu-latest" + install: conda + - os: "macos-latest" + install: pip + - os: "macos-latest" + install: conda + + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-python@v6 + if: matrix.install == 'pip' + with: + python-version: "3.12" + + - name: mamba setup + if: matrix.install == 'conda' + uses: mamba-org/setup-micromamba@v3 + with: + init-shell: bash + environment-name: ci + create-args: >- + python=3.12 + pip + pytest + cache-downloads: true + + - name: Cache conan + id: cache-conan + uses: actions/cache@v5 + with: + path: ~/.conan + key: ${{ runner.os }}-cache-conan-${{ matrix.compiler }}-${{ hashFiles('conanfile.py') }}-key + + - name: Install conan + run: | + python -m pip install conan + conan profile detect + + - name: Install C++ dependencies using conan + run: conan install . -o with_python=True -o with_testing=False --build=missing + + - name: Install Python 🐍 distributions 📦 + run: python -m pip install -v ".[tests]" + + - name: run pytest + run: python -m pytest tests/python -v From b87a9e97ee23bade0a17399b2197c4a29dec09df Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 14:16:05 +0100 Subject: [PATCH 09/10] Only look for Development.Module for python --- src/pyPROPOSAL/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pyPROPOSAL/CMakeLists.txt b/src/pyPROPOSAL/CMakeLists.txt index 7cbea25cb..74054880f 100644 --- a/src/pyPROPOSAL/CMakeLists.txt +++ b/src/pyPROPOSAL/CMakeLists.txt @@ -2,13 +2,12 @@ cmake_minimum_required(VERSION 3.17...3.31) project(pyPROPOSAL LANGUAGES CXX) -find_package(Python COMPONENTS Interpreter Development REQUIRED) +find_package(Python COMPONENTS Interpreter Development.Module REQUIRED) find_package(pybind11 REQUIRED) file(GLOB_RECURSE PYTHON_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cxx) -pybind11_add_module(pyPROPOSAL SHARED - ${PYTHON_SRC_FILES}) +pybind11_add_module(pyPROPOSAL MODULE ${PYTHON_SRC_FILES}) set_target_properties(pyPROPOSAL PROPERTIES OUTPUT_NAME proposal) From dd027a14574c8fe6cce5d22e4aa835f77b9c8d52 Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 19 May 2026 14:29:21 +0100 Subject: [PATCH 10/10] Set shell for ci steps --- .github/workflows/python.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 046a45c9a..a3ca2e545 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -14,6 +14,12 @@ env: jobs: build: runs-on: ${{ matrix.os }} + + defaults: + run: + # We need login shells (-l) for micromamba to work. + shell: bash -leo pipefail {0} + strategy: matrix: include: