From 4036dac9e4359626a40cffb439052c74ed919579 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Sun, 20 Sep 2026 10:39:30 +1200 Subject: [PATCH 01/15] Create stable ABI wheels for distribution. --- .github/workflows/deploy-on-release.yml | 73 ++++++++++------------- CMakeLists.txt | 25 +++++++- cmake/environmentchecks.cmake | 13 +++- src/bindings/python/CMakeLists.txt | 13 ++-- src/bindings/python/cibuildwheel.setup.py | 1 - src/bindings/python/pyproject.toml | 44 ++++++++++++-- 6 files changed, 112 insertions(+), 57 deletions(-) diff --git a/.github/workflows/deploy-on-release.yml b/.github/workflows/deploy-on-release.yml index b17d440ce2..f8284ba8b6 100644 --- a/.github/workflows/deploy-on-release.yml +++ b/.github/workflows/deploy-on-release.yml @@ -275,33 +275,32 @@ jobs: wheels: needs: setup-jobs if: needs.setup-jobs.outputs.allowed-jobs == 'Wheels' || needs.setup-jobs.outputs.allowed-jobs == 'All' - name: ${{ matrix.name }} ${{ matrix.py }} wheel + name: ${{ matrix.name }} Stable ABI wheel runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [macos-15, ubuntu-24.04, ubuntu-24.04-arm, windows-2022, windows-11-arm] - py: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] + os: [macos-15, macos-15-intel, ubuntu-24.04, ubuntu-24.04-arm, windows-2025-vs2026, windows-11-arm] + py: ['3.14'] include: - - name: 'Windows' - os: windows-2022 - - name: 'Windows ARM' - os: windows-11-arm - name: 'Linux' - os: ubuntu-24.04-arm - - name: 'Linux ARM' os: ubuntu-24.04 + - name: 'LinuxARM' + os: ubuntu-24.04-arm - name: 'macOS' os: macos-15 - exclude: - - os: ubuntu-24.04 - py: '3.9' - - os: ubuntu-24.04-arm - py: '3.9' + - name: 'macOSintel' + os: macos-15-intel + - name: 'Windows' + os: windows-2025-vs2026 + arch: amd64 + - name: 'WindowsARM' + os: windows-11-arm + arch: arm64 steps: - name: Check out libCellML - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: ${{ github.event.release.tag_name }} @@ -309,52 +308,44 @@ jobs: id: setup shell: bash run: | - mkdir src/bindings/python/libcellml - cp src/bindings/python/README.rst src/bindings/python/libcellml/README.rst - mv src/bindings/python/cibuildwheel.setup.py src/bindings/python/setup.py + VERSION="${GITHUB_REF#refs/tags/v}" + echo "Setting version as: VERSION=${VERSION}" + if [[ "$OSTYPE" == darwin* ]]; then + sed -i '' "s/__VERSION__/${VERSION}/" src/bindings/python/pyproject.toml + else + sed -i "s/__VERSION__/${VERSION}/" src/bindings/python/pyproject.toml + fi + grep '^version' src/bindings/python/pyproject.toml + v=${{ matrix.py }} - echo "Setting tag as: tag=${GITHUB_REF#refs/tags/}" - echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT echo "Setting build as: build=cp${v/./}-*" echo "build=cp${v/./}-*" >> $GITHUB_OUTPUT - if [[ "macOS" == "${{ matrix.name }}" ]]; then - echo "Setting macos_archs as: macos_archs='x86_64 arm64'" - echo "macos_archs=x86_64 arm64" >> $GITHUB_OUTPUT - echo "macos_deployment_target=14.0" >> $GITHUB_OUTPUT - elif [[ "Windows" == "${{ matrix.name }}" ]]; then - echo "Setting win_arch as: win_arch=amd64" - echo "win_arch=amd64" >> $GITHUB_OUTPUT - elif [[ "Windows ARM" == "${{ matrix.name }}" ]]; then - echo "Setting win_arch as: win_arch=arm64" - echo "win_arch=arm64" >> $GITHUB_OUTPUT - fi - name: Configure MSVC (Windows) if: runner.os == 'Windows' uses: TheMrMilchmann/setup-msvc-dev@v4 with: - arch: x64 + arch: ${{ matrix.arch }} - name: Install SWIG (macOS) if: runner.os == 'macOS' run: brew install swig - name: Build wheels - uses: pypa/cibuildwheel@v3.4 + uses: pypa/cibuildwheel@v4.2 env: #CIBW_BUILD_VERBOSITY: 1 CIBW_ARCHS: auto64 - CIBW_ARCHS_MACOS: ${{ steps.setup.outputs.macos_archs }} CIBW_BUILD: ${{ steps.setup.outputs.build }} - CIBW_TEST_SKIP: "*_arm64" CIBW_BEFORE_ALL_LINUX: yum install -y libxml2-devel || (apk add libxml2-dev && rm /usr/lib/cmake/libxml2/libxml2-config.cmake) CIBW_ENVIRONMENT: > - LIBCELLML_VERSION_TAG=${{ steps.setup.outputs.tag }} - MACOSX_DEPLOYMENT_TARGET=${{ steps.setup.outputs.macos_deployment_target }} - CIBW_REPAIR_WHEEL_COMMAND_MACOS: "" + LIBCELLML_VERSION_TAG=${{ github.event.release.tag_name }} + MACOSX_DEPLOYMENT_TARGET=14.0 CIBW_BEFORE_BUILD_LINUX: pip install renamewheel - CIBW_BEFORE_BUILD_WINDOWS: call "%VSINSTALLDIR%\VC\Auxiliary\Build\vcvarsall.bat" ${{ steps.setup.outputs.win_arch }} && cd src/bindings/python && cmake -S wheel_dependencies -B build-wheel_dependencies -G Ninja && cd build-wheel_dependencies && ninja + CIBW_BEFORE_BUILD_WINDOWS: cd src/bindings/python && cmake -S wheel_dependencies -B build-wheel_dependencies -G Ninja && cd build-wheel_dependencies && ninja CIBW_REPAIR_WHEEL_COMMAND_LINUX: renamewheel -w {dest_dir} {wheel} + CIBW_REPAIR_WHEEL_COMMAND_MACOS: "" + CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "" with: output-dir: wheelhouse package-dir: src/bindings/python/ @@ -363,13 +354,13 @@ jobs: uses: actions/upload-artifact@v7 with: path: ./wheelhouse/*.whl - name: ${{ matrix.name }}-${{ matrix.py }}-wheel + name: ${{ matrix.name }}-wheel retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }} publish-wheels: if: needs.setup-jobs.outputs.binaries-destination == 'Publish' needs: wheels - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 5 # Docker+network are slow sometimes. permissions: id-token: write diff --git a/CMakeLists.txt b/CMakeLists.txt index 728e7416c1..7b8066d0a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.18.0) +cmake_minimum_required(VERSION 3.26.0) if(APPLE) set(CMAKE_OSX_DEPLOYMENT_TARGET 14.0 CACHE STRING "Minimum OS X deployment version.") @@ -32,6 +32,29 @@ foreach(NEW_POLICY ${NEW_POLICIES}) endif() endforeach() + +message(STATUS "----------------------------------------------") +message(STATUS "SKBUILD: ${SKBUILD}") +message(STATUS "Environment Variables: ${ENV}") +get_cmake_property(_vars VARIABLES) +foreach(_v ${_vars}) + if(_v MATCHES "^Python") + message(STATUS "${_v}=${${_v}}") + endif() +endforeach() +foreach(_v Interpreter Module SABIModule Python NumPy) + if (TARGET Python::${_v}) + message(STATUS "Python::${_v}=${Python::${_v}}") + endif() +endforeach() + +message(STATUS "Python_EXECUTABLE=${Python_EXECUTABLE}") +message(STATUS "Python_INCLUDE_DIRS=${Python_INCLUDE_DIRS}") +message(STATUS "Python_SABI_LIBRARIES=${Python_SABI_LIBRARIES}") + +message(STATUS "--------------------- 123 -------------------------") + + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(common) diff --git a/cmake/environmentchecks.cmake b/cmake/environmentchecks.cmake index 21ba618b5a..72b7aec537 100644 --- a/cmake/environmentchecks.cmake +++ b/cmake/environmentchecks.cmake @@ -35,7 +35,16 @@ else () test_undefined_symbols_allowed() - find_package(Python ${PREFERRED_PYTHON_VERSION} COMPONENTS Interpreter ${_FIND_PYTHON_DEVELOPMENT_TYPE}) + find_package(Python ${PREFERRED_PYTHON_VERSION} COMPONENTS Interpreter Development.SABIModule Development.Module) + + if (TARGET Python::SABIModule) + set(_PYTHON_LINK_TARGET Python::SABIModule) + elseif (TARGET Python::Module) + message(STATUS "Using backup Python::Module target for linking.") + set(_PYTHON_LINK_TARGET Python::Module) + else() + message(STATUS "Could not find Python::SABIModule or Python::Module target.") + endif() find_program(BUILDCACHE_EXE buildcache) if(NOT BUILDCACHE_EXE) @@ -152,7 +161,7 @@ if(SWIG_EXECUTABLE) set(BINDINGS_AVAILABLE TRUE CACHE INTERNAL "Executable required to generate bindings is available.") endif() -if(BINDINGS_AVAILABLE AND (Python_Development.Module_FOUND OR Python_Development_FOUND)) +if(BINDINGS_AVAILABLE AND (Python_Development.SABIModule_FOUND OR Python_Development_FOUND)) set(PYTHON_BINDINGS_AVAILABLE TRUE CACHE INTERNAL "Requirements for creating Python bindings are available.") endif() diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index d4f702aa58..42c3f39af7 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -83,6 +83,12 @@ if(MSVC) list(APPEND FINALISE_PYTHON_BINDINGS_ARGUMENTS -DTARGET_FILE_NAME_libxml2=${LIBXML2_DLL_NAMES}) endif() +# if(FIND_PYTHON_DEVELOPMENT_MODULE) +# set(_PYTHON_LINK_TARGET Python::Module) +# else() +# set(_PYTHON_LINK_TARGET Python::Python) +# endif() + set(SWIG_PYTHON_BINDINGS_TARGETS) # Create bindings for each interface file foreach(SWIG_INTERFACE_SRC ${SWIG_INTERFACE_SRCS}) @@ -94,17 +100,12 @@ foreach(SWIG_INTERFACE_SRC ${SWIG_INTERFACE_SRCS}) SOURCES ${SWIG_INTERFACE_SRC} ) target_link_libraries(${MODULE_TARGET} PRIVATE cellml) + target_compile_definitions(${MODULE_TARGET} PRIVATE Py_LIMITED_API=0x030a0000) if(SWIG_VERSION VERSION_GREATER_EQUAL 4.1.0) set_target_properties(${MODULE_TARGET} PROPERTIES SWIG_COMPILE_OPTIONS -flatstaticmethod) endif() - if(FIND_PYTHON_DEVELOPMENT_MODULE) - set(_PYTHON_LINK_TARGET Python::Module) - else() - set(_PYTHON_LINK_TARGET Python::Python) - endif() - if (APPLE) # Specifically allow dynamic lookup, here we are really targeting Python symbols. set_target_properties(${MODULE_TARGET} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") diff --git a/src/bindings/python/cibuildwheel.setup.py b/src/bindings/python/cibuildwheel.setup.py index a832d5e6be..52b9cebc84 100644 --- a/src/bindings/python/cibuildwheel.setup.py +++ b/src/bindings/python/cibuildwheel.setup.py @@ -8,7 +8,6 @@ Intended Audience :: Developers Intended Audience :: Education Intended Audience :: Science/Research -License :: OSI Approved :: Apache Software License Programming Language :: Python Operating System :: Microsoft :: Windows Operating System :: Unix diff --git a/src/bindings/python/pyproject.toml b/src/bindings/python/pyproject.toml index 22bf36b343..4a659763a7 100644 --- a/src/bindings/python/pyproject.toml +++ b/src/bindings/python/pyproject.toml @@ -1,10 +1,42 @@ [build-system] requires = [ - 'setuptools', - 'wheel', - 'scikit-build>=0.12', - 'cmake', - 'ninja', + "wheel", + "scikit-build-core", ] -build-backend = 'setuptools.build_meta' +build-backend = "scikit_build_core.build" +[project] +name = "libCellML" +version = "__VERSION__" +license = { text = "Apache-2.0" } +description = "libCellML a library for the creation, printing, parsing, and manipulation of CellML models." +authors = [{ name = "libCellML developers", email = "libcellml@googlegroups.com" }] +urls = { "homepage" = "https://libcellml.org" } +readme = { file = "README.rst", content-type = "text/x-rst" } +classifiers = [ + "Programming Language :: Python :: 3", + "Intended Audience :: Developers", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "Programming Language :: Python", + "Operating System :: Microsoft :: Windows", + "Operating System :: Unix", + "Operating System :: MacOS :: MacOS X", + "Topic :: Software Development :: Libraries :: Python Modules", +] + +[tool.scikit-build] +cmake.args = ["-DUNIT_TESTS=OFF", "-DCOVERAGE=OFF", "-DMEMCHECK=OFF", "-DLLVM_COVERAGE=OFF", "-DCLANG_TIDY=OFF"] +cmake.build-type = "Release" +cmake.source-dir = "../../.." +cmake.version = ">=3.26.1" +install.targets = ["install-wheel"] +ninja.version = ">=1.11" +wheel.py-api = "cp310" + +[[tool.scikit-build.overrides]] +if.platform-system = "^win32" +inherit.cmake.args = "append" +cmake.args = ["-DLibXml2_DIR=C:/Program Files (x86)/libxml2/libxml2-2.9.10/CMake/"] From 2b237332888e4c017f0011e2c59d6277ab8313ab Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Tue, 22 Sep 2026 11:02:49 +1200 Subject: [PATCH 02/15] Clean up CMake code. --- CMakeLists.txt | 23 ----------------------- src/bindings/python/CMakeLists.txt | 6 ------ 2 files changed, 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b8066d0a3..52cb7b5be5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,29 +32,6 @@ foreach(NEW_POLICY ${NEW_POLICIES}) endif() endforeach() - -message(STATUS "----------------------------------------------") -message(STATUS "SKBUILD: ${SKBUILD}") -message(STATUS "Environment Variables: ${ENV}") -get_cmake_property(_vars VARIABLES) -foreach(_v ${_vars}) - if(_v MATCHES "^Python") - message(STATUS "${_v}=${${_v}}") - endif() -endforeach() -foreach(_v Interpreter Module SABIModule Python NumPy) - if (TARGET Python::${_v}) - message(STATUS "Python::${_v}=${Python::${_v}}") - endif() -endforeach() - -message(STATUS "Python_EXECUTABLE=${Python_EXECUTABLE}") -message(STATUS "Python_INCLUDE_DIRS=${Python_INCLUDE_DIRS}") -message(STATUS "Python_SABI_LIBRARIES=${Python_SABI_LIBRARIES}") - -message(STATUS "--------------------- 123 -------------------------") - - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(common) diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 42c3f39af7..3e314d0203 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -83,12 +83,6 @@ if(MSVC) list(APPEND FINALISE_PYTHON_BINDINGS_ARGUMENTS -DTARGET_FILE_NAME_libxml2=${LIBXML2_DLL_NAMES}) endif() -# if(FIND_PYTHON_DEVELOPMENT_MODULE) -# set(_PYTHON_LINK_TARGET Python::Module) -# else() -# set(_PYTHON_LINK_TARGET Python::Python) -# endif() - set(SWIG_PYTHON_BINDINGS_TARGETS) # Create bindings for each interface file foreach(SWIG_INTERFACE_SRC ${SWIG_INTERFACE_SRCS}) From 3d9bab49c040f5862b1c32219c3cd71da1864af4 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Tue, 22 Sep 2026 11:03:06 +1200 Subject: [PATCH 03/15] Check for correct component of Python found. --- cmake/environmentchecks.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/environmentchecks.cmake b/cmake/environmentchecks.cmake index 72b7aec537..2771253910 100644 --- a/cmake/environmentchecks.cmake +++ b/cmake/environmentchecks.cmake @@ -161,7 +161,7 @@ if(SWIG_EXECUTABLE) set(BINDINGS_AVAILABLE TRUE CACHE INTERNAL "Executable required to generate bindings is available.") endif() -if(BINDINGS_AVAILABLE AND (Python_Development.SABIModule_FOUND OR Python_Development_FOUND)) +if(BINDINGS_AVAILABLE AND (Python_Development.SABIModule_FOUND OR Python_Development.Module_FOUND)) set(PYTHON_BINDINGS_AVAILABLE TRUE CACHE INTERNAL "Requirements for creating Python bindings are available.") endif() From 0557a2ba535123e893335bead3c4d404a28f951e Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Fri, 25 Sep 2026 23:01:48 +1200 Subject: [PATCH 04/15] Update labels for Python wheels step names in deploy workflow. --- .github/workflows/deploy-on-release.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-on-release.yml b/.github/workflows/deploy-on-release.yml index f8284ba8b6..b4689a958b 100644 --- a/.github/workflows/deploy-on-release.yml +++ b/.github/workflows/deploy-on-release.yml @@ -283,20 +283,20 @@ jobs: os: [macos-15, macos-15-intel, ubuntu-24.04, ubuntu-24.04-arm, windows-2025-vs2026, windows-11-arm] py: ['3.14'] include: - - name: 'Linux' - os: ubuntu-24.04 - name: 'LinuxARM' os: ubuntu-24.04-arm - - name: 'macOS' + - name: 'LinuxIntel' + os: ubuntu-24.04 + - name: 'macOSARM' os: macos-15 - - name: 'macOSintel' + - name: 'macOSIntel' os: macos-15-intel - - name: 'Windows' - os: windows-2025-vs2026 - arch: amd64 - name: 'WindowsARM' os: windows-11-arm arch: arm64 + - name: 'WindowsIntel' + os: windows-2025-vs2026 + arch: amd64 steps: - name: Check out libCellML From 9d1a901f6f32953a8cb5d3d7d6c6b711e3a64e31 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Wed, 30 Sep 2026 22:33:24 +1300 Subject: [PATCH 05/15] Delete src/bindings/python/cibuildwheel.setup.py --- src/bindings/python/cibuildwheel.setup.py | 48 ----------------------- 1 file changed, 48 deletions(-) delete mode 100644 src/bindings/python/cibuildwheel.setup.py diff --git a/src/bindings/python/cibuildwheel.setup.py b/src/bindings/python/cibuildwheel.setup.py deleted file mode 100644 index 52b9cebc84..0000000000 --- a/src/bindings/python/cibuildwheel.setup.py +++ /dev/null @@ -1,48 +0,0 @@ -""" libCellML Library: A library for the parsing, printing, and manipulation -of CellML 2.0 compliant models. - -""" - -classifiers = """\ -Development Status :: 5 - Production/Stable -Intended Audience :: Developers -Intended Audience :: Education -Intended Audience :: Science/Research -Programming Language :: Python -Operating System :: Microsoft :: Windows -Operating System :: Unix -Operating System :: MacOS :: MacOS X -Topic :: Software Development :: Libraries :: Python Modules -""" - -import os -import platform - -from skbuild import setup - -cmake_args = ["-DUNIT_TESTS=OFF", "-DCOVERAGE=OFF", "-DMEMCHECK=OFF", "-DLLVM_COVERAGE=OFF", "-DCLANG_TIDY=OFF"] - -if platform.system() == "Windows": - cmake_args.append("-DLibXml2_DIR=C:/Program Files (x86)/libxml2/libxml2-2.9.10/CMake/") - -doclines = __doc__.split("\n") - -tag = os.environ.get("LIBCELLML_VERSION_TAG", "v0.0.0") - -setup( - name="libcellml", - version=tag[1:], - description=doclines[0], - author="libCellML contributors", - url="https://libcellml.org", - license="Apache 2.0", - packages=["libcellml"], - classifiers=[cl for cl in classifiers.split("\n") if cl], - long_description=open('README.rst').read(), - long_description_content_type='text/x-rst', - include_package_data=True, - cmake_source_dir="../../../", - cmake_install_target="install-wheel", - cmake_args=cmake_args, - exclude_package_data={"": ["bin/*", "cmake/*", "include/*", "lib/*"]}, -) From 11c6683b9c75b205b4ef603d02d633f06a4ac0ff Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Wed, 30 Sep 2026 22:36:14 +1300 Subject: [PATCH 06/15] Update documenation to mention that 3.26 is the minimum version. --- docs/configure_and_build.rst | 2 +- docs/setup.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configure_and_build.rst b/docs/configure_and_build.rst index 7a8ba05408..da848da8b2 100644 --- a/docs/configure_and_build.rst +++ b/docs/configure_and_build.rst @@ -23,7 +23,7 @@ Configure with CMake The first step is to use :cmake:`CMake<>` to configure and generate build files for the libCellML library. Linux and MacOS use a command line interface, and under Windows there is an optional GUI. -Note that CMake version 3.2 or later is required to configure libCellML. +Note that CMake version 3.26 or later is required to configure libCellML. Instructions and information about installing CMake can be found in the :ref:`Setup ` section. diff --git a/docs/setup.rst b/docs/setup.rst index 2fa3190abe..3afcc45f19 100644 --- a/docs/setup.rst +++ b/docs/setup.rst @@ -59,7 +59,7 @@ CMake :cmake:`CMake<>` is the cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and to generate native makefiles and workspaces that can be used in the compiler environment of your choice. -Note that CMake version 3.2 or later is required to configure libCellML. +Note that CMake version 3.26 or later is required to configure libCellML. Again, installation of CMake is particular to each operating system. From aebc5ae8be6df6e099f9fa9b507a7ed702954eb9 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Fri, 2 Oct 2026 15:02:48 +1300 Subject: [PATCH 07/15] Only code to the stable API if the stable API module is found. --- src/bindings/python/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 3e314d0203..c8e73269c7 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -94,7 +94,9 @@ foreach(SWIG_INTERFACE_SRC ${SWIG_INTERFACE_SRCS}) SOURCES ${SWIG_INTERFACE_SRC} ) target_link_libraries(${MODULE_TARGET} PRIVATE cellml) - target_compile_definitions(${MODULE_TARGET} PRIVATE Py_LIMITED_API=0x030a0000) + if(Python_Development.SABIModule_FOUND) + target_compile_definitions(${MODULE_TARGET} PRIVATE Py_LIMITED_API=0x030a0000) + endif() if(SWIG_VERSION VERSION_GREATER_EQUAL 4.1.0) set_target_properties(${MODULE_TARGET} PROPERTIES SWIG_COMPILE_OPTIONS -flatstaticmethod) From f5c303ca7f16eb7aa4359bb3dd384cffc4e246ff Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Fri, 2 Oct 2026 15:22:56 +1300 Subject: [PATCH 08/15] Add a note in the versions documentation to inform developers about the catch of creating stable ABI wheels and older SWIGs. --- docs/versions.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/versions.rst b/docs/versions.rst index 4e6405929e..86dbed4aca 100644 --- a/docs/versions.rst +++ b/docs/versions.rst @@ -6,8 +6,7 @@ Dependency versions and compatibility This document outlines the versions of packages which libCellML requires. -**TODO** - - - +It is prefereable to use SWIG version 4.4.0 or later, but it is possible to use SWIG version 3.0.12 if necessary. +This is only relevant if creating the Python bindings for libCellML against the stable API using a Python version less than 3.15 and you intend to use it with a Python version of at least 3.15. +**TODO** From 1eb3e01d5834f1e5535e1b0b933e30f89d66c3c9 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Fri, 2 Oct 2026 15:33:08 +1300 Subject: [PATCH 09/15] Fix typo in preferable. --- docs/versions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/versions.rst b/docs/versions.rst index 86dbed4aca..005d28abbf 100644 --- a/docs/versions.rst +++ b/docs/versions.rst @@ -6,7 +6,7 @@ Dependency versions and compatibility This document outlines the versions of packages which libCellML requires. -It is prefereable to use SWIG version 4.4.0 or later, but it is possible to use SWIG version 3.0.12 if necessary. +It is preferable to use SWIG version 4.4.0 or later, but it is possible to use SWIG version 3.0.12 if necessary. This is only relevant if creating the Python bindings for libCellML against the stable API using a Python version less than 3.15 and you intend to use it with a Python version of at least 3.15. **TODO** From 3dcb35a0da5d0b368379041f558045b4add091d6 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Fri, 2 Oct 2026 15:43:33 +1300 Subject: [PATCH 10/15] Clarify SWIG version in versions.rst. --- docs/versions.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/versions.rst b/docs/versions.rst index 005d28abbf..ec179ed6d2 100644 --- a/docs/versions.rst +++ b/docs/versions.rst @@ -4,9 +4,9 @@ Dependency versions and compatibility ===================================== -This document outlines the versions of packages which libCellML requires. +This document outlines the versions of packages which libCellML requires. -It is preferable to use SWIG version 4.4.0 or later, but it is possible to use SWIG version 3.0.12 if necessary. -This is only relevant if creating the Python bindings for libCellML against the stable API using a Python version less than 3.15 and you intend to use it with a Python version of at least 3.15. +SWIG version 4.4.0 or later is required when generating stable-ABI Python bindings intended for Python 3.15 or later. +SWIG version 3.0.12 remains supported for bindings that only target Python versions before 3.15. **TODO** From 817b04b9cccdc26146da2cc70740834d3104499e Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Mon, 5 Oct 2026 19:13:23 +1300 Subject: [PATCH 11/15] Make SWIG version 4 the minimum required SWIG. --- cmake/environmentchecks.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/environmentchecks.cmake b/cmake/environmentchecks.cmake index 2771253910..f11434f85f 100644 --- a/cmake/environmentchecks.cmake +++ b/cmake/environmentchecks.cmake @@ -82,7 +82,7 @@ else () find_package(Doxygen) find_package(Sphinx) - find_package(SWIG 3) + find_package(SWIG 4) set(_ORIGINAL_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) From 584b8f8780e3f2a71e211086e74e402f21f9d03f Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Mon, 5 Oct 2026 19:21:24 +1300 Subject: [PATCH 12/15] Update versions.rst with SWIG version supported. --- docs/versions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/versions.rst b/docs/versions.rst index ec179ed6d2..92a960e27c 100644 --- a/docs/versions.rst +++ b/docs/versions.rst @@ -7,6 +7,6 @@ Dependency versions and compatibility This document outlines the versions of packages which libCellML requires. SWIG version 4.4.0 or later is required when generating stable-ABI Python bindings intended for Python 3.15 or later. -SWIG version 3.0.12 remains supported for bindings that only target Python versions before 3.15. +SWIG version 4 remains supported for developers who are only targetting the Python version the bindings were compiled against. **TODO** From dca289ce98a9f0a9d496060d47c3489d20f7d38a Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Mon, 5 Oct 2026 19:27:13 +1300 Subject: [PATCH 13/15] Fix typo in versions.rst. --- docs/versions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/versions.rst b/docs/versions.rst index 92a960e27c..0402980980 100644 --- a/docs/versions.rst +++ b/docs/versions.rst @@ -7,6 +7,6 @@ Dependency versions and compatibility This document outlines the versions of packages which libCellML requires. SWIG version 4.4.0 or later is required when generating stable-ABI Python bindings intended for Python 3.15 or later. -SWIG version 4 remains supported for developers who are only targetting the Python version the bindings were compiled against. +SWIG version 4 remains supported for developers who are only targeting the Python version the bindings were compiled against. **TODO** From 43cc1a53f03530357497f46716ef3bc64dca8e81 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Mon, 12 Oct 2026 14:24:15 +1300 Subject: [PATCH 14/15] Update web assembly documentation to match build CMake version. --- docs/dev_building_web_assembly.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev_building_web_assembly.rst b/docs/dev_building_web_assembly.rst index 463ba84495..4222dee812 100644 --- a/docs/dev_building_web_assembly.rst +++ b/docs/dev_building_web_assembly.rst @@ -15,7 +15,7 @@ To build *libCellML* for the browser, we will need the following tools ready for - Emscripten - Compiler toolchain -- CMake (at least version 3.14) +- CMake (at least version 3.26) - Git Building From b7ec72ffba135c52eedbb203c895c0fd0becdaeb Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Tue, 13 Oct 2026 21:31:02 +1300 Subject: [PATCH 15/15] Simplify Python development checks in CMake Removed conditional checks for Python development type based on CMake version and system name. --- cmake/environmentchecks.cmake | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cmake/environmentchecks.cmake b/cmake/environmentchecks.cmake index f11434f85f..a508a1b283 100644 --- a/cmake/environmentchecks.cmake +++ b/cmake/environmentchecks.cmake @@ -26,13 +26,6 @@ if (EMSCRIPTEN) find_program(NODE_EXE NAMES ${PREFERRED_NODE_NAMES} node) find_program(NPM_EXE NAMES ${PREFERRED_NPM_NAMES} npm) else () - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18 AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(_FIND_PYTHON_DEVELOPMENT_TYPE Development.Module) - set(FIND_PYTHON_DEVELOPMENT_MODULE TRUE) - else() - set(_FIND_PYTHON_DEVELOPMENT_TYPE Development) - endif() - test_undefined_symbols_allowed() find_package(Python ${PREFERRED_PYTHON_VERSION} COMPONENTS Interpreter Development.SABIModule Development.Module)