diff --git a/recipes/numpy/patches/mobile-1.26.0.patch b/recipes/numpy/patches/mobile-1.26.0.patch deleted file mode 100644 index 7eb0622..0000000 --- a/recipes/numpy/patches/mobile-1.26.0.patch +++ /dev/null @@ -1,181 +0,0 @@ -diff -ru numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/envconfig.py numpy-1.26.0/vendored-meson/meson/mesonbuild/envconfig.py ---- numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/envconfig.py 1970-01-01 08:00:00 -+++ numpy-1.26.0/vendored-meson/meson/mesonbuild/envconfig.py 2023-10-17 15:16:38 -@@ -317,9 +317,33 @@ - - def is_darwin(self) -> bool: - """ -- Machine is Darwin (iOS/tvOS/OS X)? -+ Machine is a Darwin kernel (iOS/tvOS/macOS)? - """ -- return self.system in {'darwin', 'ios', 'tvos'} -+ return self.system in {'darwin', 'ios', 'tvos', 'watchos'} -+ -+ def is_macOS(self) -> bool: -+ """ -+ Machine is macOS? -+ """ -+ return self.system == 'darwin' -+ -+ def is_iOS(self) -> bool: -+ """ -+ Machine is iOS? -+ """ -+ return self.system == 'ios' -+ -+ def is_tvOS(self) -> bool: -+ """ -+ Machine is tvOS? -+ """ -+ return self.system == 'tvos' -+ -+ def is_watchOS(self) -> bool: -+ """ -+ Machine is watchOS? -+ """ -+ return self.system == 'watchos' - - def is_android(self) -> bool: - """ -diff -ru numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/environment.py numpy-1.26.0/vendored-meson/meson/mesonbuild/environment.py ---- numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/environment.py 1970-01-01 08:00:00 -+++ numpy-1.26.0/vendored-meson/meson/mesonbuild/environment.py 2023-10-02 14:33:03 -@@ -290,7 +290,7 @@ - """ - if mesonlib.is_windows(): - trial = detect_windows_arch(compilers) -- elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_qnx() or mesonlib.is_aix(): -+ elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_qnx() or mesonlib.is_aix() or mesonlib.is_ios() or mesonlib.is_tvos() or mesonlib.is_watchos(): - trial = platform.processor().lower() - else: - trial = platform.machine().lower() -@@ -356,7 +356,7 @@ - def detect_cpu(compilers: CompilersDict) -> str: - if mesonlib.is_windows(): - trial = detect_windows_arch(compilers) -- elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_aix(): -+ elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_aix() or mesonlib.is_ios() or mesonlib.is_tvos() or mesonlib.is_watchos(): - trial = platform.processor().lower() - else: - trial = platform.machine().lower() -diff -ru numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/linkers/detect.py numpy-1.26.0/vendored-meson/meson/mesonbuild/linkers/detect.py ---- numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/linkers/detect.py 1970-01-01 08:00:00 -+++ numpy-1.26.0/vendored-meson/meson/mesonbuild/linkers/detect.py 2023-10-17 15:18:33 -@@ -199,7 +199,17 @@ - break - else: - __failed_to_detect_linker(compiler, check_args, o, e) -- linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) -+ -+ # iOS/tvOS/watchOS have different linking needs. -+ if ( -+ env.machines[for_machine].is_iOS() -+ or env.machines[for_machine].is_tvOS() -+ or env.machines[for_machine].is_watchOS() -+ ): -+ linker = linkers.AppleMobileDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) -+ else: -+ linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) -+ - elif 'GNU' in o or 'GNU' in e: - gnu_cls: T.Type[GnuDynamicLinker] - # this is always the only thing on stdout, except for swift -diff -ru numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/linkers/linkers.py numpy-1.26.0/vendored-meson/meson/mesonbuild/linkers/linkers.py ---- numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/linkers/linkers.py 1970-01-01 08:00:00 -+++ numpy-1.26.0/vendored-meson/meson/mesonbuild/linkers/linkers.py 2023-10-17 14:59:26 -@@ -829,6 +829,15 @@ - return ["-Wl,-cache_path_lto," + path] - - -+class AppleMobileDynamicLinker(AppleDynamicLinker): -+ # iOS/tvOS/watchOS need to be linked with -dynamiclib, not -bundle -+ def get_allow_undefined_args(self) -> T.List[str]: -+ return ["-framework", "Python"] -+ -+ def get_std_shared_module_args(self, options: "KeyedOptionDictType") -> T.List[str]: -+ return ["-dynamiclib", "-framework", "Python"] -+ -+ - class LLVMLD64DynamicLinker(AppleDynamicLinker): - - id = 'ld64.lld' -diff -ru numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/utils/universal.py numpy-1.26.0/vendored-meson/meson/mesonbuild/utils/universal.py ---- numpy-1.26.0-orig/vendored-meson/meson/mesonbuild/utils/universal.py 1970-01-01 08:00:00 -+++ numpy-1.26.0/vendored-meson/meson/mesonbuild/utils/universal.py 2023-10-02 13:52:21 -@@ -133,6 +133,9 @@ - 'is_netbsd', - 'is_openbsd', - 'is_osx', -+ 'is_ios', -+ 'is_tvos', -+ 'is_watchos', - 'is_qnx', - 'is_sunos', - 'is_windows', -@@ -626,6 +629,18 @@ - - def is_osx() -> bool: - return platform.system().lower() == 'darwin' -+ -+ -+def is_ios() -> bool: -+ return platform.system().lower() == 'ios' -+ -+ -+def is_tvos() -> bool: -+ return platform.system().lower() == 'tvos' -+ -+ -+def is_watchos() -> bool: -+ return platform.system().lower() == 'watchos' - - - def is_linux() -> bool: -diff -ru numpy-1.26.0-orig/vendored-meson/meson-python/mesonpy/__init__.py numpy-1.26.0/vendored-meson/meson-python/mesonpy/__init__.py ---- numpy-1.26.0-orig/vendored-meson/meson-python/mesonpy/__init__.py 1970-01-01 08:00:00 -+++ numpy-1.26.0/vendored-meson/meson-python/mesonpy/__init__.py 2023-10-03 14:33:05 -@@ -665,7 +665,8 @@ - self._install_dir.mkdir(exist_ok=True, parents=True) - - # setuptools-like ARCHFLAGS environment variable support -- if sysconfig.get_platform().startswith('macosx-'): -+ sysconfig_platform = sysconfig.get_platform() -+ if sysconfig_platform.startswith('macosx-'): - archflags = os.environ.get('ARCHFLAGS', '').strip() - if archflags: - arch, *other = filter(None, (x.strip() for x in archflags.split('-arch'))) -@@ -689,6 +690,34 @@ - ''') - 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("-")[-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("CXX")!r}] -+ -+ [host_machine] -+ system = 'ios' -+ cpu = {arch!r} -+ cpu_family = {family!r} -+ endian = 'little' -+ -+ [properties] -+ longdouble_format = 'IEEE_DOUBLE_LE' -+ """ -+ ) -+ self._meson_cross_file.write_text(cross_file_data) -+ self._meson_args["setup"].extend( -+ ( -+ # Include the Meson cross-compilation file -+ "--cross-file", os.fspath(self._meson_cross_file), -+ # Disable BLAS -+ "-Dallow-noblas=true", -+ ) -+ ) - - # load pyproject.toml - pyproject = tomllib.loads(self._source_dir.joinpath('pyproject.toml').read_text()) \ No newline at end of file diff --git a/recipes/numpy/recipe.yaml b/recipes/numpy/recipe.yaml index 0a36d5e..9b9c528 100644 --- a/recipes/numpy/recipe.yaml +++ b/recipes/numpy/recipe.yaml @@ -1,2 +1,101 @@ package: - name: numpy \ No newline at end of file + name: numpy + # version: "" # Optional: leave empty to use latest + +# Pip dependencies needed for building numpy +# Based on void-linux and conda-forge configurations: +# - Cython: Required for building numpy's extension modules +# - meson-python: Build backend (numpy uses meson build system since 1.26+) +# - build: PEP 517 build frontend (conda-forge uses python -m build) +pip_dependencies: + - Cython + - meson-python + - build + +host_dependencies: + - python3-dev + - cmake + +# Environment variables for the build +# PKG_CONFIG="" prevents finding host system libraries during cross-compilation +# This is critical for mobile cross-compilation to avoid linking against host libs +cibw_environment: + LDFLAGS: "-lm" +# PKG_CONFIG: "" + +# Build script to set up cross-compilation +# For mobile platforms, we create a builddir and meson cross file +cibw_before_all: | + # Create build directory following conda-forge pattern + mkdir -p builddir + echo "Setting up numpy build for $CIBW_PLATFORM..." + + # Create meson cross file for mobile platforms + if [ "$CIBW_PLATFORM" = "android" ] || [ "$CIBW_PLATFORM" = "ios" ]; then + echo "Building for mobile platform: $CIBW_PLATFORM with architecture: $CIBW_ARCHS" + echo "Using no-BLAS mode for simplified mobile builds" + + # Determine CPU architecture for meson cross file + case "$CIBW_ARCHS" in + arm64*|aarch64) + CPU="aarch64" + CPU_FAMILY="aarch64" + ;; + x86_64) + CPU="x86_64" + CPU_FAMILY="x86_64" + ;; + armv7*|arm) + CPU="armv7" + CPU_FAMILY="arm" + ;; + x86|i686) + CPU="i686" + CPU_FAMILY="x86" + ;; + *) + CPU="$CIBW_ARCHS" + CPU_FAMILY="$CIBW_ARCHS" + ;; + esac + + # Create meson cross file with sanity checks disabled + # Using /tmp for cross-platform compatibility + CROSS_FILE="/tmp/numpy_meson_cross.txt" + cat > "$CROSS_FILE" << 'CROSSEOF' + [binaries] + c = '${CC:-cc}' + cpp = '${CXX:-c++}' + + [host_machine] + system = '$CIBW_PLATFORM' + cpu_family = '$CPU_FAMILY' + cpu = '$CPU' + endian = 'little' + + [properties] + skip_sanity_check = true + longdouble_format = 'IEEE_DOUBLE_LE' + CROSSEOF + + # Substitute variables in the cross file + sed -i "s/\${CC:-cc}/${CC:-cc}/g" "$CROSS_FILE" + sed -i "s/\${CXX:-c++}/${CXX:-c++}/g" "$CROSS_FILE" + sed -i "s/\$CIBW_PLATFORM/$CIBW_PLATFORM/g" "$CROSS_FILE" + sed -i "s/\$CPU_FAMILY/$CPU_FAMILY/g" "$CROSS_FILE" + sed -i "s/\$CPU/$CPU/g" "$CROSS_FILE" + + echo "Created meson cross file at $CROSS_FILE:" + cat "$CROSS_FILE" + fi + +# CIBW config settings to pass to meson-python +# Based on void-linux and conda-forge build configurations: +# - builddir=builddir: Use separate build directory (conda-forge pattern) +# - allow-noblas=true: Build without BLAS/LAPACK for simpler mobile builds +# - disable-svml=true: Disable Intel SVML for ARM portability (void-linux pattern) +# - Cross file at /tmp/numpy_meson_cross.txt with skip_sanity_check=true for mobile builds +# +# Note: Tests are skipped by default in cibuildwheel (no CIBW_TEST_COMMAND set) +# This matches the "disable sanity checks" requirement for mobile builds +cibw_config_settings: builddir=builddir setup-args=--cross-file=/tmp/numpy_meson_cross.txt setup-args=-Dallow-noblas=true setup-args=-Ddisable-svml=true