diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2f6b2bb..190de55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,11 +28,23 @@ jobs: test: name: Test builds needs: pre-commit - runs-on: macOS-latest + runs-on: ${{ matrix.runs-on }} strategy: fail-fast: false matrix: - python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13-dev" ] + python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ] + runs-on: [ "macos-latest", "macos-12" ] + + exclude: + # Don't need to run x86 tests on every Python version + - python-version: "3.9" + runs-on: "macos-12" + - python-version: "3.10" + runs-on: "macos-12" + - python-version: "3.11" + runs-on: "macos-12" + - python-version: "3.13" + runs-on: "macos-12" steps: - name: Checkout @@ -43,30 +55,60 @@ jobs: - name: Set up Python uses: actions/setup-python@v5.2.0 with: - python-version: ${{ matrix.python-version }} + # -dev suffix is a no-op for published releases + python-version: ${{ matrix.python-version }}-dev # Initial call to the setup script sets up the environment - name: Set up Forge run: | - source ./setup-iOS.sh $(cut -d- -f1 <<< ${{ matrix.python-version }}) + source ./setup-iOS.sh ${{ matrix.python-version }} + + # Build packages that are pre-build dependencies + # Calling setup script activates existing environment + - name: Build bzip2 + run: | + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS bzip2 -vv + + - name: Build ninja + run: | + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS ninja -vv - # Build an example of a native package + # Build examples of native packages # Calling setup script activates existing environment - name: Build libjpeg run: | - source ./setup-iOS.sh $(cut -d- -f1 <<< ${{ matrix.python-version }}) - forge iOS libjpeg + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS libjpeg -vv + + - name: Build freetype + run: | + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS freetype -vv # Build an example of a simple Python package # Calling setup script activates existing environment - name: Build lru-dict run: | - source ./setup-iOS.sh $(cut -d- -f1 <<< ${{ matrix.python-version }}) - forge iOS lru-dict + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS lru-dict -vv + + # Build a package with dependencies on other packages + - name: Build pillow + run: | + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS pillow -vv + + # Build a package with a complex build system + - name: Build numpy + run: | + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS numpy -vv # Build an example of a simple Python package using C++ # Calling setup script activates existing environment - name: Build brotli run: | - source ./setup-iOS.sh $(cut -d- -f1 <<< ${{ matrix.python-version }}) - forge iOS brotli + source ./setup-iOS.sh ${{ matrix.python-version }} + forge iOS brotli -vv diff --git a/recipes/numpy/patches/mobile-1.26.0.patch b/recipes/numpy/patches/mobile-1.26.0.patch index 2d23546..edf05ca 100644 --- a/recipes/numpy/patches/mobile-1.26.0.patch +++ b/recipes/numpy/patches/mobile-1.26.0.patch @@ -149,13 +149,13 @@ diff -ru numpy-1.26.0-orig/vendored-meson/meson-python/mesonpy/__init__.py numpy self._meson_cross_file.write_text(cross_file_data) self._meson_args['setup'].extend(('--cross-file', os.fspath(self._meson_cross_file))) + elif sysconfig_platform.startswith("ios-"): -+ arch = sysconfig_platform.split("-")[-1] ++ arch = sysconfig_platform.split("-")[-2] + family = "aarch64" if arch == "arm64" else arch + cross_file_data = textwrap.dedent( + f""" + [binaries] + c = [{sysconfig.get_config_var("CC")!r}] -+ cpp = [{sysconfig.get_config_var("CC")!r}] ++ cpp = [{sysconfig.get_config_var("CXX")!r}] + + [host_machine] + system = 'ios' diff --git a/recipes/pillow/meta.yaml b/recipes/pillow/meta.yaml index 101d00a..5f72955 100644 --- a/recipes/pillow/meta.yaml +++ b/recipes/pillow/meta.yaml @@ -15,6 +15,8 @@ build: # libfreetype references both libz and libbz2 # but doesn't link them into the static library - LDFLAGS=-lz -lbz2 + config: + - debug=true requirements: host: diff --git a/recipes/pillow/patches/setup-9.4.0.patch b/recipes/pillow/patches/setup-9.4.0.patch index 006dc9c..7bf32a4 100644 --- a/recipes/pillow/patches/setup-9.4.0.patch +++ b/recipes/pillow/patches/setup-9.4.0.patch @@ -1,10 +1,11 @@ Common subdirectories: Pillow-9.4.0-orig/Tests and Pillow-9.4.0/Tests +Common subdirectories: Pillow-9.4.0-orig/__pycache__ and Pillow-9.4.0/__pycache__ Common subdirectories: Pillow-9.4.0-orig/depends and Pillow-9.4.0/depends Common subdirectories: Pillow-9.4.0-orig/docs and Pillow-9.4.0/docs diff -u Pillow-9.4.0-orig/setup.py Pillow-9.4.0/setup.py ---- Pillow-9.4.0-orig/setup.py 2023-01-02 08:17:32 -+++ Pillow-9.4.0/setup.py 2023-09-21 10:16:17 -@@ -408,10 +408,19 @@ +--- Pillow-9.4.0-orig/setup.py 2023-01-01 16:17:32 ++++ Pillow-9.4.0/setup.py 2024-09-25 11:17:51 +@@ -408,10 +408,22 @@ self.extensions.remove(extension) break @@ -19,14 +20,17 @@ diff -u Pillow-9.4.0-orig/setup.py Pillow-9.4.0/setup.py + ("watchos", False): ["--sdk", "watchos"], + ("watchos", True): ["--sdk", "watchsimulator"], + ("darwin", False): [], -+ }[sys.platform, getattr(sys.implementation, "_multiarch", "").endswith("simulator")] ++ }[ ++ sys.platform, ++ getattr(sys.implementation, "_multiarch", "").endswith("simulator"), ++ ] sdk_path = ( - subprocess.check_output(["xcrun", "--show-sdk-path"]) + subprocess.check_output(["xcrun", "--show-sdk-path"] + sdk) .strip() .decode("latin1") ) -@@ -556,10 +564,15 @@ +@@ -556,10 +568,15 @@ _add_directory(library_dirs, "/usr/X11/lib") _add_directory(include_dirs, "/usr/X11/include") @@ -43,3 +47,16 @@ diff -u Pillow-9.4.0-orig/setup.py Pillow-9.4.0/setup.py elif ( sys.platform.startswith("linux") or sys.platform.startswith("gnu") +@@ -593,7 +610,9 @@ + # FIXME: check /opt/stuff directories here? + + # standard locations +- if not self.disable_platform_guessing: ++ if not ( ++ self.disable_platform_guessing or sys.platform in {"ios", "tvos", "watchos"} ++ ): + _add_directory(library_dirs, "/usr/local/lib") + _add_directory(include_dirs, "/usr/local/include") + +Common subdirectories: Pillow-9.4.0-orig/src and Pillow-9.4.0/src +Common subdirectories: Pillow-9.4.0-orig/winbuild and Pillow-9.4.0/winbuild diff --git a/recipes/pillow/patches/setup.patch b/recipes/pillow/patches/setup.patch index 892122b..d678cae 100644 --- a/recipes/pillow/patches/setup.patch +++ b/recipes/pillow/patches/setup.patch @@ -1,6 +1,10 @@ -diff -ur pillow-10.4.0-orig/setup.py pillow-10.4.0/setup.py ---- pillow-10.4.0-orig/setup.py 2024-07-01 14:02:01 -+++ pillow-10.4.0/setup.py 2024-09-05 14:20:16 +Common subdirectories: pillow-10.4.0-orig/Tests and pillow-10.4.0/Tests +Common subdirectories: pillow-10.4.0-orig/_custom_build and pillow-10.4.0/_custom_build +Common subdirectories: pillow-10.4.0-orig/depends and pillow-10.4.0/depends +Common subdirectories: pillow-10.4.0-orig/docs and pillow-10.4.0/docs +diff -u pillow-10.4.0-orig/setup.py pillow-10.4.0/setup.py +--- pillow-10.4.0-orig/setup.py 2024-06-30 23:02:01 ++++ pillow-10.4.0/setup.py 2024-09-25 11:15:21 @@ -422,10 +422,22 @@ self.extensions.remove(extension) break @@ -46,3 +50,17 @@ diff -ur pillow-10.4.0-orig/setup.py pillow-10.4.0/setup.py elif ( sys.platform.startswith("linux") or sys.platform.startswith("gnu") +@@ -618,7 +635,10 @@ + # FIXME: check /opt/stuff directories here? + + # standard locations +- if not self.disable_platform_guessing: ++ # The standard locations aren't standard on iOS et al. ++ if not ( ++ self.disable_platform_guessing or sys.platform in {"ios", "tvos", "watchos"} ++ ): + _add_directory(library_dirs, "/usr/local/lib") + _add_directory(include_dirs, "/usr/local/include") + +Common subdirectories: pillow-10.4.0-orig/src and pillow-10.4.0/src +Common subdirectories: pillow-10.4.0-orig/winbuild and pillow-10.4.0/winbuild diff --git a/src/forge/build.py b/src/forge/build.py index 06c3462..0e29dea 100644 --- a/src/forge/build.py +++ b/src/forge/build.py @@ -217,6 +217,7 @@ def compile_env(self, **kwargs) -> dict[str:str]: ar = sysconfig_data["AR"] cc = sysconfig_data["CC"] + cxx = sysconfig_data["CXX"] cflags = self.cross_venv.sysconfig_data["CFLAGS"] @@ -258,7 +259,9 @@ def compile_env(self, **kwargs) -> dict[str:str]: env = { "AR": ar, "CC": cc, + "CXX": cxx, "CFLAGS": cflags, + "CXXFLAGS": cflags, "LDFLAGS": ldflags, "INSTALL_ROOT": str(self.cross_venv.install_root), } @@ -560,6 +563,10 @@ def _build(self): else: output_dir = str(Path.cwd() / "dist") + config_args = [] + for config in self.package.meta["build"]["config"]: + config_args.extend(["-C", config]) + self.cross_venv.run( self.log_file, [ @@ -570,7 +577,9 @@ def _build(self): "--wheel", "--outdir", output_dir, - ], + "-v", + ] + + config_args, cwd=self.build_path, env=self.compile_env(**script_env), ) diff --git a/src/forge/schema/meta-schema.yaml b/src/forge/schema/meta-schema.yaml index 5e66b4d..b6d37c8 100644 --- a/src/forge/schema/meta-schema.yaml +++ b/src/forge/schema/meta-schema.yaml @@ -65,6 +65,11 @@ properties: default: [] items: type: string + config: # Config arguments to pass to python -m build in the form -C value + type: array + default: [] + items: + type: string additionalProperties: false requirements: