diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 0ca6c2fd..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,297 +0,0 @@ -skip_branch_with_pr: true - -environment: - FLUTTER_VERSION: 3.29.3 - GITHUB_TOKEN: - secure: 9SKIwc3VSfYJ5IChvNR74mEv2nb0ZFftUzn3sGRdXipXEfKSxY50DoodChHvlqZduQNhjg0oyLWAAa3n+iwWvVM2yI7Cgb14lFNClijz/kHI/PibnjDMNvLKaAygcfAc - - matrix: - - job_name: Test on macOS - job_group: test_serious_python - job_depends_on: build_python_darwin - APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey - - - job_name: Test on iOS - job_group: test_serious_python - job_depends_on: build_python_darwin - APPVEYOR_BUILD_WORKER_IMAGE: macos-ventura - - - job_name: Test on Android - job_group: test_serious_python - job_depends_on: build_python_android - APPVEYOR_BUILD_WORKER_IMAGE: ubuntu-gce-c - - - job_name: Test on Windows - job_group: test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - - - job_name: Test on Linux - job_group: test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: ubuntu2004 - - - job_name: Test on Linux ARM64 - job_group: test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: ubuntu2204-arm - - - job_name: Publish serious_python package to pub.dev - job_group: publish_package - job_depends_on: build_python, test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 - -stack: -- python 3.12 - -for: - # ====================================== - # Test on macOS - # ====================================== - - - matrix: - only: - - job_name: Test on macOS - - install: - - HOMEBREW_NO_AUTO_UPDATE=1 brew install cocoapods - - source ci/install_flutter.sh - - flutter config --enable-macos-desktop - - flutter doctor -v - - xcodebuild -version - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Darwin -r flet - - flutter test integration_test -d macos - - # ====================================== - # Test on iOS - # ====================================== - - - matrix: - only: - - job_name: Test on iOS - - install: - - HOMEBREW_NO_AUTO_UPDATE=1 brew install cocoapods - - source ci/install_flutter.sh - # - xcrun simctl list runtimes - # - xcrun simctl create "e2e test" "iPhone 12" "com.apple.CoreSimulator.SimRuntime.iOS-17-2" - # - xcrun xctrace list devices - # - | - # UDID=$(xcrun xctrace list devices | grep "^e2e test Simulator (17.2)" | awk '{gsub(/[()]/,""); print $NF}') - # echo $UDID - # xcrun simctl boot "${UDID:?No Simulator with this name found}" - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p iOS -r flet - - flutter build ios --no-codesign - # - flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart - - # ====================================== - # Test on Android - # ====================================== - - - matrix: - only: - - job_name: Test on Android - - install: - - API_LEVEL="33" - - TARGET="google_atd" - - ARCH="x86_64" - - DEVICE_NAME="android_emulator" - - DEVICE_TYPE="pixel_5" - - 'export PATH=$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH' - - sdkmanager "platform-tools" "platforms;android-${API_LEVEL}" - - sdkmanager --install "system-images;android-${API_LEVEL};${TARGET};${ARCH}" - - sdkmanager --update - - echo "y" | sdkmanager --licenses - - echo "no" | avdmanager -v create avd --force --name "${DEVICE_NAME}" --package "system-images;android-${API_LEVEL};${TARGET};${ARCH}" --tag "${TARGET}" --sdcard 128M --device "${DEVICE_TYPE}" - - ls -al ~/.android/avd - - sudo adduser $USER kvm - - sudo chown $USER /dev/kvm - - emulator -avd "${DEVICE_NAME}" -memory 2048 -wipe-data -no-boot-anim -cache-size 1000 -noaudio -no-window -partition-size 8192 & - - adb wait-for-device shell 'while [[ -z $(getprop dev.bootcomplete) ]]; do sleep 1; done;' - - source ci/install_flutter.sh - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Android -r flet - - flutter test integration_test -d emulator-5554 - - - # ====================================== - # Test on Windows - # ====================================== - - - matrix: - only: - - job_name: Test on Windows - - #environment: - # VC_REDIST_DIR: 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT' - - install: - - dart pub global activate fvm - - set PATH=%LOCALAPPDATA%\Pub\Cache\bin;%USERPROFILE%\fvm\default\bin;%PATH% - - fvm install %FLUTTER_VERSION% - - fvm global %FLUTTER_VERSION% - - flutter --version - - flutter doctor - - build: off - - test_script: - - set SERIOUS_PYTHON_SITE_PACKAGES=%APPVEYOR_BUILD_FOLDER%\site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Windows -r flet - - flutter test integration_test -d windows - - # ====================================== - # Test on Linux - # ====================================== - - - matrix: - only: - - job_name: Test on Linux - - install: - - sudo apt update --allow-releaseinfo-change - - sudo apt install -y xvfb libgtk-3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio - - source ci/install_flutter.sh - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Linux -r flet - - xvfb-run flutter test integration_test -d linux - - # ====================================== - # Test on Linux ARM64 - # ====================================== - - - matrix: - only: - - job_name: Test on Linux ARM64 - - install: - # Flutter SDK - - sudo sed -i "/#\$nrconf{restart} = 'i';/s/.*/\$nrconf{restart} = 'a';/" /etc/needrestart/needrestart.conf - - sudo apt update -y --allow-releaseinfo-change - - sudo apt install -y clang ninja-build xvfb libgtk-3-dev gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav - - git clone https://github.com/flutter/flutter.git -b stable "$HOME/flutter" - - export PATH="$PATH:$HOME/flutter/bin" - - source ci/install_flutter.sh - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Linux -r flet - - xvfb-run flutter test integration_test -d linux - - # ========================================= - # Publish serious_python package to pub.dev - # ========================================= - - - matrix: - only: - - job_name: Publish serious_python package to pub.dev - - install: - # update build version - - ps: | - if ($env:APPVEYOR_REPO_TAG_NAME) { - $env:PKG_VER = $env:APPVEYOR_REPO_TAG_NAME.replace("v", "") - } else { - $cv = [version](git describe --abbrev=0).substring(1) - $env:PKG_VER = "$($cv.major).$($cv.minor).$($env:APPVEYOR_BUILD_NUMBER)" - } - Write-Host "Package version: $($env:PKG_VER)" - - - pip3 install pyyaml - - flutter upgrade --force - - build_script: - # publish package - - sh: | - if [[ "$APPVEYOR_REPO_TAG_NAME" != "" ]]; then - mkdir -p $HOME/.config/dart - echo $PUB_DEV_TOKEN | base64 --decode > $HOME/.config/dart/pub-credentials.json - - # patch pubspecs - python3 ci/patch_pubspec.py src/serious_python_platform_interface/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_android/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_darwin/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_windows/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_linux/pubspec.yaml $PKG_VER - - cd src/serious_python_platform_interface - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - sleep 600 - - cd src/serious_python_android - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_darwin - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_windows - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_linux - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - sleep 600 - - cd src/serious_python - dart pub publish --force || exit 1 - cd $APPVEYOR_BUILD_FOLDER - - elif [[ "$APPVEYOR_PULL_REQUEST_NUMBER" == "" ]]; then - - cd src/serious_python_platform_interface - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_android - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_darwin - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_windows - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_linux - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - fi - - test: off \ No newline at end of file diff --git a/.github/scripts/check_elf_alignment.sh b/.github/scripts/check_elf_alignment.sh new file mode 100755 index 00000000..d8db1291 --- /dev/null +++ b/.github/scripts/check_elf_alignment.sh @@ -0,0 +1,699 @@ +#!/bin/bash + +# Enhanced ELF Alignment Checker for Android 16KB Page Size Compatibility +# This script checks if your app's native libraries are compatible with 16KB page size devices +# as required by Google Play starting November 1st, 2025 for apps targeting Android 15+ + +progname="${0##*/}" +progname="${progname%.sh}" + +# Color codes and formatting - detect if colors are supported +if [[ -t 1 ]] && command -v tput >/dev/null 2>&1 && tput colors >/dev/null 2>&1 && [[ $(tput colors) -ge 8 ]]; then + RED="\033[31m" + GREEN="\033[32m" + YELLOW="\033[33m" + BLUE="\033[34m" + CYAN="\033[36m" + PURPLE="\033[35m" + BOLD="\033[1m" + DIM="\033[2m" + ENDCOLOR="\033[0m" + USE_COLORS=true +else + # No color support - use plain text + RED="" + GREEN="" + YELLOW="" + BLUE="" + CYAN="" + PURPLE="" + BOLD="" + DIM="" + ENDCOLOR="" + USE_COLORS=false +fi + +# Unicode symbols with fallbacks +if [[ $USE_COLORS == true ]]; then + CHECK_MARK="āœ“" + CROSS_MARK="āœ—" + WARNING_MARK="⚠" + INFO_MARK="ℹ" + ROCKET="šŸš€" + GEAR="āš™" + PACKAGE="šŸ“¦" + DOCUMENT="šŸ“„" + ALERT="🚨" + PARTY="šŸŽ‰" + TOOLS="šŸ”§" + BOOKS="šŸ“š" + ARROW="ā–¶" +else + CHECK_MARK="[OK]" + CROSS_MARK="[X]" + WARNING_MARK="[!]" + INFO_MARK="[i]" + ROCKET="[>]" + GEAR="[*]" + PACKAGE="[P]" + DOCUMENT="[D]" + ALERT="[!]" + PARTY="[*]" + TOOLS="[T]" + BOOKS="[B]" + ARROW=">" +fi + +# Enhanced formatting functions +print_banner() { + local title="$1" + local subtitle="$2" + local width=88 + + echo + printf "%*s\n" $width | tr ' ' '═' + + # Main title + local title_len=${#title} + local title_padding=$(( (width - title_len - 4) / 2 )) + printf "ā•‘${BOLD}${BLUE}%*s %s %*s${ENDCOLOR}ā•‘\n" \ + $title_padding "" "$title" $title_padding "" + + # Subtitle if provided + if [[ -n "$subtitle" ]]; then + local subtitle_len=${#subtitle} + local subtitle_padding=$(( (width - subtitle_len - 4) / 2 )) + printf "ā•‘${DIM}%*s %s %*s${ENDCOLOR}ā•‘\n" \ + $subtitle_padding "" "$subtitle" $subtitle_padding "" + fi + + printf "%*s\n" $width | tr ' ' '═' + echo +} + +print_section() { + local icon="$1" + local title="$2" + local description="$3" + + echo + echo -e "${BOLD}${BLUE}$icon $title${ENDCOLOR}" + if [[ -n "$description" ]]; then + echo -e "${DIM}$description${ENDCOLOR}" + fi + printf "${BLUE}%*s${ENDCOLOR}\n" 80 | tr ' ' '─' +} + +print_status() { + local status="$1" + local message="$2" + local detail="$3" + + case $status in + "success") + printf " ${GREEN}${CHECK_MARK}${ENDCOLOR} %s" "$message" + ;; + "error") + printf " ${RED}${CROSS_MARK}${ENDCOLOR} %s" "$message" + ;; + "warning") + printf " ${YELLOW}${WARNING_MARK}${ENDCOLOR} %s" "$message" + ;; + "info") + printf " ${CYAN}${INFO_MARK}${ENDCOLOR} %s" "$message" + ;; + "processing") + printf " ${PURPLE}${GEAR}${ENDCOLOR} %s" "$message" + ;; + esac + + if [[ -n "$detail" ]]; then + printf "\n ${DIM}%s${ENDCOLOR}" "$detail" + fi + echo +} + +print_subsection() { + local title="$1" + echo + echo -e " ${BOLD}${PURPLE}${ARROW} $title${ENDCOLOR}" + printf " ${PURPLE}%*s${ENDCOLOR}\n" 50 | tr ' ' 'ā”ˆ' +} + +print_table_header() { + echo + local line1="ā”Œ$(printf '─%.0s' {1..29})┬$(printf '─%.0s' {1..18})┬$(printf '─%.0s' {1..15})┬$(printf '─%.0s' {1..13})┐" + local line2="│ $(printf '%-27s' 'Library') │ $(printf '%-16s' 'Architecture') │ $(printf '%-13s' 'Alignment') │ $(printf '%-11s' 'Status') │" + local line3="ā”œ$(printf '─%.0s' {1..29})┼$(printf '─%.0s' {1..18})┼$(printf '─%.0s' {1..15})┼$(printf '─%.0s' {1..13})┤" + + echo -e "${CYAN}$line1${ENDCOLOR}" + echo -e "${BOLD}${CYAN}$line2${ENDCOLOR}" + echo -e "${CYAN}$line3${ENDCOLOR}" +} + +print_table_row() { + local lib="$1" + local arch="$2" + local alignment="$3" + local status="$4" + local is_critical="$5" + + local status_symbol + local status_color + local status_text + + if [[ $status == "ALIGNED" ]]; then + status_symbol="$CHECK_MARK" + status_color="$GREEN" + status_text="PASS" + else + status_symbol="$CROSS_MARK" + if [[ $is_critical == "true" ]]; then + status_color="$RED" + status_text="FAIL" + else + status_color="$YELLOW" + status_text="WARN" + fi + fi + + # Truncate library name if too long + local display_lib="$lib" + if [[ ${#lib} -gt 27 ]]; then + display_lib="${lib:0:24}..." + fi + + printf "${CYAN}│${ENDCOLOR} %-27s ${CYAN}│${ENDCOLOR} %-16s ${CYAN}│${ENDCOLOR} %-13s ${CYAN}│${ENDCOLOR} ${status_color}%s %-7s${ENDCOLOR} ${CYAN}│${ENDCOLOR}\n" \ + "$display_lib" "$arch" "$alignment" "$status_symbol" "$status_text" + + if [[ $is_critical == "true" && $status == "UNALIGNED" ]]; then + printf "${CYAN}│${ENDCOLOR} ${RED}%-75s${ENDCOLOR} ${CYAN}│${ENDCOLOR}\n" " ${ALERT} CRITICAL: Required for Google Play compliance!" + fi +} + +print_table_footer() { + local line="ā””$(printf '─%.0s' {1..29})┓$(printf '─%.0s' {1..18})┓$(printf '─%.0s' {1..15})┓$(printf '─%.0s' {1..13})ā”˜" + echo -e "${CYAN}$line${ENDCOLOR}" + echo +} + +print_summary_box() { + local title="$1" + local status="$2" # success, warning, error + shift 2 + local lines=("$@") + + local box_color + local title_color + case $status in + "success") box_color="$GREEN"; title_color="$GREEN" ;; + "warning") box_color="$YELLOW"; title_color="$YELLOW" ;; + "error") box_color="$RED"; title_color="$RED" ;; + *) box_color="$BLUE"; title_color="$BLUE" ;; + esac + + local width=78 + echo + printf "${box_color}ā”Œ%*s┐${ENDCOLOR}\n" $((width-2)) | tr ' ' '─' + + # Title + local title_len=${#title} + local title_padding=$(( (width - title_len - 4) / 2 )) + printf "${box_color}│${ENDCOLOR}${BOLD}${title_color}%*s %s %*s${ENDCOLOR}${box_color}│${ENDCOLOR}\n" \ + $title_padding "" "$title" $title_padding "" + + printf "${box_color}ā”œ%*s┤${ENDCOLOR}\n" $((width-2)) | tr ' ' '─' + + # Content lines + for line in "${lines[@]}"; do + printf "${box_color}│${ENDCOLOR} %-*s ${box_color}│${ENDCOLOR}\n" $((width-4)) "$line" + done + + printf "${box_color}ā””%*sā”˜${ENDCOLOR}\n" $((width-2)) | tr ' ' '─' + echo +} + +cleanup_trap() { + if [ -n "${tmp}" -a -d "${tmp}" ]; then + print_status "processing" "Cleaning up temporary files..." + rm -rf "${tmp}" + fi + exit $1 +} + +usage() { + print_banner "Android 16KB Page Size Compatibility Checker" "Google Play Compliance Tool" + + echo -e "${BOLD}DESCRIPTION:${ENDCOLOR}" + echo " This tool verifies that your Android app's native libraries are compatible" + echo " with 16KB page size devices, as required by Google Play starting November 1st, 2025." + echo + + echo -e "${BOLD}USAGE:${ENDCOLOR}" + echo -e " ${GREEN}$progname${ENDCOLOR} ${CYAN}[input-path|input-APK|input-APEX]${ENDCOLOR}" + echo + + echo -e "${BOLD}EXAMPLES:${ENDCOLOR}" + echo -e " ${DIM}# Check an APK file${ENDCOLOR}" + echo -e " $progname ${CYAN}app/build/outputs/apk/release/app-release.apk${ENDCOLOR}" + echo + echo -e " ${DIM}# Check a directory of native libraries${ENDCOLOR}" + echo -e " $progname ${CYAN}/path/to/native/libs/${ENDCOLOR}" + echo + + echo -e "${BOLD}WHAT THIS TOOL CHECKS:${ENDCOLOR}" + echo -e " ${CHECK_MARK} APK zip-alignment for 16KB boundaries (requires build-tools 35.0.0+)" + echo -e " ${CHECK_MARK} ELF segment alignment in native libraries (arm64-v8a and x86_64)" + echo -e " ${CHECK_MARK} Compliance with Android 16KB page size requirements" + echo + + echo -e "${BOLD}RESULT MEANINGS:${ENDCOLOR}" + echo -e " ${GREEN}${CHECK_MARK} PASS${ENDCOLOR} - Library is compatible with 16KB page sizes (2**14 or higher)" + echo -e " ${RED}${CROSS_MARK} FAIL${ENDCOLOR} - Library needs recompilation with 16KB ELF alignment" + echo -e " ${YELLOW}${WARNING_MARK} WARN${ENDCOLOR} - Non-critical architecture but should be fixed" + echo +} + +# Enhanced dependency checking +check_dependencies() { + print_section "$GEAR" "Dependency Check" "Verifying required tools are available" + + local missing_tools=() + local available_tools=() + + # Check each tool + local tools=("objdump" "unzip" "file") + for tool in "${tools[@]}"; do + if command -v "$tool" >/dev/null 2>&1; then + available_tools+=("$tool") + print_status "success" "$tool" "$(which "$tool")" + else + missing_tools+=("$tool") + print_status "error" "$tool not found" + fi + done + + if [ ${#missing_tools[@]} -gt 0 ]; then + echo + print_subsection "Installation Instructions" + for tool in "${missing_tools[@]}"; do + case $tool in + objdump) + print_status "info" "Install objdump:" "macOS: Xcode Command Line Tools or Android NDK's llvm-objdump" + print_status "info" "" "Linux: sudo apt-get install binutils (Ubuntu/Debian)" + ;; + unzip) + print_status "info" "Install unzip:" "Usually pre-installed on most systems" + print_status "info" "" "Linux: sudo apt-get install unzip" + ;; + file) + print_status "info" "Install file:" "Usually pre-installed on most systems" + print_status "info" "" "Linux: sudo apt-get install file" + ;; + esac + echo + done + exit 1 + fi + + print_status "success" "All dependencies satisfied" "${#available_tools[@]} tools available" +} + +# Validate input arguments +if [ ${#} -ne 1 ]; then + usage + exit 1 +fi + +case ${1} in + --help | -h | -\?) + usage + exit 0 + ;; + *) + dir="${1}" + ;; +esac + +# Validate input file/directory +if ! [ -f "${dir}" -o -d "${dir}" ]; then + print_status "error" "Invalid input: ${dir}" + echo " Please provide a valid APK file, APEX file, or directory containing native libraries." + exit 1 +fi + +# Check dependencies before proceeding +check_dependencies + +print_banner "ANALYSIS IN PROGRESS" "Checking 16KB Page Size Compatibility" + +print_status "processing" "Target: $(basename "${dir}")" +print_status "info" "Compliance Deadline: November 1st, 2025" +print_status "info" "Requirement: Apps targeting Android 15+ must support 16KB pages" + +# APK Processing +if [[ "${dir}" == *.apk ]]; then + trap 'cleanup_trap' EXIT + + print_section "$PACKAGE" "APK Analysis" "Processing Android Package file" + + # Enhanced zipalign check + if command -v zipalign >/dev/null 2>&1; then + if { zipalign --help 2>&1 | grep -q "\-P "; }; then + print_status "processing" "Checking APK zip-alignment for 16KB boundaries..." + + zip_result=$(zipalign -v -c -P 16 4 "${dir}" 2>&1) + zip_exit_code=$? + + if [ $zip_exit_code -eq 0 ]; then + print_status "success" "APK zip-alignment verification passed" + else + print_status "error" "APK zip-alignment verification failed" + echo " ${DIM}Details:${ENDCOLOR}" + echo "$zip_result" | grep -E 'lib/arm64-v8a|lib/x86_64|Verification|would be' | sed 's/^/ /' || echo " $zip_result" + fi + else + print_status "warning" "zipalign version doesn't support 16KB alignment checks" + print_status "info" "Solution: Update to Android SDK build-tools 35.0.0+" + echo " ${DIM}Update via Android Studio → SDK Manager → SDK Tools${ENDCOLOR}" + echo " ${DIM}Or run: sdkmanager \"build-tools;35.0.0\"${ENDCOLOR}" + fi + else + print_status "warning" "zipalign not found in PATH" + print_status "info" "Ensure Android SDK build-tools are installed and in PATH" + fi + + # Extract APK + dir_filename=$(basename "${dir}") + tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX") + + if [ ! -d "${tmp}" ]; then + print_status "error" "Failed to create temporary directory" + exit 1 + fi + + print_status "processing" "Extracting native libraries from APK..." + if ! unzip -q "${dir}" "lib/*" -d "${tmp}" 2>/dev/null; then + print_summary_box "NO NATIVE LIBRARIES FOUND" "success" \ + "${PARTY} Your app contains only Java/Kotlin code!" \ + "" \ + "${CHECK_MARK} Apps without native libraries automatically support 16KB devices" \ + "${CHECK_MARK} No additional changes required for Google Play compliance" \ + "${CHECK_MARK} You're all set for the November 1st, 2025 deadline!" + cleanup_trap 0 + fi + + dir="${tmp}" +fi + +# APEX Processing +if [[ "${dir}" == *.apex ]]; then + trap 'cleanup_trap' EXIT + + print_section "$DOCUMENT" "APEX Analysis" "Processing Android Pony EXpress file" + + if ! command -v deapexer >/dev/null 2>&1; then + print_status "error" "deapexer tool not found" + echo " Please ensure Android SDK tools are properly installed and in your PATH." + exit 1 + fi + + dir_filename=$(basename "${dir}") + tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX") + + if [ ! -d "${tmp}" ]; then + print_status "error" "Failed to create temporary directory" + exit 1 + fi + + print_status "processing" "Extracting APEX contents..." + if ! deapexer extract "${dir}" "${tmp}"; then + print_status "error" "Failed to extract APEX file" + cleanup_trap 1 + fi + + dir="${tmp}" +fi + +# Track libraries for enhanced summary +unaligned_libs=() +aligned_libs=() +critical_unaligned_libs=() +non_critical_unaligned_libs=() +total_libs=0 +critical_libs=0 + +print_section "$GEAR" "ELF Segment Analysis" "Scanning native libraries for 16KB alignment compliance" + +# Find all native libraries +matches="$(find "${dir}" -type f -name '*.so' 2>/dev/null)" +if [ -z "$matches" ]; then + # Also check for ELF files without .so extension + matches="$(find "${dir}" -type f -exec file {} \; 2>/dev/null | grep 'ELF' | cut -d: -f1)" +fi + +if [ -z "$matches" ]; then + print_summary_box "NO NATIVE LIBRARIES DETECTED" "success" \ + "${PARTY} Your app uses only Java/Kotlin code!" \ + "" \ + "${CHECK_MARK} No native library alignment issues to worry about" \ + "${CHECK_MARK} Already compatible with 16KB page size devices" \ + "${CHECK_MARK} Ready for Google Play's November 1st, 2025 requirement!" + cleanup_trap 0 +fi + +print_status "info" "Found native libraries - analyzing ELF segment alignment..." + +print_table_header + +IFS=$'\n' +for match in $matches; do + # Skip non-ELF files and nested packages + if [[ "${match}" == *".apk" ]]; then + continue + fi + if [[ "${match}" == *".apex" ]]; then + continue + fi + + # Verify it's actually an ELF file + if ! [[ $(file "${match}" 2>/dev/null) == *"ELF"* ]]; then + continue + fi + + total_libs=$((total_libs + 1)) + + # Determine architecture and criticality + arch="unknown" + is_critical="false" + if [[ "${match}" == *"arm64-v8a"* ]]; then + arch="arm64-v8a" + is_critical="true" + critical_libs=$((critical_libs + 1)) + elif [[ "${match}" == *"x86_64"* ]]; then + arch="x86_64" + is_critical="true" + critical_libs=$((critical_libs + 1)) + elif [[ "${match}" == *"armeabi-v7a"* ]]; then + arch="armeabi-v7a" + elif [[ "${match}" == *"x86"* ]]; then + arch="x86" + fi + + # Check ELF segment alignment + res="$(objdump -p "${match}" 2>/dev/null | grep LOAD | awk '{ print $NF }' | head -1)" + + if [ -z "$res" ]; then + print_table_row "$(basename "${match}")" "$arch" "UNKNOWN" "FAILED" "$is_critical" + continue + fi + + # Check if alignment meets 16KB requirement (2**14 or higher) + if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then + print_table_row "$(basename "${match}")" "$arch" "$res" "ALIGNED" "$is_critical" + aligned_libs+=("${match}") + else + print_table_row "$(basename "${match}")" "$arch" "$res" "UNALIGNED" "$is_critical" + unaligned_libs+=("${match}") + + if [[ "$is_critical" == "true" ]]; then + critical_unaligned_libs+=("${match}") + else + non_critical_unaligned_libs+=("${match}") + fi + fi +done + +print_table_footer + +# Enhanced Summary Section +if [ ${#unaligned_libs[@]} -gt 0 ]; then + # Failure case - unaligned libraries found + summary_lines=( + "${ALERT} ACTION REQUIRED: Unaligned native libraries detected!" + "" + "Analysis Results:" + " • Total libraries scanned: $total_libs" + " • Critical architectures (64-bit): $critical_libs" + " • Libraries aligned: ${#aligned_libs[@]}" + " • Libraries UNALIGNED: ${#unaligned_libs[@]}" + ) + + if [ ${#critical_unaligned_libs[@]} -gt 0 ]; then + summary_lines+=(" • Critical failures: ${#critical_unaligned_libs[@]} (MUST FIX)") + fi + + if [ ${#non_critical_unaligned_libs[@]} -gt 0 ]; then + summary_lines+=(" • Non-critical warnings: ${#non_critical_unaligned_libs[@]} (SHOULD FIX)") + fi + + summary_lines+=("") + summary_lines+=("Google Play Compliance: FAILED") + summary_lines+=("Deadline: November 1st, 2025") + + print_summary_box "COMPATIBILITY CHECK FAILED" "error" "${summary_lines[@]}" + + # Detailed library breakdown + if [ ${#critical_unaligned_libs[@]} -gt 0 ]; then + print_subsection "Critical Libraries Requiring Immediate Attention" + for lib in "${critical_unaligned_libs[@]}"; do + arch_type="64-bit" + [[ "${lib}" == *"arm64-v8a"* ]] && arch_type="ARM64" + [[ "${lib}" == *"x86_64"* ]] && arch_type="x86_64" + print_status "error" "$(basename "$lib")" "$arch_type architecture - Required for Google Play" + done + fi + + if [ ${#non_critical_unaligned_libs[@]} -gt 0 ]; then + print_subsection "Non-Critical Libraries (Recommended to Fix)" + for lib in "${non_critical_unaligned_libs[@]}"; do + arch_type="32-bit" + [[ "${lib}" == *"armeabi-v7a"* ]] && arch_type="ARMv7" + [[ "${lib}" == *"x86"* ]] && arch_type="x86" + print_status "warning" "$(basename "$lib")" "$arch_type architecture" + done + fi + + # Comprehensive fix instructions + print_section "$TOOLS" "How to Fix Unaligned Libraries" "Step-by-step guide to achieve 16KB compatibility" + + print_subsection "Step 1: Update Your Build Environment" + print_status "info" "Android Gradle Plugin (AGP)" "Upgrade to version 8.5.1 or higher" + print_status "info" "Android NDK" "Update to NDK r27 or higher (r28+ recommended)" + print_status "info" "Build Tools" "Ensure Android SDK build-tools 35.0.0+ for zipalign" + + print_subsection "Step 2: Configure 16KB ELF Alignment" + echo + echo -e "${BOLD}For NDK r28 and newer:${ENDCOLOR}" + print_status "success" "Automatic Support" "16KB alignment enabled by default - no changes needed!" + + echo + echo -e "${BOLD}For NDK r27:${ENDCOLOR}" + print_status "info" "Gradle Configuration" "Add to your app/build.gradle:" + echo -e "${DIM} android {" + echo -e " defaultConfig {" + echo -e " externalNativeBuild {" + echo -e " cmake {" + echo -e " arguments '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'" + echo -e " }" + echo -e " }" + echo -e " }" + echo -e " }${ENDCOLOR}" + + print_status "info" "NDK-Build Configuration" "Add to Application.mk:" + echo -e "${DIM} APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true${ENDCOLOR}" + + echo + echo -e "${BOLD}For NDK r26 and older:${ENDCOLOR}" + print_status "info" "Manual Linker Flags" "Add to your native build configuration:" + echo -e "${DIM} # For Android.mk:" + echo -e " LOCAL_LDFLAGS += \"-Wl,-z,max-page-size=16384\"" + echo + echo -e " # For CMakeLists.txt:" + echo -e " target_link_options(\${CMAKE_PROJECT_NAME} PRIVATE \"-Wl,-z,max-page-size=16384\")${ENDCOLOR}" + + print_subsection "Step 3: Update Library Packaging" + print_status "info" "AGP 8.5.1+" "Uncompressed libraries used by default (no changes needed)" + print_status "info" "Older AGP versions" "Add to app/build.gradle:" + echo -e "${DIM} android {" + echo -e " packagingOptions {" + echo -e " jniLibs {" + echo -e " useLegacyPackaging = true" + echo -e " }" + echo -e " }" + echo -e " }${ENDCOLOR}" + + print_subsection "Step 4: Build and Verify" + print_status "processing" "Clean Build" "Run ./gradlew clean" + print_status "processing" "Rebuild Project" "Run ./gradlew assembleRelease" + print_status "processing" "Re-run This Script" "Verify all libraries are now aligned" + print_status "processing" "Test on Device" "Use Android 15 emulator with 16KB system image" + + print_section "$BOOKS" "Additional Resources" "Learn more about 16KB page size support" + print_status "info" "Official Guide" "https://developer.android.com/guide/practices/page-sizes" + print_status "info" "NDK Documentation" "https://developer.android.com/ndk/guides/" + print_status "info" "Testing Guide" "Use 'adb shell getconf PAGE_SIZE' (should return 16384)" + print_status "info" "Emulator Setup" "Android 15 system images with 16KB page size" + + final_message="" + if [ ${#critical_unaligned_libs[@]} -gt 0 ]; then + final_message="CRITICAL: Fix required for Google Play compliance by November 1st, 2025!" + else + final_message="Warning: Non-critical issues found - recommended to fix for complete compatibility" + fi + + print_summary_box "NEXT STEPS" "error" \ + "$final_message" \ + "" \ + "1. Update your build tools and NDK version" \ + "2. Apply the configuration changes above" \ + "3. Clean and rebuild your project" \ + "4. Run this script again to verify fixes" \ + "5. Test thoroughly on 16KB devices/emulator" + + cleanup_trap 1 +else + # Success case - all libraries aligned + summary_lines=( + "${PARTY} All native libraries are properly aligned!" + "" + "Analysis Results:" + " • Total libraries scanned: $total_libs" + " • Critical architectures: $critical_libs" + " • All libraries: ${#aligned_libs[@]}/${total_libs} ALIGNED" + "" + "Google Play Compliance: PASSED ${CHECK_MARK}" + "Ready for November 1st, 2025 deadline!" + ) + + print_summary_box "COMPATIBILITY CHECK PASSED" "success" "${summary_lines[@]}" + + print_section "$ROCKET" "Next Steps" "Ensure complete 16KB compatibility" + + print_status "success" "Library Alignment" "All ELF segments properly aligned for 16KB pages" + print_status "info" "Runtime Testing" "Test on Android 15 emulator with 16KB system image" + print_status "info" "Code Review" "Check for hardcoded PAGE_SIZE dependencies in your code" + print_status "info" "Third-party SDKs" "Verify all dependencies are 16KB compatible" + print_status "info" "Zipalign Verification" "Run: zipalign -c -P 16 -v 4 your-app.apk" + + print_subsection "Testing Commands" + echo -e "${DIM} # Verify page size on device/emulator${ENDCOLOR}" + echo -e "${DIM} adb shell getconf PAGE_SIZE # Should return: 16384${ENDCOLOR}" + echo + echo -e "${DIM} # Verify APK alignment${ENDCOLOR}" + echo -e "${DIM} zipalign -c -P 16 -v 4 app-release.apk${ENDCOLOR}" + + print_summary_box "CONGRATULATIONS!" "success" \ + "${PARTY} Your app is 16KB page size compatible!" \ + "" \ + "${CHECK_MARK} All native libraries meet Google Play requirements" \ + "${CHECK_MARK} Ready for devices with 16KB page sizes" \ + "${CHECK_MARK} Compliant with November 1st, 2025 deadline" \ + "" \ + "Recommendation: Test thoroughly on 16KB environment to ensure" \ + "no runtime issues exist in your application code." +fi + +echo +print_status "info" "Analysis completed at $(date)" +echo diff --git a/ci/patch_pubspec.py b/.github/scripts/patch_pubspec.py similarity index 91% rename from ci/patch_pubspec.py rename to .github/scripts/patch_pubspec.py index d655767a..66689a46 100644 --- a/ci/patch_pubspec.py +++ b/.github/scripts/patch_pubspec.py @@ -1,3 +1,7 @@ +# /// script +# dependencies = ["pyyaml"] +# /// + import os import pathlib import sys @@ -22,7 +26,7 @@ "serious_python_macos", ] -with open(pubspec_path, "r") as f: +with open(pubspec_path) as f: data = yaml.safe_load(f) # patch version diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..0dda04c3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,296 @@ +name: CI + +on: + push: + branches: + - '**' + tags: + - '*' + pull_request: + workflow_dispatch: + +env: + ROOT: "${{ github.workspace }}" + SCRIPTS: "${{ github.workspace }}/.github/scripts" + SERIOUS_PYTHON_SITE_PACKAGES: "${{ github.workspace }}/site-packages" + UV_PYTHON: "3.12" + +jobs: + macos: + name: Test on macOS + runs-on: macos-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Run tests + working-directory: "src/serious_python/example/flet_example" + run: | + dart run serious_python:main package app/src --platform Darwin --requirements flet + flutter test integration_test --device-id macos + + ios: + name: Test on iOS + runs-on: macos-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Setup iOS Simulator + id: simulator + uses: futureware-tech/simulator-action@v4 + with: + # https://github.com/futureware-tech/simulator-action/wiki/Devices-macos-latest + model: 'iPhone 16 Pro Max' + os: "iOS" + os_version: "^18.6" + shutdown_after_job: true + wait_for_boot: true + + - name: Run tests + working-directory: "src/serious_python/example/flet_example" + run: | + dart run serious_python:main package app/src --platform iOS --requirements flet + flutter test integration_test --device-id ${{ steps.simulator.outputs.udid }} + + android: + name: Test on Android + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - 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: Gradle cache + uses: gradle/actions/setup-gradle@v3 + + - name: AVD cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd + + - name: Setup Android Emulator + Run tests + uses: reactivecircus/android-emulator-runner@v2 + env: + EMULATOR_PORT: 5554 + with: + avd-name: android_emulator + api-level: 33 + target: google_atd + arch: x86_64 + profile: pixel_5 + sdcard-path-or-size: 128M + ram-size: 2048M + disk-size: 4096M + emulator-port: ${{ env.EMULATOR_PORT }} + disable-animations: true + emulator-options: -no-window -noaudio -no-boot-anim -wipe-data -cache-size 1000 -partition-size 8192 + pre-emulator-launch-script: | + sdkmanager --list_installed + script: | + cd src/serious_python/example/flet_example && dart run serious_python:main package app/src --platform Android --requirements flet + cd src/serious_python/example/flet_example && flutter test integration_test --device-id emulator-${{ env.EMULATOR_PORT }} + + windows: + name: Test on Windows + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Run tests + working-directory: "src/serious_python/example/flet_example" + run: | + dart run serious_python:main package app/src --platform Windows --requirements flet + flutter test integration_test -d windows + + linux: + name: Test on Linux ${{ matrix.title }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - arch: arm64 + runner: ubuntu-24.04-arm + title: ARM64 + - arch: amd64 + runner: ubuntu-24.04 + title: AMD64 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup uv + uses: astral-sh/setup-uv@v6 + + - name: Get Flutter version from ".fvmrc" + uses: kuhnroyal/flutter-fvm-config-action/config@v3 + id: fvm-config-action + with: + path: '.fvmrc' + + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} + channel: ${{ matrix.arch == 'arm64' && 'master' || 'stable' }} # https://github.com/subosito/flutter-action/issues/345#issuecomment-2657332687 + cache: true + + - name: Install dependencies + run: | + sudo apt-get update --allow-releaseinfo-change + sudo apt-get install -y xvfb libgtk-3-dev + + if [ "${{ matrix.arch }}" = "amd64" ]; then + sudo apt-get install -y \ + libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-dev \ + libgstreamer-plugins-bad1.0-dev \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav \ + gstreamer1.0-tools \ + gstreamer1.0-x \ + gstreamer1.0-alsa \ + gstreamer1.0-gl \ + gstreamer1.0-gtk3 \ + gstreamer1.0-qt5 \ + gstreamer1.0-pulseaudio + else + sudo apt-get install -y \ + clang \ + ninja-build \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav + fi + + - name: Run tests + working-directory: src/serious_python/example/flet_example + run: | + flutter pub get + dart run serious_python:main package app/src --platform Linux --requirements flet + xvfb-run flutter test integration_test -d linux + + publish: + name: Publish to pub.dev + needs: + - macos + - ios + - android + - windows + - linux + runs-on: ubuntu-22.04 + if: startsWith(github.ref, 'refs/tags/v') + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup uv + uses: astral-sh/setup-uv@v6 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Compute PKG_VER + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + # Extract the tag name + tag="${GITHUB_REF#refs/tags/}" + + # Remove leading "v" if present + PKG_VER="${tag#v}" + else + # Get the latest tag, or fall back to "v0.0.0" if none exist + cv=$(git describe --abbrev=0 2>/dev/null || echo "v0.0.0") + # Remove leading "v" if present + cv=${cv#v} + + # Split into major/minor components + major=$(echo "$cv" | cut -d. -f1) + minor=$(echo "$cv" | cut -d. -f2) + + # Construct the package version + PKG_VER="${major}.${minor}.${GITHUB_RUN_NUMBER}" + fi + + export PKG_VER + echo "PKG_VER=$PKG_VER" | tee -a "$GITHUB_ENV" + + - name: Configure pub.dev credentials + run: | + mkdir -p $HOME/.config/dart + echo "${{ secrets.PUB_DEV_TOKEN }}" | base64 --decode > $HOME/.config/dart/pub-credentials.json + + - name: Patch pubspec versions + working-directory: "src" + run: | + for pkg in \ + "serious_python" \ + "serious_python_platform_interface" \ + "serious_python_android" \ + "serious_python_darwin" \ + "serious_python_windows" \ + "serious_python_linux"; do + + uv run "$SCRIPTS/patch_pubspec.py" "$pkg/pubspec.yaml" "$PKG_VER" + done + + - name: Publish packages + run: | + publish_pkg () { + pushd "$1" >/dev/null + dart pub publish --force + popd >/dev/null + } + + publish_pkg src/serious_python_platform_interface + sleep 600 + publish_pkg src/serious_python_android + publish_pkg src/serious_python_darwin + publish_pkg src/serious_python_windows + publish_pkg src/serious_python_linux + sleep 600 + publish_pkg src/serious_python \ No newline at end of file diff --git a/ci/download_artifact.py b/ci/download_artifact.py deleted file mode 100644 index 6b37f5d7..00000000 --- a/ci/download_artifact.py +++ /dev/null @@ -1,51 +0,0 @@ -import json -import os -import pathlib -import sys -import tarfile -import urllib.request - -if len(sys.argv) < 2: - print("Specify artifact job name and artifact deployment name to download") - sys.exit(1) - -artifact_job_name = sys.argv[1] -artifact_file_name = sys.argv[2].format( - version=os.environ.get("APPVEYOR_BUILD_VERSION") -) - -build_jobs = {} - - -def download_job_artifact(job_id, file_name, dest_file): - url = f"https://ci.appveyor.com/api/buildjobs/{job_id}/artifacts/{file_name}" - print(f"Downloading {url}...") - urllib.request.urlretrieve(url, dest_file) - - -def get_build_job_ids(): - account_name = os.environ.get("APPVEYOR_ACCOUNT_NAME") - project_slug = os.environ.get("APPVEYOR_PROJECT_SLUG") - build_id = os.environ.get("APPVEYOR_BUILD_ID") - url = f"https://ci.appveyor.com/api/projects/{account_name}/{project_slug}/builds/{build_id}" - print(f"Fetching build details at {url}") - req = urllib.request.Request(url) - req.add_header("Content-type", "application/json") - project = json.loads(urllib.request.urlopen(req).read().decode()) - for job in project["build"]["jobs"]: - build_jobs[job["name"]] = job["jobId"] - - -current_dir = pathlib.Path(os.getcwd()) -print("current_dir", current_dir) - -get_build_job_ids() - -# create "web" directory -dist_path = current_dir.joinpath("python_dist") -dist_path.mkdir(exist_ok=True) -tar_path = current_dir.joinpath(artifact_file_name) -download_job_artifact(build_jobs[artifact_job_name], artifact_file_name, tar_path) -with tarfile.open(tar_path, "r:gz") as tar: - tar.extractall(str(dist_path)) -os.remove(tar_path) diff --git a/ci/install_flutter.sh b/ci/install_flutter.sh deleted file mode 100755 index 7366c8af..00000000 --- a/ci/install_flutter.sh +++ /dev/null @@ -1,6 +0,0 @@ -dart pub global activate fvm -export PATH=$HOME/.pub-cache/bin:$HOME/fvm/default/bin:$PATH -fvm install $FLUTTER_VERSION -fvm global $FLUTTER_VERSION -flutter --version -flutter doctor \ No newline at end of file diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index 3aad09c5..4d973579 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -1,4 +1,6 @@ ## 0.9.4 + +* 16 KB memory page support for Android 15+ (by [@ReYaNOW](https://github.com/ReYaNOW)). * Fix: Updated compileSdkVersion to pass Android builds * Fix: The version of the dependency `archive` was increased to `4.0.7` and code changes were made for migration. diff --git a/src/serious_python/example/flet_example/integration_test/app_test.dart b/src/serious_python/example/flet_example/integration_test/app_test.dart index d32be512..880d75ff 100644 --- a/src/serious_python/example/flet_example/integration_test/app_test.dart +++ b/src/serious_python/example/flet_example/integration_test/app_test.dart @@ -10,7 +10,7 @@ void main() { testWidgets('make sure counter can be incremented and decremented', (tester) async { app.main(); - await tester.pumpAndSettle(); + await tester.pumpAndSettle(const Duration(seconds: 5)); // Wait for up to 10 seconds for the app to start bool counterFound = false; diff --git a/src/serious_python_android/CHANGELOG.md b/src/serious_python_android/CHANGELOG.md index 075ab98c..658f9f8d 100644 --- a/src/serious_python_android/CHANGELOG.md +++ b/src/serious_python_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* 16 KB memory page support for Android 15+ (by [@ReYaNOW](https://github.com/ReYaNOW)). + ## 0.9.3 * Fix: Hidden files in site-packages are skipped when building macOS app. diff --git a/src/serious_python_android/analysis_options.yaml b/src/serious_python_android/analysis_options.yaml index 872a1ebd..e550cb50 100644 --- a/src/serious_python_android/analysis_options.yaml +++ b/src/serious_python_android/analysis_options.yaml @@ -1,4 +1,8 @@ include: package:flutter_lints/flutter.yaml +analyzer: + exclude: + - lib/src/gen.dart + # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options \ No newline at end of file diff --git a/src/serious_python_android/android/build.gradle b/src/serious_python_android/android/build.gradle index c72c2dd5..f0a3444a 100644 --- a/src/serious_python_android/android/build.gradle +++ b/src/serious_python_android/android/build.gradle @@ -54,7 +54,7 @@ android { } defaultConfig { - minSdkVersion 16 + minSdkVersion 21 ndk { abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64' diff --git a/src/serious_python_android/src/CMakeLists.txt b/src/serious_python_android/src/CMakeLists.txt index 2d52ffcd..c2800814 100644 --- a/src/serious_python_android/src/CMakeLists.txt +++ b/src/serious_python_android/src/CMakeLists.txt @@ -14,4 +14,11 @@ set_target_properties(serious_python PROPERTIES OUTPUT_NAME "serious_python" ) +# Add 16 KB page size support for Android 15 +if(ANDROID) + set_target_properties(serious_python PROPERTIES + LINK_FLAGS "-Wl,-z,max-page-size=16384" + ) +endif() + target_compile_definitions(serious_python PUBLIC DART_SHARED_LIB) diff --git a/src/serious_python_darwin/CHANGELOG.md b/src/serious_python_darwin/CHANGELOG.md index 07cd93da..330b8328 100644 --- a/src/serious_python_darwin/CHANGELOG.md +++ b/src/serious_python_darwin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* 16 KB memory page support for Android 15+ (by [@ReYaNOW](https://github.com/ReYaNOW)). + ## 0.9.3 * Fix: Hidden files in site-packages are skipped when building macOS app. diff --git a/src/serious_python_linux/CHANGELOG.md b/src/serious_python_linux/CHANGELOG.md index e4e42b45..0f06bba1 100644 --- a/src/serious_python_linux/CHANGELOG.md +++ b/src/serious_python_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* 16 KB memory page support for Android 15+ (by [@ReYaNOW](https://github.com/ReYaNOW)). + ## 0.9.3 * Fix: Hidden files in site-packages are skipped when building macOS app. diff --git a/src/serious_python_platform_interface/CHANGELOG.md b/src/serious_python_platform_interface/CHANGELOG.md index c66601dd..bb1ffc8f 100644 --- a/src/serious_python_platform_interface/CHANGELOG.md +++ b/src/serious_python_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* 16 KB memory page support for Android 15+ (by [@ReYaNOW](https://github.com/ReYaNOW)). + ## 0.9.3 * Fix: Hidden files in site-packages are skipped when building macOS app. diff --git a/src/serious_python_windows/CHANGELOG.md b/src/serious_python_windows/CHANGELOG.md index 64dde934..a29364f5 100644 --- a/src/serious_python_windows/CHANGELOG.md +++ b/src/serious_python_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* 16 KB memory page support for Android 15+ (by [@ReYaNOW](https://github.com/ReYaNOW)). + ## 0.9.3 * Fix: Hidden files in site-packages are skipped when building macOS app.