diff --git a/.github/workflows/macOS_build.yml b/.github/workflows/macOS_build.yml index 0cbaa505c..30b53e87a 100644 --- a/.github/workflows/macOS_build.yml +++ b/.github/workflows/macOS_build.yml @@ -34,7 +34,7 @@ jobs: with: submodules: true - - name: Install OpenMP + - name: Install Dependencies run: | brew install libomp OPENMP_PREFIX=$(brew --prefix)/opt/libomp diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 461560cbf..f7a12b8e2 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -3,7 +3,11 @@ name: Wheel builder -on: workflow_dispatch +on: + workflow_dispatch: + release: + types: + - published jobs: build_wheels: @@ -14,53 +18,43 @@ jobs: matrix: include: # manylinux builds - - os: ubuntu-20.04 + - os: ubuntu-latest python: "cp39" platform: manylinux_x86_64 - - os: ubuntu-20.04 + - os: ubuntu-latest python: "cp310" platform: manylinux_x86_64 - - os: ubuntu-20.04 + - os: ubuntu-latest python: "cp311" platform: manylinux_x86_64 - - os: ubuntu-20.04 + - os: ubuntu-latest python: "cp312" platform: manylinux_x86_64 - - os: ubuntu-20.04 + - os: ubuntu-latest python: "cp313" platform: manylinux_x86_64 - - # manylinux pypy builds - - os: ubuntu-20.04 - python: "pp39" - platform: manylinux_x86_64 - - os: ubuntu-20.04 - python: "pp310" + - os: ubuntu-latest + python: "cp314" platform: manylinux_x86_64 # MacOS builds - intel - - os: macos-12 + - os: macos-13 python: "cp39" platform: macosx_x86_64 - - os: macos-12 + - os: macos-13 python: "cp310" platform: macosx_x86_64 - - os: macos-12 + - os: macos-13 python: "cp311" platform: macosx_x86_64 - - os: macos-12 + - os: macos-13 python: "cp312" platform: macosx_x86_64 - - os: macos-12 + - os: macos-13 python: "cp313" platform: macosx_x86_64 - - # MacOS PyPy builds - - os: macos-12 - python: "pp39" - platform: macosx_x86_64 - - os: macos-12 - python: "pp310" + - os: macos-13 + python: "cp314" platform: macosx_x86_64 # MacOS arm64 @@ -79,30 +73,28 @@ jobs: - os: macos-14 python: "cp313" platform: macosx_arm64 + - os: macos-14 + python: "cp314" + platform: macosx_arm64 # Windows builds - - os: windows-2019 + - os: windows-latest python: "cp39" platform: win_amd64 - - os: windows-2019 + - os: windows-latest python: "cp310" platform: win_amd64 - - os: windows-2019 + - os: windows-latest python: "cp311" platform: win_amd64 - - os: windows-2019 + - os: windows-latest python: "cp312" platform: win_amd64 - - os: windows-2019 + - os: windows-latest python: "cp313" platform: win_amd64 - - # Windows PyPy builds - - os: windows-2019 - python: "pp39" - platform: win_amd64 - - os: windows-2019 - python: "pp310" + - os: windows-latest + python: "cp314" platform: win_amd64 steps: @@ -111,11 +103,12 @@ jobs: with: submodules: true - - name: Set MACOSX_DEPLOYMENT_TARGET + - name: macOS Configuration if: runner.os == 'macOS' run: | - if [[ "${{ matrix.os }}" == "macos-12" ]]; then - echo "MACOSX_DEPLOYMENT_TARGET=12.0" >> $GITHUB_ENV + brew install libomp + if [[ "${{ matrix.os }}" == "macos-13" ]]; then + echo "MACOSX_DEPLOYMENT_TARGET=13.0" >> $GITHUB_ENV elif [[ "${{ matrix.os }}" == "macos-14" ]]; then echo "MACOSX_DEPLOYMENT_TARGET=14.0" >> $GITHUB_ENV fi @@ -123,7 +116,6 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v3.1.2 env: - CIBW_BEFORE_ALL_MACOS: CC=gcc-12 CXX=g++-12 CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform }} CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 CIBW_BUILD_VERBOSITY: 3 @@ -153,7 +145,7 @@ jobs: upload: runs-on: ubuntu-latest - # if: github.event_name == 'release' && github.event.action == 'published' + if: github.event_name == 'release' && github.event.action == 'published' needs: [build_wheels, build_sdist] environment: name: pypi diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a6874f26..b992aefa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Changes: * Reduce `max_trials` in Python tests for speed ([#206](https://github.com/xcsf-dev/xcsf/pull/206)) * Update Python packaging: move `setup.cfg` metadata to `pyproject.toml` ([#207](https://github.com/xcsf-dev/xcsf/pull/207)) * Fix macOS building with AppleClang ([#210](https://github.com/xcsf-dev/xcsf/pull/210)) +* Add support for Python 3.14 ([#211](https://github.com/xcsf-dev/xcsf/pull/211)) ## Version 1.4.7 (Aug 19, 2024) diff --git a/MANIFEST.in b/MANIFEST.in index 0c2df7608..1d8ad37ac 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,8 @@ include README.md LICENSE.md graft lib/pybind11/include graft lib/pybind11/tools -graft lib/dSFMT +include lib/dSFMT/*.h +exclude lib/dSFMT/jump/* graft lib/cJSON graft xcsf global-include CMakeLists.txt *.cmake diff --git a/pyproject.toml b/pyproject.toml index cc6f0a542..115516506 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ version = "1.4.7" description = "XCSF learning classifier system: rule-based evolutionary machine learning" readme = "README.md" requires-python = ">=3.9" -license = {text = "GPL-3.0"} +license = "GPL-3.0-or-later" maintainers = [ {name = "Richard Preen", email = "rpreen@gmail.com"} ] @@ -32,7 +32,6 @@ classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: Science/Research", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Programming Language :: C", "Programming Language :: C++", "Programming Language :: Python :: 3.9", diff --git a/setup.py b/setup.py index 70e93672c..131438b2e 100644 --- a/setup.py +++ b/setup.py @@ -38,6 +38,21 @@ def __init__(self, name, sourcedir=""): class CMakeBuild(build_ext): """Builds CMake extension.""" + def _get_openmp_root(self): + """Get OpenMP root path on macOS.""" + if platform.system() == "Darwin": + try: # Try Homebrew first + return subprocess.check_output( + ["brew", "--prefix", "libomp"], text=True + ).strip() + except (subprocess.CalledProcessError, FileNotFoundError): + # Try common system paths + for path in ["/usr/local", "/opt/homebrew"]: + if os.path.exists(f"{path}/lib/libomp.dylib"): + return path + return None + + def build_extension(self, ext): self.announce("Configuring CMake project", level=3) extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) @@ -45,29 +60,33 @@ def build_extension(self, ext): extdir += os.path.sep if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) + cmake_args = [ f"-DPYTHON_EXECUTABLE={sys.executable}", "-DCMAKE_BUILD_TYPE=Release", - "-DCMAKE_C_COMPILER=gcc", - "-DCMAKE_CXX_COMPILER=g++", "-DXCSF_MAIN=OFF", "-DXCSF_PYLIB=ON", "-DENABLE_DOXYGEN=OFF", "-DNATIVE_OPT=OFF", ] - build_args = [ - "--config", - "Release", - ] - if platform.system() == "Darwin": # set to force CI to use GCC - cmake_args[2] = "-DCMAKE_C_COMPILER=gcc-12" - cmake_args[3] = "-DCMAKE_CXX_COMPILER=g++-12" + build_args = [ "--config", "Release" ] + + if platform.system() == "Darwin": + openmp_root = self._get_openmp_root() + if openmp_root: + cmake_args += ["-DOpenMP_ROOT=" + openmp_root] + os.environ["LDFLAGS"] = os.environ.get("LDFLAGS", "") + \ + f" -L{os.path.join(openmp_root, 'lib')}" + if platform.system() == "Windows": + cmake_args += ["-DCMAKE_C_COMPILER=gcc"] + cmake_args += ["-DCMAKE_CXX_COMPILER=g++"] cmake_args += ["-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=" + extdir] cmake_args += ["-GMinGW Makefiles"] else: cmake_args += ["-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=" + extdir] build_args += ["-j4"] + subprocess.check_call( ["cmake", ext.sourcedir] + cmake_args, cwd=self.build_temp )