diff --git a/CMakeLists.txt b/CMakeLists.txt index a45a768d..67c78641 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,13 +151,25 @@ endif() if(heyoka_WITH_REAL AND ${Python3_NumPy_VERSION} LESS 1.22) message(FATAL_ERROR "The minimum version of NumPy required for supporting arbitrary-precision computations is 1.22, but version ${Python3_NumPy_VERSION} was found instead") endif() -# Extract the major.minor version of NumPy for use in the wheel configuration. -string(REGEX MATCH "([0-9]+)\.([0-9]+)" _HEYOKA_PY_NPY_MAJOR_MINOR ${Python3_NumPy_VERSION}) -message(STATUS "NumPy major.minor version: ${_HEYOKA_PY_NPY_MAJOR_MINOR}") +# NOTE: NumPy 2 not supported yet if we are building with support +# for mppp::real or mppp::real128. +if((heyoka_WITH_REAL OR heyoka_WITH_REAL128) AND ${Python3_NumPy_VERSION} VERSION_GREATER_EQUAL 2) + message(FATAL_ERROR "NumPy 2 is not supported when building with support for quadruple-precision or arbitrary-precision computations") +endif() +message(STATUS "NumPy version: ${Python3_NumPy_VERSION}") +unset(_HEYOKA_PY_PYTHON3_COMPONENTS) + +if (DEFINED SKBUILD) + # If we're using scikit-build-core, set install path to the current + # directory since skbuild will be handling the installation. + set(HEYOKA_PY_INSTALL_PATH "." CACHE STRING "heyoka module installation path") -set(HEYOKA_PY_INSTALL_PATH "" CACHE STRING "heyoka module installation path") + # Also ensure shared libraries can be found in RPATH. + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) +else() + set(HEYOKA_PY_INSTALL_PATH "" CACHE STRING "heyoka module installation path") +endif() mark_as_advanced(HEYOKA_PY_INSTALL_PATH) -unset(_HEYOKA_PY_PYTHON3_COMPONENTS) # pybind11. find_package(pybind11 REQUIRED CONFIG) @@ -194,6 +206,3 @@ endif() # Add the module directory. add_subdirectory(heyoka) - -# Cleanup. -unset(_HEYOKA_PY_NPY_MAJOR_MINOR) diff --git a/doc/changelog.rst b/doc/changelog.rst index 6ec87c48..7ecd3ae9 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -6,9 +6,18 @@ Changelog 6.1.0 (unreleased) ------------------ +New +~~~ + +- Add a proper ``pyproject.toml`` file and use it to produce + the binary wheels + (`#195 `__). + Fix ~~~ +- Do not open the heyoka.py compiled module with ``RTLD_GLOBAL`` + (`#197 `__). - Workaround for a clang 17 issue that would result in runtime exceptions during (de)serialisation (`#196 `__). diff --git a/heyoka/CMakeLists.txt b/heyoka/CMakeLists.txt index 997e787c..4fb3d530 100644 --- a/heyoka/CMakeLists.txt +++ b/heyoka/CMakeLists.txt @@ -1,13 +1,6 @@ # Configure the version file. configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_version.py.in" "${CMAKE_CURRENT_BINARY_DIR}/_version.py" @ONLY) -# Configure the files needed to make the python wheels (for PyPI packages). -if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - message(STATUS "Creating the files for the generation of a binary wheel.") - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../tools/wheel_setup.py" "${CMAKE_CURRENT_BINARY_DIR}/../wheel/setup.py" @ONLY) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../tools/wheel_setup.cfg" "${CMAKE_CURRENT_BINARY_DIR}/../wheel/setup.cfg" @ONLY) -endif() - # The list of heyoka.py's Python files. set(HEYOKA_PY_PYTHON_FILES __init__.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..8a4c096a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,46 @@ +[build-system] +build-backend = 'scikit_build_core.build' +requires = ['scikit-build-core', 'numpy >= 1.22, < 2'] + +[project] +name = 'heyoka' +version = '6.1.0' +description = "Python library for ODE integration via Taylor's method and LLVM" +readme = 'README.md' +requires-python = '>=3.5' +dependencies = ['cloudpickle', 'numpy >= 1.22, < 2'] +authors = [ + { name = 'Francesco Biscarni', email = 'bluescarni@gmail.com' }, + { name = 'Dario Izzo' }, +] +license = { text = 'MPL-2.0' } +classifiers = [ + # How mature is this project? Common values are + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + "Development Status :: 5 - Production/Stable", + "Operating System :: OS Independent", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Physics", + "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", + "Programming Language :: Python :: 3", +] +keywords = ['science', 'math', 'physics', 'ode'] + +[project.urls] +Documentation = "https://bluescarni.github.io/heyoka.py/index.html" +Repository = "https://github.com/bluescarni/heyoka.py" + +[project.optional-dependencies] +sympy = ["sympy", "mpmath"] +sgp4 = ["skyfield"] + +[tool.scikit-build] +# Avoid copying the C++ source files when building +# binary wheels. +wheel.packages = [] +# Enable IPO. +cmake.define.HEYOKA_PY_ENABLE_IPO = "ON" diff --git a/tools/gha_manylinux.sh b/tools/gha_manylinux.sh index 91e9a59a..53f53a03 100644 --- a/tools/gha_manylinux.sh +++ b/tools/gha_manylinux.sh @@ -15,7 +15,7 @@ git config --global --add safe.directory ${GITHUB_WORKSPACE} BRANCH_NAME=`git rev-parse --abbrev-ref HEAD` echo "BRANCH_NAME: ${BRANCH_NAME}" -# Read for what python wheels have to be built. +# Detect the Python version. if [[ ${HEYOKA_PY_BUILD_TYPE} == *38* ]]; then PYTHON_DIR="cp38-cp38" elif [[ ${HEYOKA_PY_BUILD_TYPE} == *39* ]]; then @@ -33,16 +33,9 @@ else exit 1 fi -# Report the inferred directory whwere python is found. +# Report the inferred directory where python is found. echo "PYTHON_DIR: ${PYTHON_DIR}" -# The numpy version heyoka.py will be built against. -if [[ ${HEYOKA_PY_BUILD_TYPE} == *312* || ${HEYOKA_PY_BUILD_TYPE} == *313* ]]; then - export NUMPY_VERSION="1.26.*" -else - export NUMPY_VERSION="1.24.*" -fi - # The heyoka version to be used for releases. export HEYOKA_VERSION_RELEASE="6.1.0" @@ -54,15 +47,7 @@ else echo "Non-tag build detected" fi -# Python mandatory deps. -# NOTE: explicit installation of setuptools is apparently -# needed in Python 3.13. -/opt/python/${PYTHON_DIR}/bin/pip install numpy==${NUMPY_VERSION} cloudpickle setuptools -# Python optional deps. -/opt/python/${PYTHON_DIR}/bin/pip install sympy mpmath skyfield - -# In the pagmo2/manylinux2014_x86_64_with_deps:latest image in dockerhub -# the working directory is /root/install, we will install heyoka there. +# In the manylinux image in dockerhub the working directory is /root/install, we will install heyoka there. cd /root/install # Install heyoka. @@ -85,30 +70,19 @@ cmake -DHEYOKA_WITH_MPPP=yes \ -DCMAKE_BUILD_TYPE=Release ../; make -j4 install -# Install heyoka.py. +# Build the heyoka.py wheel. cd ${GITHUB_WORKSPACE} -mkdir build -cd build -cmake -DCMAKE_BUILD_TYPE=Release \ - -DHEYOKA_PY_ENABLE_IPO=ON \ - -DPython3_EXECUTABLE=/opt/python/${PYTHON_DIR}/bin/python ../; -make -j4 install - -# Making the wheel and installing it -cd wheel -# Move the installed heyoka.py files into the current dir. -mv `/opt/python/${PYTHON_DIR}/bin/python -c 'import site; print(site.getsitepackages()[0])'`/heyoka ./ -# Create the wheel and repair it. +/opt/python/${PYTHON_DIR}/bin/pip wheel . -v +# Repair it. # NOTE: this is temporary because some libraries in the docker # image are installed in lib64 rather than lib and they are # not picked up properly by the linker. export LD_LIBRARY_PATH="/usr/local/lib64:/usr/local/lib" -/opt/python/${PYTHON_DIR}/bin/python setup.py bdist_wheel -auditwheel repair dist/heyoka* -w ./dist2 +auditwheel repair ./heyoka*.whl -w ./repaired_wheel # Try to install it and run the tests. unset LD_LIBRARY_PATH cd / -/opt/python/${PYTHON_DIR}/bin/pip install ${GITHUB_WORKSPACE}/build/wheel/dist2/heyoka* +/opt/python/${PYTHON_DIR}/bin/pip install ${GITHUB_WORKSPACE}/repaired_wheel/heyoka* cd ${GITHUB_WORKSPACE}/tools /opt/python/${PYTHON_DIR}/bin/python ci_test_runner.py cd / diff --git a/tools/wheel_setup.cfg b/tools/wheel_setup.cfg deleted file mode 100644 index 9b3e1739..00000000 --- a/tools/wheel_setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[install] -install_lib= diff --git a/tools/wheel_setup.py b/tools/wheel_setup.py deleted file mode 100644 index a9e35366..00000000 --- a/tools/wheel_setup.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -from setuptools import setup -from setuptools.dist import Distribution -import sys - -NAME = "heyoka" -VERSION = "@heyoka.py_VERSION@" -DESCRIPTION = "Python library for ODE integration via Taylor's method and LLVM" -LONG_DESCRIPTION = "heyoka is a Python library for the integration of ordinary differential equations (ODEs) via Taylor's method, based on automatic differentiation techniques and aggressive just-in-time compilation via LLVM." -URL = "https://github.com/bluescarni/heyoka.py" -AUTHOR = "Francesco Biscani, Dario Izzo" -AUTHOR_EMAIL = "bluescarni@gmail.com" -LICENSE = "MPL-2.0" -CLASSIFIERS = [ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - "Development Status :: 5 - Production/Stable", - "Operating System :: OS Independent", - "Intended Audience :: Science/Research", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Scientific/Engineering :: Physics", - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", - "Programming Language :: Python :: 3", -] -KEYWORDS = "science math physics ode" -INSTALL_REQUIRES = ["numpy==@_HEYOKA_PY_NPY_MAJOR_MINOR@.*", "cloudpickle"] -PLATFORMS = ["Unix"] - - -class BinaryDistribution(Distribution): - def has_ext_modules(foo): - return True - - -setup( - name=NAME, - version=VERSION, - description=DESCRIPTION, - long_description=LONG_DESCRIPTION, - url=URL, - author=AUTHOR, - author_email=AUTHOR_EMAIL, - license=LICENSE, - classifiers=CLASSIFIERS, - keywords=KEYWORDS, - platforms=PLATFORMS, - install_requires=INSTALL_REQUIRES, - packages=["heyoka", "heyoka.model", "heyoka.callback"], - # Include pre-compiled extension - package_data={"heyoka": [f for f in os.listdir("heyoka/") if f.endswith(".so")]}, - distclass=BinaryDistribution, -)