From ec5fb7dab05b2f754ae9a4031c08f6b949abb1da Mon Sep 17 00:00:00 2001 From: O01eg Date: Fri, 30 Jan 2026 07:46:31 +0400 Subject: [PATCH 01/11] Fix and test Android build --- .github/workflows/CI.yml | 71 ++++++++++++++++++++++++++++++++++++ .github/workflows/adb-emu.sh | 9 +++++ 2 files changed, 80 insertions(+) create mode 100755 .github/workflows/adb-emu.sh diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 552b404f7..9a390a3e8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -60,10 +60,81 @@ jobs: CC: ${{ matrix.c-compiler }} CXX: ${{ matrix.cxx-compiler }} + tests-android: + runs-on: ${{ matrix.host }} + strategy: + matrix: + ndk-arch: [x86_64] + arch: [x86_64] + api-level: [21] + target: [default] + host: [ubuntu-24.04] + python-version: [3.11.12] + include: + - ndk-arch: arm64-v8a + arch: x86_64 + api-level: 30 + target: google_apis + host: ubuntu-24.04 + python-version: 3.11.12 + - ndk-arch: x86 + arch: x86 + api-level: 21 + target: default + host: ubuntu-24.04 + python-version: 3.11.12 + - ndk-arch: armeabi-v7a + arch: x86_64 + api-level: 30 + target: google_apis + host: ubuntu-24.04 + python-version: 3.11.12 + name: python-android-${{ matrix.python-version }}-${{ matrix.host }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + path: src + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Make build and prefix directories + run: | + mkdir build + mkdir install-prefix + - name: run action + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: ${{ matrix.target }} + arch: ${{ matrix.arch }} + profile: Galaxy Nexus + cores: 2 + ram-size: 2048M + sdcard-path-or-size: 100M + emulator-build: 7425822 # https://github.com/ReactiveCircus/android-emulator-runner/issues/160 + avd-name: test + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + working-directory: build/ + ndk: 23.0.7421159 + cmake: 3.10.2.4988404 + channel: beta + script: | + adb devices + cmake -DANDROID_NDK=/usr/local/lib/android/sdk/ndk/23.0.7421159/ -DCMAKE_INSTALL_PREFIX:PATH=../install-prefix -DCMAKE_TOOLCHAIN_FILE=/usr/local/lib/android/sdk/ndk/23.0.7421159/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.ndk-arch }} -DCMAKE_CROSSCOMPILING_EMULATOR=$(pwd)/../src/.github/workflows/adb-emu.sh -DANDROID_ALLOW_UNDEFINED_SYMBOLS=On -DENABLE_DECIMAL=Off -DENABLE_CTYPES=Off -DENABLE_CODECS_JP=OFF -DENABLE_CODECS_KR=OFF -DENABLE_CODECS_TW=OFF -DENABLE_MULTIBYTECODEC=OFF -DENABLE_CODECS_CN=OFF -DENABLE_CODECS_HK=OFF -DENABLE_CODECS_ISO2022=OFF -DBUILD_EXTENSIONS_AS_BUILTIN=On -DANDROID_PLATFORM=android-21 -DPYTHON_VERSION=${{ matrix.python-version }} $(pwd)/../src/ + cmake --build . -- VERBOSE=1 + cmake --build . --target install + + pass: # This job does nothing and is only used for the branch protection if: always() needs: - tests + - tests-android runs-on: ubuntu-latest diff --git a/.github/workflows/adb-emu.sh b/.github/workflows/adb-emu.sh new file mode 100755 index 000000000..d5e849f97 --- /dev/null +++ b/.github/workflows/adb-emu.sh @@ -0,0 +1,9 @@ +#!/bin/sh +adb push "$1" /data/local/tmp/ 1>/dev/null 2>/dev/null +if [ $# -eq 1 ]; then + adb shell /data/local/tmp/$(basename $1) +elif [ $# -eq 3 ]; then + adb push "$2" /data/local/tmp/ 1>/dev/null 2>/dev/null + adb shell /data/local/tmp/$(basename $1) /data/local/tmp/$(basename $2) /data/local/tmp/$(basename $3) + adb pull /data/local/tmp/$(basename $3) "$3" 1>/dev/null 2>/dev/null +fi From 79a8d4a488f4b86d5ceb43d5b0ff7def201250c2 Mon Sep 17 00:00:00 2001 From: O01eg Date: Fri, 30 Jan 2026 08:02:45 +0400 Subject: [PATCH 02/11] Make it buildable --- cmake/ConfigureChecks.cmake | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index 5ed2c5b7a..542dbf543 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -356,7 +356,11 @@ check_include_files(grp.h HAVE_GRP_H) check_include_files(ieeefp.h HAVE_IEEEFP_H) check_include_files(inttypes.h HAVE_INTTYPES_H) # libffi and cpython check_include_files(io.h HAVE_IO_H) -check_include_files(langinfo.h HAVE_LANGINFO_H) +if (ANDROID) + set(HAVE_LANGINFO_H 0) # Android cann't link functions from langinfo.h +else() + check_include_files(langinfo.h HAVE_LANGINFO_H) +endif() check_include_files(libintl.h HAVE_LIBINTL_H) check_include_files(libutil.h HAVE_LIBUTIL_H) check_include_files(linux/tipc.h HAVE_LINUX_TIPC_H) @@ -532,7 +536,7 @@ find_library(HAVE_LIBTERMCAP termcap) set(LIBUTIL_LIBRARIES ) set(LIBUTIL_EXPECTED 1) -if(CMAKE_SYSTEM MATCHES "VxWorks\\-7$") +if(ANDROID OR CMAKE_SYSTEM MATCHES "VxWorks\\-7$") set(LIBUTIL_EXPECTED 0) set(HAVE_LIBUTIL 0) endif() From 6c61e9b85f46d59187a71c1a345f8ca3f9614623 Mon Sep 17 00:00:00 2001 From: O01eg Date: Fri, 30 Jan 2026 08:16:44 +0400 Subject: [PATCH 03/11] Use working Python 3.10 --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9a390a3e8..e9461d6d4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -69,26 +69,26 @@ jobs: api-level: [21] target: [default] host: [ubuntu-24.04] - python-version: [3.11.12] + python-version: [3.10.17] include: - ndk-arch: arm64-v8a arch: x86_64 api-level: 30 target: google_apis host: ubuntu-24.04 - python-version: 3.11.12 + python-version: 3.10.17 - ndk-arch: x86 arch: x86 api-level: 21 target: default host: ubuntu-24.04 - python-version: 3.11.12 + python-version: 3.10.17 - ndk-arch: armeabi-v7a arch: x86_64 api-level: 30 target: google_apis host: ubuntu-24.04 - python-version: 3.11.12 + python-version: 3.10.17 name: python-android-${{ matrix.python-version }}-${{ matrix.host }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 From fbdcfd129ce072eca5246e7a9dc8cd80a5df10d4 Mon Sep 17 00:00:00 2001 From: Victor Paleologue Date: Fri, 17 Apr 2020 18:20:40 +0200 Subject: [PATCH 04/11] Fix floating point endianness checks Translated to CMake from a patch on the Yocto project: http://cgit.openembedded.org/openembedded-core/tree/meta/recipes-devtools/python/python3/0002-Don-t-do-runtime-test-to-get-float-byte-order.patch?h=zeus It avoids the execution of a program on the target device, and produces a clearer endianness result. --- cmake/ConfigureChecks.cmake | 80 ++++++++++++++----------------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index 542dbf543..ecde8b91d 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -1302,60 +1302,38 @@ python_platform_test( # Check for various properties of floating point # ####################################################################### - -# Check whether C doubles are little-endian IEEE 754 binary64 -set(check_src ${PROJECT_BINARY_DIR}/CMakeFiles/ac_cv_little_endian_double.c) -file(WRITE ${check_src} "#include -int main() { - double x = 9006104071832581.0; - if (memcmp(&x, \"\\x05\\x04\\x03\\x02\\x01\\xff\\x3f\\x43\", 8) == 0) - return 0; - else - return 1; -} -") -python_platform_test_run( - DOUBLE_IS_LITTLE_ENDIAN_IEEE754 - "Checking whether C doubles are little-endian IEEE 754 binary64" - ${check_src} - DIRECT - ) - -# Check whether C doubles are big-endian IEEE 754 binary64 set(check_src ${PROJECT_BINARY_DIR}/CMakeFiles/ac_cv_big_endian_double.c) -file(WRITE ${check_src} "#include -int main() { - double x = 9006104071832581.0; - if (memcmp(&x, \"\\x43\\x3f\\xff\\x01\\x02\\x03\\x04\\x05\", 8) == 0) - return 0; - else - return 1; -} +file(WRITE ${check_src} " +double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; ") -python_platform_test_run( - DOUBLE_IS_BIG_ENDIAN_IEEE754 - "Checking whether C doubles are big-endian IEEE 754 binary64" - ${check_src} - DIRECT - ) -# Check whether C doubles are ARM mixed-endian IEEE 754 binary64 -set(check_src ${PROJECT_BINARY_DIR}/CMakeFiles/ac_cv_mixed_endian_double.c) -file(WRITE ${check_src} "#include -int main() { - double x = 9006104071832581.0; - if (memcmp(&x, \"\\x01\\xff\\x3f\\x43\\x05\\x04\\x03\\x02\", 8) == 0) - return 0; - else - return 1; -} -") -python_platform_test_run( - DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 - "Checking doubles are ARM mixed-endian IEEE 754 binary64" - ${check_src} - DIRECT - ) +# TODO: factorize this try_compile statement +try_compile(DOUBLE_BIG_ENDIAN_TEST_COMPILED + ${CMAKE_CURRENT_BINARY_DIR} + ${check_src} + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}" + "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}" + COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/double_big_endian.bin) + +if(DOUBLE_BIG_ENDIAN_TEST_COMPILED) + file(READ ${CMAKE_CURRENT_BINARY_DIR}/double_big_endian.bin DOUBLE_BIG_ENDIAN_DATA) + string(FIND ${DOUBLE_BIG_ENDIAN_DATA} "noonsees" NOONSEES) + if(NOONSEES) + set(DOUBLE_IS_BIG_ENDIAN_IEEE754 1) + set(DOUBLE_IS_LITTLE_ENDIAN_IEEE754 0) + else() + string(FIND ${DOUBLE_BIG_ENDIAN_DATA} "seesnoon" SEESNOON) + if(SEESNOON) + set(DOUBLE_IS_BIG_ENDIAN_IEEE754 0) + set(DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1) + else() + message(WARNING "Could not determine if double precision floats endianness") + endif() + endif() +endif() # The short float repr introduced in Python 3.1 requires the # correctly-rounded string <-> double conversion functions from From 392b46bb6adcfc219145fa2245a66f9eac0ddc26 Mon Sep 17 00:00:00 2001 From: O01eg Date: Sat, 31 Jan 2026 01:13:50 +0400 Subject: [PATCH 05/11] Don't build fcntl and grp extensions for Android --- cmake/extensions/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/extensions/CMakeLists.txt b/cmake/extensions/CMakeLists.txt index 10750ccce..4005dead5 100644 --- a/cmake/extensions/CMakeLists.txt +++ b/cmake/extensions/CMakeLists.txt @@ -417,9 +417,11 @@ add_python_extension(_xxsubinterpreters ${WIN32_BUILTIN} _xxsubinterpretersmodule.c ) -# UNIX-only extensions -add_python_extension(fcntl REQUIRES UNIX SOURCES fcntlmodule.c) -add_python_extension(grp REQUIRES UNIX SOURCES grpmodule.c) +if(NOT ANDROID) + # UNIX-only extensions + add_python_extension(fcntl REQUIRES UNIX SOURCES fcntlmodule.c) + add_python_extension(grp REQUIRES UNIX SOURCES grpmodule.c) +endif() set(nis_REQUIRES UNIX HAVE_LIBNSL) set(nis_LIBRARIES ${HAVE_LIBNSL}) From b3ecef464b35972f3cf6037f5ec70ec023dd1994 Mon Sep 17 00:00:00 2001 From: O01eg Date: Sat, 31 Jan 2026 01:16:38 +0400 Subject: [PATCH 06/11] Don't generate sysconfigdata for Android --- cmake/python/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/python/CMakeLists.txt b/cmake/python/CMakeLists.txt index cfbe1a11d..60cda177a 100644 --- a/cmake/python/CMakeLists.txt +++ b/cmake/python/CMakeLists.txt @@ -47,7 +47,7 @@ if(WIN32) ) endif() -if(UNIX) +if(UNIX AND NOT ANDROID) # Setup landmark allowing to run the interpreter from a build tree. See 'getpath.c' for details. set(_sysconfigdata_py "_sysconfigdata.py") if("${PY_VERSION}" VERSION_GREATER_EQUAL "3.6.0") From 651dba6dbc26fe5d4658b6ce8f2bef20493079d6 Mon Sep 17 00:00:00 2001 From: O01eg Date: Sat, 31 Jan 2026 01:19:02 +0400 Subject: [PATCH 07/11] Add platform triplets for Android --- cmake/platform.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cmake/platform.c b/cmake/platform.c index 4c8278967..7530a33e3 100644 --- a/cmake/platform.c +++ b/cmake/platform.c @@ -18,16 +18,28 @@ char *PLATFORM_TRIPLET = #if defined(__linux__) # if defined(__x86_64__) && defined(__LP64__) +# if defined(__ANDROID_NDK__) + "x86_64-linux-android" +# else "x86_64-linux-gnu" +# endif # elif defined(__x86_64__) && defined(__ILP32__) "x86_64-linux-gnux32" # elif defined(__i386__) +# if defined(__ANDROID_NDK__) + "i686-linux-android" +# else "i386-linux-gnu" +# endif # elif defined(__aarch64__) && defined(__AARCH64EL__) # if defined(__ILP32__) "aarch64_ilp32-linux-gnu" # else +# if defined(__ANDROID_NDK__) + "aarch64-linux-android" +# else "aarch64-linux-gnu" +# endif # endif # elif defined(__aarch64__) && defined(__AARCH64EB__) # if defined(__ILP32__) @@ -45,7 +57,11 @@ char *PLATFORM_TRIPLET = # endif # elif defined(__ARM_EABI__) && !defined(__ARM_PCS_VFP) # if defined(__ARMEL__) +# if defined(__ANDROID_NDK__) + "arm-linux-androideabi" +# else "arm-linux-gnueabi" +# endif # else "armeb-linux-gnueabi" # endif From 4a8b9d1e9ce1827b010a5148e94a868981eb73da Mon Sep 17 00:00:00 2001 From: O01eg <397177+o01eg@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:51:29 +0400 Subject: [PATCH 08/11] Some more Android fixes --- CMakeLists.txt | 2 +- cmake/Extensions.cmake | 2 +- cmake/extensions/CMakeLists.txt | 1 + cmake/lib/CMakeLists.txt | 34 +++++++++++++++++---------------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 730e0fa21..8ada2539e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -799,7 +799,7 @@ if(UNIX) # Makefile set(MAKEFILE_LDSHARED_FLAGS "-shared") - if(APPLE) + if(APPLE OR ANDROID) set(MAKEFILE_LDSHARED_FLAGS "-dynamiclib -headerpad_max_install_names -undefined dynamic_lookup") endif() configure_file(cmake/makefile-variables.in diff --git a/cmake/Extensions.cmake b/cmake/Extensions.cmake index 45b63f236..c0edc2468 100644 --- a/cmake/Extensions.cmake +++ b/cmake/Extensions.cmake @@ -196,7 +196,7 @@ function(add_python_extension name) ) endif() - if(APPLE) + if(APPLE OR ANDROID) set_target_properties(${target_name} PROPERTIES LINK_FLAGS -Wl,-undefined,dynamic_lookup SUFFIX .so diff --git a/cmake/extensions/CMakeLists.txt b/cmake/extensions/CMakeLists.txt index 4005dead5..1cd1f6e70 100644 --- a/cmake/extensions/CMakeLists.txt +++ b/cmake/extensions/CMakeLists.txt @@ -836,6 +836,7 @@ elseif(${CMAKE_SIZEOF_VOID_P} EQUAL 4) if(HAVE_GCC_ASM_FOR_X87 AND (CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") AND NOT CMAKE_SYSTEM MATCHES SunOS + AND NOT ANDROID ) # solaris: problems with register allocation. # icc >= 11.0 works as well. diff --git a/cmake/lib/CMakeLists.txt b/cmake/lib/CMakeLists.txt index ac97ab4b3..5f62ecab3 100644 --- a/cmake/lib/CMakeLists.txt +++ b/cmake/lib/CMakeLists.txt @@ -37,20 +37,22 @@ endforeach() # Generate grammar tables in install directory # XXX Should a custom target be added to generate file at built time ? -install(CODE "find_program( - PYTHON_EXECUTABLE python - HINTS \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${BIN_INSTALL_DIR} - NO_DEFAULT_PATH) -set(wrapper) -if(UNIX) - set(_envvar LD_LIBRARY_PATH) - if(APPLE) - set(_envvar DYLD_LIBRARY_PATH) - endif() - set(wrapper env \${_envvar}=\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${LIBPYTHON_LIBDIR}) +if(NOT ANDROID) + install(CODE "find_program( + PYTHON_EXECUTABLE python + HINTS \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${BIN_INSTALL_DIR} + NO_DEFAULT_PATH) + set(wrapper) + if(UNIX) + set(_envvar LD_LIBRARY_PATH) + if(APPLE) + set(_envvar DYLD_LIBRARY_PATH) + endif() + set(wrapper env \${_envvar}=\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${LIBPYTHON_LIBDIR}) + endif() + execute_process(COMMAND \${wrapper} \${PYTHON_EXECUTABLE} -m lib2to3.pgen2.driver + \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PYTHONHOME}/lib2to3/Grammar.txt) + execute_process(COMMAND \${wrapper} \${PYTHON_EXECUTABLE} -m lib2to3.pgen2.driver + \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PYTHONHOME}/lib2to3/PatternGrammar.txt) + ") endif() -execute_process(COMMAND \${wrapper} \${PYTHON_EXECUTABLE} -m lib2to3.pgen2.driver - \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PYTHONHOME}/lib2to3/Grammar.txt) -execute_process(COMMAND \${wrapper} \${PYTHON_EXECUTABLE} -m lib2to3.pgen2.driver - \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PYTHONHOME}/lib2to3/PatternGrammar.txt) -") From cc787b00464f55b055f72b92adf6433cd06ea4d1 Mon Sep 17 00:00:00 2001 From: O01eg <397177+o01eg@users.noreply.github.com> Date: Wed, 18 Feb 2026 16:30:33 +0400 Subject: [PATCH 09/11] Reorganize CI for Android --- .github/workflows/CI.yml | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e9461d6d4..79aecb96c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -64,32 +64,10 @@ jobs: runs-on: ${{ matrix.host }} strategy: matrix: - ndk-arch: [x86_64] - arch: [x86_64] - api-level: [21] - target: [default] + ndk-arch: [x86_64, arm64-v8a, x86, armeabi-v7a] host: [ubuntu-24.04] - python-version: [3.10.17] - include: - - ndk-arch: arm64-v8a - arch: x86_64 - api-level: 30 - target: google_apis - host: ubuntu-24.04 - python-version: 3.10.17 - - ndk-arch: x86 - arch: x86 - api-level: 21 - target: default - host: ubuntu-24.04 - python-version: 3.10.17 - - ndk-arch: armeabi-v7a - arch: x86_64 - api-level: 30 - target: google_apis - host: ubuntu-24.04 - python-version: 3.10.17 - name: python-android-${{ matrix.python-version }}-${{ matrix.host }} + python-version: [3.8.20, 3.9.22, 3.10.17] + name: python-android-${{ matrix.ndk-arch }}-${{ matrix.python-version }}-${{ matrix.host }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -107,9 +85,9 @@ jobs: - name: run action uses: reactivecircus/android-emulator-runner@v2 with: - api-level: ${{ matrix.api-level }} - target: ${{ matrix.target }} - arch: ${{ matrix.arch }} + api-level: ${{ startsWith(matrix.ndk-arch, 'x86') && 21 || 30 }} + target: ${{ startsWith(matrix.ndk-arch, 'x86') && 'default' || 'google_apis' }} + arch: ${{ matrix.ndk-arch == 'x86' && 'x86' || 'x86_64' }} profile: Galaxy Nexus cores: 2 ram-size: 2048M From 0ef0e78cce5cb2ecddd058f50ec0cdf78fc52ed8 Mon Sep 17 00:00:00 2001 From: O01eg <397177+o01eg@users.noreply.github.com> Date: Wed, 18 Feb 2026 17:09:33 +0400 Subject: [PATCH 10/11] Don't install old CMake --- .github/workflows/CI.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 79aecb96c..e905b8a41 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -99,7 +99,6 @@ jobs: disable-animations: true working-directory: build/ ndk: 23.0.7421159 - cmake: 3.10.2.4988404 channel: beta script: | adb devices From 19943b8aaa4479bbb90ceac27212e598ed0723b1 Mon Sep 17 00:00:00 2001 From: O01eg <397177+o01eg@users.noreply.github.com> Date: Sun, 3 May 2026 10:22:36 +0400 Subject: [PATCH 11/11] Add Python 3.11.12 to Android CI workflow and fix it --- .github/workflows/CI.yml | 25 +++++++++++++++++++++++-- .github/workflows/adb-emu.sh | 14 +++++++++++--- CMakeLists.txt | 22 ++++++++++++++++++++++ cmake/extensions/CMakeLists.txt | 22 ++++++++++++---------- cmake/libpython/CMakeLists.txt | 4 +++- 5 files changed, 71 insertions(+), 16 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e905b8a41..1275f9938 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -66,7 +66,7 @@ jobs: matrix: ndk-arch: [x86_64, arm64-v8a, x86, armeabi-v7a] host: [ubuntu-24.04] - python-version: [3.8.20, 3.9.22, 3.10.17] + python-version: [3.8.20, 3.9.22, 3.10.17, 3.11.12] name: python-android-${{ matrix.ndk-arch }}-${{ matrix.python-version }}-${{ matrix.host }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -82,6 +82,27 @@ jobs: run: | mkdir build mkdir install-prefix + mkdir bootstrap-build + mkdir bootstrap-install-prefix + - name: Check for bootstrap needed + id: check-bootstrap + shell: cmake -P {0} + run: | + string(REPLACE "." ";" VERSION_LIST "${{ matrix.python-version }}") + list(GET VERSION_LIST 0 PY_VERSION_MAJOR) + list(GET VERSION_LIST 1 PY_VERSION_MINOR) + list(GET VERSION_LIST 2 PY_VERSION_PATCH) + set(PY_VERSION "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}.${PY_VERSION_PATCH}") + if(PY_VERSION VERSION_GREATER_EQUAL "3.11") + file(APPEND "$ENV{GITHUB_OUTPUT}" "needed=yes") + endif() + - name: Bootstrap + if: steps.check-bootstrap.outputs.needed == 'yes' + run: | + cd bootstrap-build + cmake -DCMAKE_INSTALL_PREFIX:PATH=../bootstrap-install-prefix -DPYTHON_VERSION=${{ matrix.python-version }} $(pwd)/../src/ + cmake --build . -- VERBOSE=1 + cmake --build . --target install - name: run action uses: reactivecircus/android-emulator-runner@v2 with: @@ -102,7 +123,7 @@ jobs: channel: beta script: | adb devices - cmake -DANDROID_NDK=/usr/local/lib/android/sdk/ndk/23.0.7421159/ -DCMAKE_INSTALL_PREFIX:PATH=../install-prefix -DCMAKE_TOOLCHAIN_FILE=/usr/local/lib/android/sdk/ndk/23.0.7421159/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.ndk-arch }} -DCMAKE_CROSSCOMPILING_EMULATOR=$(pwd)/../src/.github/workflows/adb-emu.sh -DANDROID_ALLOW_UNDEFINED_SYMBOLS=On -DENABLE_DECIMAL=Off -DENABLE_CTYPES=Off -DENABLE_CODECS_JP=OFF -DENABLE_CODECS_KR=OFF -DENABLE_CODECS_TW=OFF -DENABLE_MULTIBYTECODEC=OFF -DENABLE_CODECS_CN=OFF -DENABLE_CODECS_HK=OFF -DENABLE_CODECS_ISO2022=OFF -DBUILD_EXTENSIONS_AS_BUILTIN=On -DANDROID_PLATFORM=android-21 -DPYTHON_VERSION=${{ matrix.python-version }} $(pwd)/../src/ + cmake -DANDROID_NDK=/usr/local/lib/android/sdk/ndk/23.0.7421159/ -DCMAKE_INSTALL_PREFIX:PATH=../install-prefix -DCMAKE_TOOLCHAIN_FILE=/usr/local/lib/android/sdk/ndk/23.0.7421159/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.ndk-arch }} -DCMAKE_CROSSCOMPILING_EMULATOR=$(pwd)/../src/.github/workflows/adb-emu.sh -DANDROID_ALLOW_UNDEFINED_SYMBOLS=On -DENABLE_DECIMAL=Off -DENABLE_CTYPES=Off -DENABLE_CODECS_JP=OFF -DENABLE_CODECS_KR=OFF -DENABLE_CODECS_TW=OFF -DENABLE_MULTIBYTECODEC=OFF -DENABLE_CODECS_CN=OFF -DENABLE_CODECS_HK=OFF -DENABLE_CODECS_ISO2022=OFF -DBUILD_EXTENSIONS_AS_BUILTIN=On -DANDROID_PLATFORM=android-21 -DPYTHON_VERSION=${{ matrix.python-version }} -DBUILD_PYTHON=../bootstrap-install-prefix/bin/python $(pwd)/../src/ cmake --build . -- VERBOSE=1 cmake --build . --target install diff --git a/.github/workflows/adb-emu.sh b/.github/workflows/adb-emu.sh index d5e849f97..f7336503d 100755 --- a/.github/workflows/adb-emu.sh +++ b/.github/workflows/adb-emu.sh @@ -1,9 +1,17 @@ #!/bin/sh adb push "$1" /data/local/tmp/ 1>/dev/null 2>/dev/null +BINARY=$(basename "$1") if [ $# -eq 1 ]; then - adb shell /data/local/tmp/$(basename $1) + adb shell "/data/local/tmp/${BINARY}" elif [ $# -eq 3 ]; then adb push "$2" /data/local/tmp/ 1>/dev/null 2>/dev/null - adb shell /data/local/tmp/$(basename $1) /data/local/tmp/$(basename $2) /data/local/tmp/$(basename $3) - adb pull /data/local/tmp/$(basename $3) "$3" 1>/dev/null 2>/dev/null + adb shell "/data/local/tmp/${BINARY}" "/data/local/tmp/$(basename $2)" "/data/local/tmp/$(basename $3)" + adb pull "/data/local/tmp/$(basename $3)" "$3" 1>/dev/null 2>/dev/null +elif [ $# -eq 4 ] && [ "${BINARY}" = "_freeze_importlib" ]; then + adb push "$3" /data/local/tmp/ 1>/dev/null 2>/dev/null + adb shell "/data/local/tmp/${BINARY}" "$2" "/data/local/tmp/$(basename $3)" "/data/local/tmp/$(basename $4)" + adb pull "/data/local/tmp/$(basename $4)" "$4" 1>/dev/null 2>/dev/null +else + echo "Unknown number of arguments $# for ${BINARY}" + exit 1 fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ada2539e..7cabf83cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,28 @@ else() set(WITH_STATIC_DEPENDENCIES 0) endif() +if(ANDROID AND PY_VERSION VERSION_GREATER_EQUAL "3.11") + set(BUILD_PYTHON "" CACHE PATH "path to build ``python`` binary for cross compiling") + if(NOT BUILD_PYTHON) + message(FATAL_ERROR "Cross compiling requires -DBUILD_PYTHON=") + endif() + if(NOT EXISTS ${BUILD_PYTHON}) + message(FATAL_ERROR "invalid or missing build python binary ${BUILD_PYTHON}") + endif() + execute_process( + COMMAND ${BUILD_PYTHON} -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" + OUTPUT_VARIABLE BUILD_PYTHON_VER + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE BUILD_PYTHON_EXEC_RESULT + ) + if(NOT BUILD_PYTHON_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "can not execute build python binary ${BUILD_PYTHON}") + endif() + if(NOT "${BUILD_PYTHON_VER}" STREQUAL "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}") + message(FATAL_ERROR "\"${BUILD_PYTHON}\" has incompatible version ${BUILD_PYTHON_VER} (expected: ${PY_VERSION_MAJOR}.${PY_VERSION_MINOR})") + endif() +endif() + # Detect source directory set(_landmark "pyconfig.h.in") # CMake will look for this file. if(NOT (SRC_DIR AND EXISTS ${SRC_DIR}/${_landmark})) diff --git a/cmake/extensions/CMakeLists.txt b/cmake/extensions/CMakeLists.txt index 1cd1f6e70..10f3245dd 100644 --- a/cmake/extensions/CMakeLists.txt +++ b/cmake/extensions/CMakeLists.txt @@ -373,16 +373,18 @@ add_python_extension(_xxtestfuzz _xxtestfuzz/fuzzer.c ) -# Python 3.8 -set(_wide_char_modifier "L") -add_python_extension(_testinternalcapi - REQUIRES - IS_PY3_8_OR_GREATER - SOURCES - _testinternalcapi.c - DEFINITIONS - "PY3_DLLNAME=${_wide_char_modifier}\"python3$<$:_d>\"" -) +if (NOT ANDROID) + # Python 3.8 + set(_wide_char_modifier "L") + add_python_extension(_testinternalcapi + REQUIRES + IS_PY3_8_OR_GREATER + SOURCES + _testinternalcapi.c + DEFINITIONS + "PY3_DLLNAME=${_wide_char_modifier}\"python3$<$:_d>\"" + ) +endif() # Python 3.9 add_python_extension(_peg_parser ALWAYS_BUILTIN diff --git a/cmake/libpython/CMakeLists.txt b/cmake/libpython/CMakeLists.txt index c344b674f..b7124d3e5 100644 --- a/cmake/libpython/CMakeLists.txt +++ b/cmake/libpython/CMakeLists.txt @@ -744,6 +744,7 @@ set(LIBPYTHON_DEEPFREEZE_SOURCES ) if(PY_VERSION VERSION_GREATER_EQUAL "3.11") +if(NOT ANDROID) # Build _bootstrap_python executable add_executable(_bootstrap_python ${SRC_DIR}/Programs/_bootstrap_python.c @@ -763,6 +764,7 @@ target_compile_definitions(_bootstrap_python PUBLIC Py_NO_ENABLE_SHARED ) +endif() list(APPEND LIBPYTHON_DEEPFREEZE_SOURCES ${SRC_DIR}/Python/deepfreeze/deepfreeze.c @@ -773,7 +775,7 @@ set(DEEPFREEZE_PY ${SRC_DIR}/Tools/$,${BUILD_PYTHON},_bootstrap_python> ${DEEPFREEZE_PY} "${SRC_DIR}/Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap" "${SRC_DIR}/Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external"