From a5e69a6d7d977e9eec3e1ce17cced0da820d6900 Mon Sep 17 00:00:00 2001 From: scaramallion Date: Tue, 19 Aug 2025 10:13:24 +1000 Subject: [PATCH 1/6] Bump cibuildwheel --- .github/workflows/release-wheels.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-wheels.yml b/.github/workflows/release-wheels.yml index ae2f627..65b1b2e 100644 --- a/.github/workflows/release-wheels.yml +++ b/.github/workflows/release-wheels.yml @@ -3,9 +3,9 @@ name: release-deploy on: release: types: [ published ] - # push: - # branches: [ main ] - # pull_request: + push: + branches: [ main ] + pull_request: jobs: build-sdist: @@ -166,7 +166,7 @@ jobs: - name: Install cibuildwheel run: | python -m pip install -U pip - python -m pip install cibuildwheel>=2.21 + python -m pip install cibuildwheel>=3.1.0 - name: Build wheels (non-MacOS arm64) env: @@ -225,7 +225,7 @@ jobs: python-version: '3.9' - name: Install cibuildwheel - run: python -m pip install cibuildwheel>=2.21 wheel>=0.42 + run: python -m pip install cibuildwheel>=3.1.0 wheel>=0.42 - name: Build wheels env: From 5c2447945c8f1099d6bbb6020881db9719e718fd Mon Sep 17 00:00:00 2001 From: scaramallion Date: Tue, 19 Aug 2025 10:14:50 +1000 Subject: [PATCH 2/6] Build using Python 3.13 --- .github/workflows/release-wheels.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-wheels.yml b/.github/workflows/release-wheels.yml index 65b1b2e..70689ec 100644 --- a/.github/workflows/release-wheels.yml +++ b/.github/workflows/release-wheels.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-python@v5 name: Install Python with: - python-version: '3.10' + python-version: '3.13' - name: Build sdist run: | @@ -161,7 +161,7 @@ jobs: - uses: actions/setup-python@v5 name: Install Python with: - python-version: '3.9' + python-version: '3.13' - name: Install cibuildwheel run: | @@ -222,7 +222,7 @@ jobs: - uses: actions/setup-python@v5 name: Install Python with: - python-version: '3.9' + python-version: '3.13' - name: Install cibuildwheel run: python -m pip install cibuildwheel>=3.1.0 wheel>=0.42 From c4c76217eaae7f7487bba3c0ae8c5809aa061626 Mon Sep 17 00:00:00 2001 From: scaramallion Date: Tue, 19 Aug 2025 10:19:41 +1000 Subject: [PATCH 3/6] Bump to cibuildwheel 3.1.3 --- .github/workflows/release-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-wheels.yml b/.github/workflows/release-wheels.yml index 70689ec..3ae4d60 100644 --- a/.github/workflows/release-wheels.yml +++ b/.github/workflows/release-wheels.yml @@ -166,7 +166,7 @@ jobs: - name: Install cibuildwheel run: | python -m pip install -U pip - python -m pip install cibuildwheel>=3.1.0 + python -m pip install cibuildwheel>=3.1.3 - name: Build wheels (non-MacOS arm64) env: @@ -225,7 +225,7 @@ jobs: python-version: '3.13' - name: Install cibuildwheel - run: python -m pip install cibuildwheel>=3.1.0 wheel>=0.42 + run: python -m pip install cibuildwheel>=3.1.3 - name: Build wheels env: From 0038dcedb6dc8e0c62209d24ba6eb9b9afd93f14 Mon Sep 17 00:00:00 2001 From: scaramallion Date: Tue, 19 Aug 2025 10:28:03 +1000 Subject: [PATCH 4/6] Fix name conflict with cibuildwheel --- .github/workflows/release-wheels.yml | 2 + build.py | 187 --------------------------- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 188 deletions(-) delete mode 100644 build.py diff --git a/.github/workflows/release-wheels.yml b/.github/workflows/release-wheels.yml index 3ae4d60..23cd497 100644 --- a/.github/workflows/release-wheels.yml +++ b/.github/workflows/release-wheels.yml @@ -171,6 +171,7 @@ jobs: - name: Build wheels (non-MacOS arm64) env: CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }} + CIBW_PLATFORM: linux, macos, windows CIBW_ARCHS: all CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_image }} CIBW_MANYLINUX_I686_IMAGE: ${{ matrix.manylinux_image }} @@ -230,6 +231,7 @@ jobs: - name: Build wheels env: CIBW_BUILD: cp${{ matrix.python }}-* + CIBW_PLATFORM: macos CIBW_ARCHS_MACOS: arm64 CIBW_BUILD_VERBOSITY: 1 run: | diff --git a/build.py b/build.py deleted file mode 100644 index 1aa203b..0000000 --- a/build.py +++ /dev/null @@ -1,187 +0,0 @@ - -import os -from pathlib import Path -import shutil -from struct import unpack -import subprocess -from typing import List, Any - - -PACKAGE_DIR = Path(__file__).parent / "openjpeg" -LIB_DIR = Path(__file__).parent / "lib" -BUILD_TOOLS = Path(__file__).parent / "build_tools" -OPENJPEG_SRC = LIB_DIR / "openjpeg" / "src" / "lib" / "openjp2" -THIRDPARTY_SRC = LIB_DIR / "openjpeg" / "thirdparty" -BIN_SRC = LIB_DIR / "openjpeg" / "src" / "bin" / "common" -INTERFACE_SRC = LIB_DIR / "interface" -BUILD_DIR = LIB_DIR / "openjpeg" / "build" -BACKUP_DIR = BUILD_TOOLS / "backup" - - -def build(setup_kwargs: Any) -> Any: - from setuptools import Extension - from setuptools.dist import Distribution - import Cython.Compiler.Options - from Cython.Build import build_ext, cythonize - import numpy - - setup_oj() - - # Determine if system is big endian or not - macros = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")] - if unpack("h", b"\x00\x01")[0] == 1: - macros.append(("PYOJ_BIG_ENDIAN", None)) - - ext = Extension( - "_openjpeg", - [os.fspath(p) for p in get_source_files()], - language="c", - include_dirs=[ - os.fspath(OPENJPEG_SRC), - os.fspath(THIRDPARTY_SRC / "liblcms2" / "include"), - os.fspath(INTERFACE_SRC), - numpy.get_include(), - ], - extra_compile_args=[], - extra_link_args=[], - define_macros=macros, - ) - - ext_modules = cythonize( - [ext], - include_path=ext.include_dirs, - language_level=3, - ) - - dist = Distribution({"ext_modules": ext_modules}) - cmd = build_ext(dist) - cmd.ensure_finalized() - cmd.run() - - for output in cmd.get_outputs(): - output = Path(output) - relative_ext = output.relative_to(cmd.build_lib) - shutil.copyfile(output, relative_ext) - - reset_oj() - - return setup_kwargs - - -def get_source_files() -> List[Path]: - """Return a list of paths to the source files to be compiled.""" - source_files = [ - INTERFACE_SRC / "decode.c", - INTERFACE_SRC / "encode.c", - INTERFACE_SRC / "color.c", - INTERFACE_SRC / "utils.c", - ] - for fname in OPENJPEG_SRC.glob("*"): - if fname.parts[-1].startswith("test"): - continue - - if fname.parts[-1].startswith("bench"): - continue - - if fname.suffix == ".c": - source_files.append(fname) - - for name in (THIRDPARTY_SRC / "liblcms2" / "src").glob("*"): - if name.suffix == ".c": - source_files.append(name) - - source_files = [p.relative_to(Path(__file__).parent) for p in source_files] - source_files.insert(0, PACKAGE_DIR / "_openjpeg.pyx") - - return source_files - - -def setup_oj() -> None: - """Run custom cmake.""" - base_dir = LIB_DIR / "openjpeg" - p_openjpeg = base_dir / "src" / "lib" / "openjp2" / "openjpeg.c" - - # Backup original CMakeLists.txt and openjpeg.c files - if os.path.exists(BACKUP_DIR): - shutil.rmtree(BACKUP_DIR) - - BACKUP_DIR.mkdir(exist_ok=True, parents=True) - - # Copy the color space conversion files - for name in ("color.c", "color.h"): - shutil.copy(BIN_SRC / name, INTERFACE_SRC / name) - - shutil.copy( - LIB_DIR / "openjpeg" / "CMakeLists.txt", - BACKUP_DIR / "CMakeLists.txt.backup", - ) - shutil.copy( - OPENJPEG_SRC / "openjpeg.c", - BACKUP_DIR / "openjpeg.c.backup", - ) - - # Copy custom CMakeLists.txt file to openjpeg base dir - shutil.copy( - BUILD_TOOLS / "cmake" / "CMakeLists.txt", - LIB_DIR / "openjpeg" / "CMakeLists.txt", - ) - - # Edit openjpeg.c to remove the OPJ_API declaration - with p_openjpeg.open("r") as f: - data = f.readlines() - - data = [ - line.replace("OPJ_API ", "") - if line.startswith("OPJ_API ") else line for line in data - ] - with p_openjpeg.open("w") as f: - f.write("".join(data)) - - if os.path.exists(BUILD_DIR): - shutil.rmtree(BUILD_DIR) - - for name in ("opj_config.h", "opj_config_private.h"): - try: - os.remove(INTERFACE_SRC / name) - except: - pass - - os.mkdir(BUILD_DIR) - cur_dir = os.getcwd() - os.chdir(BUILD_DIR) - subprocess.call(['cmake', os.fspath((LIB_DIR / "openjpeg").resolve(strict=True))]) - os.chdir(cur_dir) - - shutil.copy( - BUILD_DIR / "src" / "bin" / "common" / "opj_apps_config.h", - INTERFACE_SRC / "opj_apps_config.h", - ) - - # Turn off JPIP - if os.path.exists(INTERFACE_SRC / "opj_config.h"): - with open(INTERFACE_SRC / "opj_config.h", "a") as f: - f.write("\n") - f.write("#define USE_JPIP 0") - - -def reset_oj() -> None: - # Restore submodule to original state - # Restore CMakeLists.txt and openjpeg.c files - if (BACKUP_DIR / "CMakeLists.txt.backup").exists(): - shutil.copy( - BACKUP_DIR / "CMakeLists.txt.backup", - LIB_DIR / "openjpeg" / "CMakeLists.txt", - ) - - if (BACKUP_DIR / "openjpeg.c.backup").exists(): - shutil.copy( - BACKUP_DIR / "openjpeg.c.backup", - OPENJPEG_SRC / "openjpeg.c", - ) - - # Cleanup added directories - if os.path.exists(BUILD_DIR): - shutil.rmtree(BUILD_DIR) - - if os.path.exists(BACKUP_DIR): - shutil.rmtree(BACKUP_DIR) diff --git a/pyproject.toml b/pyproject.toml index fb2a899..95bb2c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ requires = [ build-backend = "poetry.core.masonry.api" [tool.poetry.build] -script = "build.py" +script = "build_package.py" generate-setup-file = true [tool.poetry] From 1646af7251b398d0078a0ba1cb172d39229f6c67 Mon Sep 17 00:00:00 2001 From: scaramallion Date: Tue, 19 Aug 2025 10:30:33 +1000 Subject: [PATCH 5/6] Add renamed file --- .github/workflows/release-wheels.yml | 2 - build_package.py | 187 +++++++++++++++++++++++++++ 2 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 build_package.py diff --git a/.github/workflows/release-wheels.yml b/.github/workflows/release-wheels.yml index 23cd497..3ae4d60 100644 --- a/.github/workflows/release-wheels.yml +++ b/.github/workflows/release-wheels.yml @@ -171,7 +171,6 @@ jobs: - name: Build wheels (non-MacOS arm64) env: CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }} - CIBW_PLATFORM: linux, macos, windows CIBW_ARCHS: all CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_image }} CIBW_MANYLINUX_I686_IMAGE: ${{ matrix.manylinux_image }} @@ -231,7 +230,6 @@ jobs: - name: Build wheels env: CIBW_BUILD: cp${{ matrix.python }}-* - CIBW_PLATFORM: macos CIBW_ARCHS_MACOS: arm64 CIBW_BUILD_VERBOSITY: 1 run: | diff --git a/build_package.py b/build_package.py new file mode 100644 index 0000000..1aa203b --- /dev/null +++ b/build_package.py @@ -0,0 +1,187 @@ + +import os +from pathlib import Path +import shutil +from struct import unpack +import subprocess +from typing import List, Any + + +PACKAGE_DIR = Path(__file__).parent / "openjpeg" +LIB_DIR = Path(__file__).parent / "lib" +BUILD_TOOLS = Path(__file__).parent / "build_tools" +OPENJPEG_SRC = LIB_DIR / "openjpeg" / "src" / "lib" / "openjp2" +THIRDPARTY_SRC = LIB_DIR / "openjpeg" / "thirdparty" +BIN_SRC = LIB_DIR / "openjpeg" / "src" / "bin" / "common" +INTERFACE_SRC = LIB_DIR / "interface" +BUILD_DIR = LIB_DIR / "openjpeg" / "build" +BACKUP_DIR = BUILD_TOOLS / "backup" + + +def build(setup_kwargs: Any) -> Any: + from setuptools import Extension + from setuptools.dist import Distribution + import Cython.Compiler.Options + from Cython.Build import build_ext, cythonize + import numpy + + setup_oj() + + # Determine if system is big endian or not + macros = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")] + if unpack("h", b"\x00\x01")[0] == 1: + macros.append(("PYOJ_BIG_ENDIAN", None)) + + ext = Extension( + "_openjpeg", + [os.fspath(p) for p in get_source_files()], + language="c", + include_dirs=[ + os.fspath(OPENJPEG_SRC), + os.fspath(THIRDPARTY_SRC / "liblcms2" / "include"), + os.fspath(INTERFACE_SRC), + numpy.get_include(), + ], + extra_compile_args=[], + extra_link_args=[], + define_macros=macros, + ) + + ext_modules = cythonize( + [ext], + include_path=ext.include_dirs, + language_level=3, + ) + + dist = Distribution({"ext_modules": ext_modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + cmd.run() + + for output in cmd.get_outputs(): + output = Path(output) + relative_ext = output.relative_to(cmd.build_lib) + shutil.copyfile(output, relative_ext) + + reset_oj() + + return setup_kwargs + + +def get_source_files() -> List[Path]: + """Return a list of paths to the source files to be compiled.""" + source_files = [ + INTERFACE_SRC / "decode.c", + INTERFACE_SRC / "encode.c", + INTERFACE_SRC / "color.c", + INTERFACE_SRC / "utils.c", + ] + for fname in OPENJPEG_SRC.glob("*"): + if fname.parts[-1].startswith("test"): + continue + + if fname.parts[-1].startswith("bench"): + continue + + if fname.suffix == ".c": + source_files.append(fname) + + for name in (THIRDPARTY_SRC / "liblcms2" / "src").glob("*"): + if name.suffix == ".c": + source_files.append(name) + + source_files = [p.relative_to(Path(__file__).parent) for p in source_files] + source_files.insert(0, PACKAGE_DIR / "_openjpeg.pyx") + + return source_files + + +def setup_oj() -> None: + """Run custom cmake.""" + base_dir = LIB_DIR / "openjpeg" + p_openjpeg = base_dir / "src" / "lib" / "openjp2" / "openjpeg.c" + + # Backup original CMakeLists.txt and openjpeg.c files + if os.path.exists(BACKUP_DIR): + shutil.rmtree(BACKUP_DIR) + + BACKUP_DIR.mkdir(exist_ok=True, parents=True) + + # Copy the color space conversion files + for name in ("color.c", "color.h"): + shutil.copy(BIN_SRC / name, INTERFACE_SRC / name) + + shutil.copy( + LIB_DIR / "openjpeg" / "CMakeLists.txt", + BACKUP_DIR / "CMakeLists.txt.backup", + ) + shutil.copy( + OPENJPEG_SRC / "openjpeg.c", + BACKUP_DIR / "openjpeg.c.backup", + ) + + # Copy custom CMakeLists.txt file to openjpeg base dir + shutil.copy( + BUILD_TOOLS / "cmake" / "CMakeLists.txt", + LIB_DIR / "openjpeg" / "CMakeLists.txt", + ) + + # Edit openjpeg.c to remove the OPJ_API declaration + with p_openjpeg.open("r") as f: + data = f.readlines() + + data = [ + line.replace("OPJ_API ", "") + if line.startswith("OPJ_API ") else line for line in data + ] + with p_openjpeg.open("w") as f: + f.write("".join(data)) + + if os.path.exists(BUILD_DIR): + shutil.rmtree(BUILD_DIR) + + for name in ("opj_config.h", "opj_config_private.h"): + try: + os.remove(INTERFACE_SRC / name) + except: + pass + + os.mkdir(BUILD_DIR) + cur_dir = os.getcwd() + os.chdir(BUILD_DIR) + subprocess.call(['cmake', os.fspath((LIB_DIR / "openjpeg").resolve(strict=True))]) + os.chdir(cur_dir) + + shutil.copy( + BUILD_DIR / "src" / "bin" / "common" / "opj_apps_config.h", + INTERFACE_SRC / "opj_apps_config.h", + ) + + # Turn off JPIP + if os.path.exists(INTERFACE_SRC / "opj_config.h"): + with open(INTERFACE_SRC / "opj_config.h", "a") as f: + f.write("\n") + f.write("#define USE_JPIP 0") + + +def reset_oj() -> None: + # Restore submodule to original state + # Restore CMakeLists.txt and openjpeg.c files + if (BACKUP_DIR / "CMakeLists.txt.backup").exists(): + shutil.copy( + BACKUP_DIR / "CMakeLists.txt.backup", + LIB_DIR / "openjpeg" / "CMakeLists.txt", + ) + + if (BACKUP_DIR / "openjpeg.c.backup").exists(): + shutil.copy( + BACKUP_DIR / "openjpeg.c.backup", + OPENJPEG_SRC / "openjpeg.c", + ) + + # Cleanup added directories + if os.path.exists(BUILD_DIR): + shutil.rmtree(BUILD_DIR) + + if os.path.exists(BACKUP_DIR): + shutil.rmtree(BACKUP_DIR) From 5d3e1d47e6687705790a23caef955c9f04326725 Mon Sep 17 00:00:00 2001 From: scaramallion Date: Tue, 19 Aug 2025 10:39:35 +1000 Subject: [PATCH 6/6] Finalise --- .github/workflows/release-wheels.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-wheels.yml b/.github/workflows/release-wheels.yml index 3ae4d60..16a0120 100644 --- a/.github/workflows/release-wheels.yml +++ b/.github/workflows/release-wheels.yml @@ -3,9 +3,9 @@ name: release-deploy on: release: types: [ published ] - push: - branches: [ main ] - pull_request: + # push: + # branches: [ main ] + # pull_request: jobs: build-sdist: