From d7dd2556201b9175ab55ddab18fb537d62592b1d Mon Sep 17 00:00:00 2001 From: Jose Quintana <1700322+joseluisq@users.noreply.github.com> Date: Tue, 18 Apr 2023 03:02:15 +0200 Subject: [PATCH] feat: android arm64 target support (#194) * feat: android arm64 (`aarch64-linux-android`) target * refactor: android arm64 release ci pipeline resolves #163 --- .github/workflows/devel.yml | 41 +++++++++++++++++++++++++++++++---------- .github/workflows/release.docker.yml | 3 ++- .github/workflows/release.yml | 25 ++++++++++++++++++++++--- ci/cargo.sh | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ci/install-tools.sh | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 14 deletions(-) create mode 100755 ci/cargo.sh create mode 100755 ci/install-tools.sh diff --git a/.github/workflows/devel.yml b/.github/workflows/devel.yml index f576574..7da2397 100644 --- a/.github/workflows/devel.yml +++ b/.github/workflows/devel.yml @@ -40,6 +40,9 @@ jobs: - linux-arm-gnueabihf - linux-musl-armv6 - linux-musl-armv7 + # NOTE: looks like not supported by `listenfd` crate + # - linux-android-armv7 + - linux-android-arm64 - macos - macos-arm64 - windows-msvc @@ -95,6 +98,15 @@ jobs: os: ubuntu-20.04 rust: stable target: armv7-unknown-linux-musleabihf + # NOTE: looks like not supported by `listenfd` crate + # - build: linux-android-armv7 + # os: ubuntu-22.04 + # rust: stable + # target: armv7-linux-androideabi + - build: linux-android-arm64 + os: ubuntu-22.04 + rust: stable + target: aarch64-linux-android - build: macos os: macos-11 rust: stable @@ -123,18 +135,28 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 + - name: Install Linux/BSD tools + if: ${{ !contains(matrix.os, 'windows') }} + run: ci/install-tools.sh --target=${{ matrix.target }} + - name: Install Rust uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} - - name: Use Cross - if: matrix.target != '' + - name: Set up Cross + if: ${{ !contains(matrix.os, 'windows') && matrix.target != '' }} run: | - cargo install cross@^0.2 - echo "CARGO_BIN=cross" >> $GITHUB_ENV - echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV + # Use 'cargo.sh' script for Android targets only + if [[ "${{ matrix.build }}" == "linux-android-armv7" ]] || [[ "${{ matrix.build }}" == "linux-android-arm64" ]]; then + echo "CARGO_BIN=ci/cargo.sh" >> $GITHUB_ENV + else + cargo install cross@^0.2 + echo "CARGO_BIN=cross" >> $GITHUB_ENV + fi + + echo "TARGET_FLAGS=--target=${{ matrix.target }}" >> $GITHUB_ENV echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV - name: Show command used for Cargo @@ -143,18 +165,17 @@ jobs: echo "target flag is: ${{ env.TARGET_FLAGS }}" echo "target dir is: ${{ env.TARGET_DIR }}" - - name: aarch64 specific items - if: matrix.build == 'macos-arm64' + - name: Skip tests + if: ${{ contains(fromJSON('["macos-arm64", "linux-android-arm64", "linux-android-armv7"]'), matrix.build) }} run: | # Can't run tests: cross-compiling - echo "SKIP_TESTS=yes" >> $GITHUB_ENV + echo "SKIP_TESTS=--no-run" >> $GITHUB_ENV - name: Run tests shell: bash - if: env.SKIP_TESTS == '' run: | if [[ "${{ matrix.build }}" == "pinned" ]]; then unset CARGO_REGISTRIES_CRATES_IO_PROTOCOL; fi - ${{ env.CARGO_BIN }} test --verbose ${{ env.TARGET_FLAGS }} + ${{ env.CARGO_BIN }} test --verbose ${{ env.TARGET_FLAGS }} ${{ env.SKIP_TESTS }} - name: Run build shell: bash diff --git a/.github/workflows/release.docker.yml b/.github/workflows/release.docker.yml index 0ce510e..d6f04a7 100644 --- a/.github/workflows/release.docker.yml +++ b/.github/workflows/release.docker.yml @@ -1,7 +1,8 @@ name: release-docker on: release: - types: published + types: + - published jobs: docker-image-alpine: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2e3bdde..420beb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,6 +60,8 @@ jobs: - linux-arm-gnueabihf - linux-musl-armv6 - linux-musl-armv7 + # - linux-android-armv7 + - linux-android-arm64 - macos - macos-arm64 - windows-msvc @@ -103,6 +105,14 @@ jobs: os: ubuntu-20.04 rust: stable target: armv7-unknown-linux-musleabihf + # - build: linux-android-armv7 + # os: ubuntu-22.04 + # rust: stable + # target: armv7-linux-androideabi + - build: linux-android-arm64 + os: ubuntu-22.04 + rust: stable + target: aarch64-linux-android - build: macos os: macos-11 rust: stable @@ -134,18 +144,27 @@ jobs: with: fetch-depth: 1 + - name: Install Linux/BSD tools + if: ${{ !contains(matrix.os, 'windows') }} + run: ci/install-tools.sh --target=${{ matrix.target }} + - name: Install Rust uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} - - name: Use Cross + - name: Set up Cross shell: bash run: | if [ "${{ matrix.os }}" = "ubuntu-20.04" ]; then - cargo install cross@^0.2 - echo "CARGO_BIN=cross" >> $GITHUB_ENV + # Use 'cargo.sh' script for Android targets only + if [[ "${{ matrix.build }}" == "linux-android-armv7" ]] || [[ "${{ matrix.build }}" == "linux-android-arm64" ]]; then + echo "CARGO_BIN=ci/cargo.sh" >> $GITHUB_ENV + else + cargo install cross@^0.2 + echo "CARGO_BIN=cross" >> $GITHUB_ENV + fi fi echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV diff --git a/ci/cargo.sh b/ci/cargo.sh new file mode 100755 index 0000000..8fc2956 --- /dev/null +++ b/ci/cargo.sh @@ -0,0 +1,61 @@ +# Adapted from https://github.com/briansmith/ring/blob/main/mk/cargo.sh + +set -eux -o pipefail + +# Avoid putting the Android tools in `$PATH` because there are tools in this +# directory like `clang` that would conflict with the same-named tools that may +# be needed to compile the build script, or to compile for other targets. +if [ -n "${ANDROID_HOME-}" ]; then + # Keep the next line in sync with the corresponding line in install-build-tools.sh. + ndk_version=25.2.9519653 + ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT:-${ANDROID_HOME}/ndk/$ndk_version} +fi +if [ -n "${ANDROID_NDK_ROOT-}" ]; then + android_tools=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin +fi + +for arg in $*; do + case $arg in + --target=*) + target=${arg#*=} + ;; + *) + ;; + esac +done + +case $target in + aarch64-linux-android) + export CC_aarch64_linux_android=$android_tools/aarch64-linux-android21-clang + export AR_aarch64_linux_android=$android_tools/llvm-ar + export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$android_tools/aarch64-linux-android21-clang + ;; + # aarch64-unknown-linux-gnu) + # export CC_aarch64_unknown_linux_gnu=clang-$llvm_version + # export AR_aarch64_unknown_linux_gnu=llvm-ar-$llvm_version + # export CFLAGS_aarch64_unknown_linux_gnu="--sysroot=/usr/aarch64-linux-gnu" + # export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc + # export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER="$qemu_aarch64" + # ;; + # aarch64-unknown-linux-musl) + # export CC_aarch64_unknown_linux_musl=clang-$llvm_version + # export AR_aarch64_unknown_linux_musl=llvm-ar-$llvm_version + # export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained" + # export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUNNER="$qemu_aarch64" + # ;; + # arm-unknown-linux-gnueabihf) + # export CC_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc + # export AR_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc-ar + # export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc + # export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER="$qemu_arm" + # ;; + armv7-linux-androideabi) + export CC_armv7_linux_androideabi=$android_tools/armv7a-linux-androideabi19-clang + export AR_armv7_linux_androideabi=$android_tools/llvm-ar + export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$android_tools/armv7a-linux-androideabi19-clang + ;; + *) + ;; +esac + +cargo "$@" diff --git a/ci/install-tools.sh b/ci/install-tools.sh new file mode 100755 index 0000000..d1dee42 --- /dev/null +++ b/ci/install-tools.sh @@ -0,0 +1,36 @@ +# Adapted from https://github.com/briansmith/ring/blob/main/mk/install-build-tools.sh + +set -eux -o pipefail + +target=$1 + +case $target in +--target*android*) + # https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html says + # "Going forward the Android platform will target the most recent LTS NDK, + # allowing Rust developers to access platform features sooner. These updates + # should occur yearly and will be announced in release notes." Assume that + # means that we should always prefer to be using the latest 25.x.y version of + # the NDK until the Rust project announces that we should use a higher major + # version number. + # + # TODO: This should probably be implemented as a map of Rust toolchain version + # to NDK version; e.g. our MSRV might (only) support an older NDK than the + # latest stable Rust toolchain. + # + # Keep the following line in sync with the corresponding line in cargo.sh. + ndk_version=25.2.9519653 + + mkdir -p "${ANDROID_HOME}/licenses" + android_license_file="${ANDROID_HOME}/licenses/android-sdk-license" + accept_android_license=24333f8a63b6825ea9c5514f83c2829b004d1fee + grep --quiet --no-messages "$accept_android_license" "$android_license_file" \ + || echo $accept_android_license >> "$android_license_file" + "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;$ndk_version" + + # XXX: Older Rust toolchain versions link with `-lgcc` instead of `-lunwind`; + # see https://github.com/rust-lang/rust/pull/85806. + find -L ${ANDROID_NDK_ROOT:-${ANDROID_HOME}/ndk/$ndk_version} -name libunwind.a \ + -execdir sh -c 'echo "INPUT(-lunwind)" > libgcc.a' \; + ;; +esac -- libgit2 1.7.2