diff --git a/.github/workflows/build-wheels-with-cibuildwheel.yml b/.github/workflows/build-wheels-with-cibuildwheel.yml deleted file mode 100644 index 42129b0..0000000 --- a/.github/workflows/build-wheels-with-cibuildwheel.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: wheels-android - -on: - workflow_dispatch: - -env: - UV_PYTHON: "3.12" # cibuildwheel runner python; not the target - -jobs: - build_android_wheels: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup uv - uses: astral-sh/setup-uv@v6 - - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: "17" - - - name: Set up Android SDK - uses: android-actions/setup-android@v3 - - - name: Build Android wheels - env: - CIBW_PLATFORM: android - CIBW_BUILD: "cp313-android_*" - CIBW_ARCHS_ANDROID: "arm64_v8a x86_64" - ANDROID_API_LEVEL: "24" - run: | - wget https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz - tar xf websockets-16.0.tar.gz - cd websockets-16.0 - uvx cibuildwheel --output-dir wheelhouse - - - uses: actions/upload-artifact@v4 - with: - name: wheels-android - path: websockets-16.0/wheelhouse/*.whl \ No newline at end of file diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 14a1807..4887cae 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -19,7 +19,7 @@ on: default: false env: - UV_PYTHON: "3.12.12" + UV_PYTHON: "3.12.13" MOBILE_FORGE_CACHE_DOWNLOADS_OFF: "1" NDK_VERSION: r27d @@ -155,7 +155,7 @@ jobs: rm -f dist/bzip2-* dist/libffi-* dist/mpdecimal-* dist/openssl-* dist/sqlite-* dist/xz-* - name: Publish wheels - if: ${{ hashFiles('dist/*.whl') != '' && (inputs.publish || (github.event_name == 'push' && github.ref == 'refs/heads/python3.12')) }} + if: ${{ hashFiles('dist/*.whl') != '' && (inputs.publish || (github.event_name == 'push' && github.ref == 'refs/heads/main')) }} shell: bash env: GEMFURY_TOKEN: ${{ secrets.GEMFURY_TOKEN }} diff --git a/recipes/cryptography/meta.yaml b/recipes/cryptography/meta.yaml index a64edca..9563932 100644 --- a/recipes/cryptography/meta.yaml +++ b/recipes/cryptography/meta.yaml @@ -1,6 +1,12 @@ package: name: cryptography +# cryptography 43.0.1 pins pyo3 0.22.2 which hard-stops at Python 3.13. +# 48.0.0 moves to pyo3 0.28 (knows 3.14) and classifies 3.14 as supported. +# {% if py_version.minor >= 14 %} + version: 48.0.0 +# {% else %} version: 43.0.1 +# {% endif %} requirements: host: diff --git a/recipes/pydantic-core/meta.yaml b/recipes/pydantic-core/meta.yaml index cb3ef62..46ea247 100644 --- a/recipes/pydantic-core/meta.yaml +++ b/recipes/pydantic-core/meta.yaml @@ -1,6 +1,6 @@ package: name: pydantic-core - version: 2.33.2 + version: 2.47.0 build: number: 4 diff --git a/setup.sh b/setup.sh index 1201bc0..4da2c8b 100755 --- a/setup.sh +++ b/setup.sh @@ -32,12 +32,33 @@ fi PYTHON_VERSION=$1 PYTHON_VER="${PYTHON_VERSION%.*}" +python_version_minor="${PYTHON_VER#*.}" echo "Python version: $PYTHON_VERSION" echo "Python short version: $PYTHON_VER" +# Per-version support-path overrides: MOBILE_FORGE_{IOS,ANDROID}_SUPPORT_PATH__ +# (e.g. MOBILE_FORGE_IOS_SUPPORT_PATH_3_13). When set, they take precedence over +# the unversioned variable for this session, so .envrc can declare paths for +# 3.12 / 3.13 / 3.14 side-by-side and `source ./setup.sh ` picks the right one. +versioned_suffix="${PYTHON_VER//./_}" +ios_versioned_var="MOBILE_FORGE_IOS_SUPPORT_PATH_${versioned_suffix}" +android_versioned_var="MOBILE_FORGE_ANDROID_SUPPORT_PATH_${versioned_suffix}" +# Indirect variable expansion: bash uses ${!var}, zsh uses ${(P)var}. +# `eval` is the portable form that works in both. +eval "ios_versioned_val=\${$ios_versioned_var:-}" +eval "android_versioned_val=\${$android_versioned_var:-}" +if [ -n "$ios_versioned_val" ]; then + export MOBILE_FORGE_IOS_SUPPORT_PATH="$ios_versioned_val" +fi +if [ -n "$android_versioned_val" ]; then + export MOBILE_FORGE_ANDROID_SUPPORT_PATH="$android_versioned_val" +fi + if [[ -z "$MOBILE_FORGE_IOS_SUPPORT_PATH" && -z "$MOBILE_FORGE_ANDROID_SUPPORT_PATH" ]]; then echo "Neither MOBILE_FORGE_IOS_SUPPORT_PATH nor MOBILE_FORGE_ANDROID_SUPPORT_PATH are defined." + echo "Set MOBILE_FORGE_{IOS,ANDROID}_SUPPORT_PATH or per-version overrides" + echo "MOBILE_FORGE_{IOS,ANDROID}_SUPPORT_PATH_${versioned_suffix}." return fi @@ -106,7 +127,7 @@ if [ ! -z "$MOBILE_FORGE_ANDROID_SUPPORT_PATH" ]; then return fi - if [ "$PYTHON_VER" = "3.12" ]; then + if [ "$python_version_minor" -lt 13 ]; then if [ ! -e $MOBILE_FORGE_ANDROID_SUPPORT_PATH/install/android/armeabi-v7a/python-$PYTHON_VERSION/bin/python$PYTHON_VER ]; then echo "MOBILE_FORGE_ANDROID_SUPPORT_PATH does not appear to contain a Python $PYTHON_VERSION Android armeabi-v7a device binary." return diff --git a/src/forge/build.py b/src/forge/build.py index ef7da5c..76c6917 100644 --- a/src/forge/build.py +++ b/src/forge/build.py @@ -359,6 +359,15 @@ def compile_env(self, **kwargs) -> dict[str, str]: # cargo_ldflags = re.sub(r"-march=[\w-]+", "", ldflags) cargo_ldflags = " -L{}/lib".format(self.cross_venv.sysconfig_data["prefix"]) + # On Android, pyo3-ffi (and similar) link `-lpython3` / `-lpython3.`. + # PYO3_CROSS_LIB_DIR points at the host stdlib directory (so maturin can + # find _sysconfigdata__*.py and build-details.json there), but the + # actual `libpython*.so` files live in the host install's `lib/` + # directory (LIBDIR). Add LIBDIR as an extra library search path so the + # linker can resolve those `-lpython*` references. + host_libdir = self.cross_venv.sysconfig_data.get("LIBDIR") + if host_libdir: + cargo_ldflags += f" -L{host_libdir}" cargo_ldflags += " -C link-arg=-undefined -C link-arg=dynamic_lookup" if self.cross_venv.sdk == "android":