From 42054cd9093790abcc5616e8ad33a87bf203db04 Mon Sep 17 00:00:00 2001 From: Duc Le Date: Mon, 29 Dec 2025 18:16:21 +0000 Subject: [PATCH 1/3] Update for pyodide (WIP) --- .github/workflows/build_python.yml | 10 +++++----- .gitignore | 3 +++ CMakeLists.txt | 24 ++++++++++++++++++++---- setup.py | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_python.yml b/.github/workflows/build_python.yml index be281719..3716e670 100644 --- a/.github/workflows/build_python.yml +++ b/.github/workflows/build_python.yml @@ -34,17 +34,17 @@ jobs: cache-downloads: true - name: Build wheels run: | - $MAMBA_EXE create -n cibuildwheel python=3.12 + $MAMBA_EXE create -n cibuildwheel python=3.13 eigen pybind11 eval "$($MAMBA_EXE shell activate cibuildwheel)" python -m pip install cibuildwheel if [[ $OSTYPE == "darwin23" ]] || [[ $OSTYPE == "darwin22" ]] then # For some reason cibuildwheel on builds 3.9-3.12 arm64 on macos-latest - export CIBW_BUILD="cp39* cp310* cp311* cp312*" + export CIBW_BUILD="cp310* cp311* cp312*" fi python -m cibuildwheel --output-dir wheelhouse env: - CIBW_BUILD: "cp38-* cp39* cp310-* cp311-* cp312-*" + CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-* cp314-*" CIBW_SKIP: "*musllinux* *win32* *i686*" CIBW_ARCHS_MACOS: "native" CIBW_BUILD_VERBOSITY: 1 @@ -54,9 +54,9 @@ jobs: set -e if [[ $OSTYPE == "darwin23" ]] || [[ $OSTYPE == "darwin22" ]] then - export PYVERS="3.9 3.10 3.11 3.12" + export PYVERS="3.10 3.11 3.12" else - export PYVERS="3.8 3.9 3.10 3.11 3.12" + export PYVERS="3.10 3.11 3.12 3.13 3.14" fi for pyver in $PYVERS do diff --git a/.gitignore b/.gitignore index 10fc3c4b..c699cb5b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,11 @@ *.swo *.o *.exe +*.whl __pycache__ build dist libMcPhase.egg-info +libmcphase.egg-info +emsdk diff --git a/CMakeLists.txt b/CMakeLists.txt index eafcb813..26b2226e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) set(CMAKE_MACOSX_RPATH TRUE) set(CMAKE_CXX_STANDARD 11) set(CXX_STANDARD_REQUIRED 11) +cmake_policy(SET CMP0148 OLD) # New policy gives error when cannot find shared libs set(LIBMCPHASE_PYTHON_MODULE libmcphase) @@ -18,11 +19,26 @@ if(WIN32) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -d2:-FH4-") endif(WIN32) -include(Eigen) -include_directories(${EIGEN3_INCLUDE_DIR}) +if (DEFINED ENV{CONDA_PREFIX}) + message(STATUS "Searching $ENV{CONDA_PREFIX} for Pybind11 and Eigen") + file(GLOB pybind11_search $ENV{CONDA_PREFIX}/share/cmake/pybind11/pybind11Config.cmake) + if (NOT pybind11_search STREQUAL "") + cmake_path(GET pybind11_search PARENT_PATH pybind11_DIR) + endif() + file(GLOB eigen_search $ENV{CONDA_PREFIX}/share/eigen3/cmake/Eigen3Config.cmake) + if (NOT eigen_search STREQUAL "") + cmake_path(GET eigen_search PARENT_PATH Eigen3_DIR) + endif() +endif() + +if (EMSCRIPTEN) + message(STATUS "Emscripten detected - setting Pybind to use cross-compiler") + set(PYBIND11_USE_CROSSCOMPILING TRUE) +endif() -include(PyBind11) -add_subdirectory(${PyBind11_DIR}) +find_package(Eigen3 REQUIRED NO_MODULE) +include_directories(${EIGEN3_INCLUDE_DIR}) +find_package(pybind11 CONFIG) add_subdirectory(src) diff --git a/setup.py b/setup.py index 9abbd670..3a2ee932 100644 --- a/setup.py +++ b/setup.py @@ -124,10 +124,10 @@ def build_extension(self, ext): cmdclass=cmdclass, url="https://github.com/mducle/libmcphase", zip_safe=False, + license="GPL-3.0-or-later", classifiers=[ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Science/Research", - "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Operating System :: Microsoft :: Windows :: Windows 10", "Operating System :: POSIX :: Linux", "Programming Language :: C++", From 589dd967ebf745bfdc4bb2ed1a0673440ce26e98 Mon Sep 17 00:00:00 2001 From: Duc Le Date: Thu, 8 Jan 2026 09:07:23 +0000 Subject: [PATCH 2/3] Fix bugs in gha yaml and setup.py (for 3.14) --- .github/workflows/build_python.yml | 18 +++++------------- setup.py | 4 ++-- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build_python.yml b/.github/workflows/build_python.yml index 3716e670..02a5610d 100644 --- a/.github/workflows/build_python.yml +++ b/.github/workflows/build_python.yml @@ -23,24 +23,22 @@ jobs: build_and_test: strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, windows-latest, macos-14] name: Build and test, ${{ matrix.os }} runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - uses: mamba-org/setup-micromamba@v1 with: cache-downloads: true - name: Build wheels run: | - $MAMBA_EXE create -n cibuildwheel python=3.13 eigen pybind11 + $MAMBA_EXE create -n cibuildwheel python=3.12 eigen pybind11 eval "$($MAMBA_EXE shell activate cibuildwheel)" python -m pip install cibuildwheel - if [[ $OSTYPE == "darwin23" ]] || [[ $OSTYPE == "darwin22" ]] + if [[ $OSTYPE == "linux-gnu" ]] then - # For some reason cibuildwheel on builds 3.9-3.12 arm64 on macos-latest - export CIBW_BUILD="cp310* cp311* cp312*" + export CIBW_ENVIRONMENT="CONDA_PREFIX=/host/$CONDA_PREFIX" fi python -m cibuildwheel --output-dir wheelhouse env: @@ -52,13 +50,7 @@ jobs: run: | # set -e makes sure the script fails if any command in the loop fails set -e - if [[ $OSTYPE == "darwin23" ]] || [[ $OSTYPE == "darwin22" ]] - then - export PYVERS="3.10 3.11 3.12" - else - export PYVERS="3.10 3.11 3.12 3.13 3.14" - fi - for pyver in $PYVERS + for pyver in 3.10 3.11 3.12 3.13 3.14 do $MAMBA_EXE create -n py$pyver -c conda-forge python=$pyver numpy eval "$($MAMBA_EXE shell activate py$pyver)" diff --git a/setup.py b/setup.py index 3a2ee932..9e7f38ff 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ import re import sys import subprocess -import pkgutil +import importlib.util from sysconfig import get_platform from subprocess import CalledProcessError, check_output, check_call from distutils.version import LooseVersion @@ -14,7 +14,7 @@ # Except that in the manylinux builds it's placed at /opt/python/[version]/bin/ # (as a symlink at least) which is *not* on the path. # If cmake is a known module, import it and use it tell us its binary directory -if pkgutil.find_loader('cmake') is not None: +if (cmakemod := importlib.util.find_spec('cmake')) and cmakemod.loader: import cmake CMAKE_BIN = cmake.CMAKE_BIN_DIR + os.path.sep + 'cmake' else: From 30227d78e2f4f129832846889b2d486dadd7fba3 Mon Sep 17 00:00:00 2001 From: Duc Le Date: Thu, 8 Jan 2026 15:36:34 +0000 Subject: [PATCH 3/3] Add pyodide build to gh-actions --- .github/workflows/build_python.yml | 7 ++++++- .gitignore | 4 ++++ cmake/Eigen.cmake | 18 ------------------ cmake/Eigen.in | 18 ------------------ cmake/PyBind11.cmake | 19 ------------------- cmake/PyBind11.in | 12 ------------ 6 files changed, 10 insertions(+), 68 deletions(-) delete mode 100644 cmake/Eigen.cmake delete mode 100644 cmake/Eigen.in delete mode 100644 cmake/PyBind11.cmake delete mode 100644 cmake/PyBind11.in diff --git a/.github/workflows/build_python.yml b/.github/workflows/build_python.yml index 02a5610d..5b4e74f8 100644 --- a/.github/workflows/build_python.yml +++ b/.github/workflows/build_python.yml @@ -23,7 +23,7 @@ jobs: build_and_test: strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-14] + os: [ubuntu-latest, windows-latest, macos-14, macos-15-intel] name: Build and test, ${{ matrix.os }} runs-on: ${{ matrix.os }} steps: @@ -59,6 +59,11 @@ jobs: python -m unittest cd .. done + - name: Build Pyodide wheel + if: matrix.os == 'ubuntu-latest' + run: | + eval "$($MAMBA_EXE shell activate cibuildwheel)" + CIBW_BUILD="cp312*" python -m cibuildwheel --output-dir wheelhouse --platform pyodide - name: Upload release wheels if: | contains(github.event.pull_request.title, 'RELEASE') && diff --git a/.gitignore b/.gitignore index c699cb5b..c8998769 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,12 @@ *.whl __pycache__ +.pyodide-xbuildenv build dist libMcPhase.egg-info libmcphase.egg-info emsdk +Emscripten.cmake + +libmcphase/*pyd diff --git a/cmake/Eigen.cmake b/cmake/Eigen.cmake deleted file mode 100644 index 129c26a1..00000000 --- a/cmake/Eigen.cmake +++ /dev/null @@ -1,18 +0,0 @@ -include(ExternalProject) - -option(USE_SYSTEM_EIGEN "Use the system installed Eigen" OFF) - -if(USE_SYSTEM_EIGEN) - message(STATUS "Using system Eigen") - find_package(Eigen3 REQUIRED) -else() - message(STATUS "Using Eigen in ExternalProject") - - # Download and unpack Eigen at configure time - configure_file(${CMAKE_SOURCE_DIR}/cmake/Eigen.in ${CMAKE_BINARY_DIR}/extern-eigen/CMakeLists.txt) - - execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-eigen ) - execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-eigen ) - - set(EIGEN3_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/source") -endif() diff --git a/cmake/Eigen.in b/cmake/Eigen.in deleted file mode 100644 index b54ae42f..00000000 --- a/cmake/Eigen.in +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required ( VERSION 3.1 ) -project(libMcPhase_Eigen) -include( ExternalProject ) - -ExternalProject_Add(eigen - URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz - DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/download - SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/source - INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/install - CMAKE_CACHE_ARGS - -DCMAKE_BUILD_TYPE:STRING=Release - -DCMAKE_VERBOSE_MAKEFILE:BOOL=OFF - -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/install - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) diff --git a/cmake/PyBind11.cmake b/cmake/PyBind11.cmake deleted file mode 100644 index dcf97ce2..00000000 --- a/cmake/PyBind11.cmake +++ /dev/null @@ -1,19 +0,0 @@ -include(ExternalProject) - -if(USE_SYSTEM_PYBIND11) - message(STATUS "Using system Pybind11") -else() - message(STATUS "Using Pybind11 in ExternalProject") - - # Download and unpack Pybind11 at configure time - configure_file(${CMAKE_SOURCE_DIR}/cmake/PyBind11.in ${CMAKE_BINARY_DIR}/extern-pybind11/CMakeLists.txt) - - # The OLD behavior for this policy is to ignore the visibility properties - # for static libraries, object libraries, and executables without exports. - cmake_policy(SET CMP0063 "OLD") - - execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-pybind11 ) - execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-pybind11 ) - - set(PyBind11_DIR "${CMAKE_BINARY_DIR}/extern-pybind11/pybind11-prefix/src/pybind11/" CACHE PATH "") -endif() diff --git a/cmake/PyBind11.in b/cmake/PyBind11.in deleted file mode 100644 index 20e4bb75..00000000 --- a/cmake/PyBind11.in +++ /dev/null @@ -1,12 +0,0 @@ -cmake_minimum_required ( VERSION 3.1 ) -project(libMcPhase_Pybind11) -include( ExternalProject ) - -ExternalProject_Add(pybind11 - GIT_REPOSITORY https://github.com/pybind/pybind11.git - GIT_TAG v2.11.1 - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" -) -