Skip to content

Build Android image #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 78 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
fee3b82
Build Android image
marcprux Mar 31, 2025
3656ddd
Checkout without ssh
marcprux Mar 31, 2025
3337239
Retry build if it fails
marcprux Mar 31, 2025
bf9feec
Swift 6.1 Release Dockerfiles (#456)
shahmishal Mar 31, 2025
dedc07b
Change binutils-gold package dependency on Debian 12 to binutils (#457)
cmcgee1024 Apr 1, 2025
7c66259
Update installed packages after nightly platform expansion (#458)
justice-adams-apple Apr 2, 2025
8f25ca3
Android SDK build
marcprux Apr 16, 2025
e396c41
Android SDK build
marcprux Apr 16, 2025
e0e98ba
Android SDK build
marcprux Apr 16, 2025
a628972
Android SDK build
marcprux Apr 16, 2025
42cfd3b
Android SDK build
marcprux Apr 17, 2025
2e9df8e
Android SDK build
marcprux Apr 17, 2025
353511a
Fedora 41 Dockerfile (#464)
sookach Apr 14, 2025
31af52d
Build Android image
marcprux Mar 31, 2025
0c436f9
Build Android image
marcprux Mar 31, 2025
2bc10df
Swift 6.1 Release Dockerfiles (#456)
shahmishal Mar 31, 2025
b4ccd68
Change binutils-gold package dependency on Debian 12 to binutils (#457)
cmcgee1024 Apr 1, 2025
c1cfaa3
Build Android image
marcprux Mar 31, 2025
1fce8ff
Build Android image
marcprux Mar 31, 2025
893d6bf
Build Android image
marcprux Mar 31, 2025
b459d2b
Merge branch 'main' into android-image
marcprux Apr 17, 2025
530626e
Android SDK build
marcprux Apr 17, 2025
a28c1c1
Android SDK build
marcprux Apr 17, 2025
e5d5fdf
Android SDK build
marcprux Apr 17, 2025
c292c89
Android SDK build
marcprux Apr 17, 2025
fa28b81
Android SDK build
marcprux Apr 17, 2025
2029bbe
Android SDK build
marcprux Apr 17, 2025
79fa529
Android SDK build
marcprux Apr 17, 2025
200025d
Android SDK build
marcprux Apr 17, 2025
234ca95
Android SDK build
marcprux Apr 17, 2025
ffb35be
Android SDK build
marcprux Apr 17, 2025
a137f03
Android SDK build
marcprux Apr 17, 2025
e937f54
Android SDK build
marcprux Apr 17, 2025
4050451
Android SDK build
marcprux Apr 17, 2025
74f81e5
Android SDK build
marcprux Apr 17, 2025
641cb60
Android SDK build
marcprux Apr 17, 2025
0d2a8d5
Android SDK build
marcprux Apr 17, 2025
f7e8486
Android SDK build
marcprux Apr 18, 2025
7a59154
Android SDK build
marcprux Apr 18, 2025
d0ef38e
Android SDK build
marcprux Apr 18, 2025
bcfcc43
Android SDK build
marcprux Apr 18, 2025
7db7744
Android SDK build
marcprux Apr 18, 2025
e6a2b92
Android SDK build
marcprux Apr 18, 2025
a8ebb6c
Android SDK build
marcprux Apr 18, 2025
d512582
Android SDK build
marcprux Apr 18, 2025
16dcbaa
Android SDK build
marcprux Apr 19, 2025
413d431
Android SDK build
marcprux Apr 19, 2025
0ef0eca
Android SDK build
marcprux Apr 19, 2025
ddd2c4b
Android SDK build
marcprux Apr 19, 2025
877e5e3
Android SDK build
marcprux Apr 19, 2025
31bd0e9
Android SDK build
marcprux Apr 19, 2025
0ea2a35
Android SDK build
marcprux Apr 19, 2025
2a9eaf7
Android SDK build
marcprux Apr 20, 2025
836d862
Android SDK build
marcprux Apr 20, 2025
53d9bbb
Android SDK build
marcprux Apr 20, 2025
a8071ba
Android SDK build
marcprux Apr 20, 2025
f551ad8
Android SDK build
marcprux Apr 20, 2025
9bd510b
Swift Androd build
marcprux Apr 21, 2025
26f9599
Swift Androd build
marcprux Apr 21, 2025
a441618
Swift Androd build
marcprux Apr 21, 2025
417e483
Swift Androd build
marcprux Apr 21, 2025
652b8b8
Swift Androd build
marcprux Apr 21, 2025
73ebe28
Swift Androd build
marcprux Apr 21, 2025
ebad1cd
Swift Androd build
marcprux Apr 21, 2025
1149f52
Swift Androd build
marcprux Apr 22, 2025
b154b33
Swift Androd build
marcprux Apr 22, 2025
63d9b7f
Swift Androd build
marcprux Apr 22, 2025
9562903
Swift Androd build
marcprux Apr 22, 2025
30d839e
Swift Androd build
marcprux Apr 22, 2025
e2efeaf
Swift Androd build
marcprux Apr 22, 2025
3bf4a6a
Swift Androd build
marcprux Apr 22, 2025
53d9924
Swift Androd build
marcprux Apr 22, 2025
af6ff72
Swift Androd build
marcprux Apr 22, 2025
8a8b68b
Swift Androd build
marcprux Apr 22, 2025
5e8011e
Swift Android build
marcprux Apr 22, 2025
85b678f
Swift Android build
marcprux Apr 22, 2025
0633a32
Swift Android build
marcprux Apr 22, 2025
8d2a2c4
Swift Android build
marcprux Apr 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 121 additions & 5 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,129 @@ jobs:
run: ./build

android-build:
name: Build Android image
runs-on: ubuntu-latest
if: false
name: Build Android ${{ matrix.arch }} SDK
strategy:
fail-fast: false
matrix:
# blank arch builds all (aarch64,x86_64,armv7)
#arch: ['']
# builds only x86_64 to speed up the validation
#arch: ['x86_64']
# build both the quick (x86_64) and complete (aarch64,x86_64,armv7) SDKs
arch: ['x86_64', '']
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Build Docker images
- name: Install Dependencies
run: |
sudo apt install -q ninja-build patchelf
- name: Build Android SDK
working-directory: swift-ci/sdks/android
run: ./build
run: |
TARGET_ARCHS=${{ matrix.arch }} ./build
- name: Get artifact info
id: info
shell: bash
run: |
set -ex
SWIFT_ROOT=$(dirname ${{ runner.temp }}/swift-android-sdk/host-toolchain/*/usr)
echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT
echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT

ARTIFACT_BUILD=$(realpath ${{ runner.temp }}/swift-android-sdk/build/*.artifactbundle)
ARTIFACT_PATH=$(realpath ${{ runner.temp }}/swift-android-sdk/products/*.artifactbundle.tar.gz)
echo "artifact-path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT
echo "sdk-id=x86_64-unknown-linux-android28" >> $GITHUB_OUTPUT

ARTIFACT_EXT=".artifactbundle.tar.gz"
ARTIFACT_NAME="$(basename ${ARTIFACT_PATH} ${ARTIFACT_EXT})"
# artifacts need a unique name so we suffix with the matrix arch(s)
if [[ ! -z "${{ matrix.arch }}" ]]; then
ARTIFACT_NAME="${ARTIFACT_NAME}-$(echo ${{ matrix.arch }} | tr ',' '-')"
fi
ARTIFACT_NAME="${ARTIFACT_NAME}${ARTIFACT_EXT}"

# There is no way to prevent even a single-file artifact from being zipped:
# https://github.com/actions/upload-artifact?tab=readme-ov-file#zip-archives
# so the actual artifact download will look like:
# swift-6.1-RELEASE_android-0.1-x86_64.artifactbundle.tar.gz.zip
echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT

# validate some required paths in the artifactbundle
pushd ${ARTIFACT_BUILD}/*/*/usr
ls lib/swift/android
ls lib/swift/android/*
ls lib/swift/android/*/swiftrt.o
ls lib/*-linux-android/*/crtbegin_dynamic.o

ls lib/swift_static-*
ls lib/swift_static-*/android
ls lib/swift_static-*/android/libFoundationEssentials.a

ls lib/*-linux-android/libFoundationEssentials.so
ls lib/*-linux-android/libFoundationNetworking.so
ls lib/*-linux-android/libFoundationInternationalization.so
ls lib/*-linux-android/lib_FoundationICU.so
ls lib/*-linux-android/libFoundationXML.so
ls lib/*-linux-android/libTesting.so

ls lib/swift/clang/lib
ls lib/swift/clang/lib/linux
ls lib/swift/clang/lib/linux/*/libunwind.a
popd
- name: Upload SDK artifactbundle
uses: actions/upload-artifact@v4
with:
compression-level: 0
name: ${{ steps.info.outputs.artifact-name }}
path: ${{ steps.info.outputs.artifact-path }}
- name: Cleanup
run: |
# need to free up some space or else when installing we get: No space left on device
rm -rf ${{ runner.temp }}/swift-android-sdk/{build,src}
- name: Install artifactbundle
shell: bash
run: |
set -ex
${{ steps.info.outputs.swift-path }} sdk install ${{ steps.info.outputs.artifact-path }}
${{ steps.info.outputs.swift-path }} sdk configure --show-configuration $(${{ steps.info.outputs.swift-path }} sdk list | head -n 1) ${{ steps.info.outputs.sdk-id }}
# recent releases require that ANDROID_NDK_ROOT *not* be set
# see https://github.com/finagolfin/swift-android-sdk/issues/207
echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV

- name: Create Demo Project
run: |
cd ${{ runner.temp }}
mkdir DemoProject
cd DemoProject
${{ steps.info.outputs.swift-path }} --version
${{ steps.info.outputs.swift-path }} package init
echo 'import Foundation' >> Sources/DemoProject/DemoProject.swift
echo 'import FoundationEssentials' >> Sources/DemoProject/DemoProject.swift
echo 'import FoundationXML' >> Sources/DemoProject/DemoProject.swift
echo 'import FoundationNetworking' >> Sources/DemoProject/DemoProject.swift
echo 'import Dispatch' >> Sources/DemoProject/DemoProject.swift
echo 'import Android' >> Sources/DemoProject/DemoProject.swift
- name: Test Demo Project on Android
uses: skiptools/swift-android-action@v2
with:
# only test for the complete arch SDK build to speed up CI
run-tests: ${{ matrix.arch == '' }}
package-path: ${{ runner.temp }}/DemoProject
installed-sdk: ${{ steps.info.outputs.sdk-id }}
installed-swift: ${{ steps.info.outputs.swift-root }}

- name: Checkout swift-algorithms
uses: actions/checkout@v4
with:
repository: apple/swift-algorithms
path: swift-algorithms
- name: Test swift-algorithms
uses: skiptools/swift-android-action@v2
with:
run-tests: ${{ matrix.arch == '' }}
package-path: swift-algorithms
installed-sdk: ${{ steps.info.outputs.sdk-id }}
installed-swift: ${{ steps.info.outputs.swift-root }}

43 changes: 43 additions & 0 deletions swift-ci/sdks/android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Build scripts for Swift Android SDK

This folder contains scripts to build a Swift Android SDK
in the form of an artifactbundle.

## Running

The top-level `./build` script installs a host toolchain and the
Android NDK, and then invokes `scripts/fetch-source.sh` which will
fetch tagged sources for libxml2, curl, boringssl, and swift.

It then applies some patches and invokes `scripts/build.sh`,
which will build the sources for each of the specified
architectures. Finally, it combines the NDK and the newly built
SDKs into a single artifactbundle.

## Specifying Architectures

By default all the supported Android architectures
(`aarch64`, `x86_64`, `aarmv7`)
will be built, but this can be reduced in order to speed
up the build. This can be useful, e.g., as part of a CI that
validates a pull request, as building a single architecture
takes around 30 minutes on a standard ubuntu-24.04 GitHub runner,
whereas building for all the architectures takes over an hour.

To build an artifactbundle for just the `x86_64` architecture, run:

```
TARGET_ARCHS=x86_64 ./build
```

## Installing and validating the SDK

The `.github/workflows/pull_request.yml` workflow
will create and upload an installable SDK named something like:
`swift-6.1-RELEASE_android-0.1.artifactbundle.tar.gz`

The workflow will also install the SDK locally and use
[swift-android-action](https://github.com/marketplace/actions/swift-android-action)
to build and test various Swift packages in an Android emulator.


91 changes: 91 additions & 0 deletions swift-ci/sdks/android/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/bin/bash -e
# Swift Android SDK: Top-level Build Script

# default architectures to build for
TARGET_ARCHS=${TARGET_ARCHS:-aarch64,x86_64,armv7}

ANDROID_NDK_VERSION=android-ndk-r27c
ANDROID_API=28

SDKROOT=${RUNNER_TEMP:-${TMPDIR:-'/tmp'}}/swift-android-sdk
mkdir -p ${SDKROOT}

# Install a Swift host toolchain if it isn't already present
SWIFT_ROOT=${SDKROOT}/host-toolchain
HOST_OS=ubuntu$(lsb_release -sr)
SWIFT_VERSION=6.1
SWIFT_TAG="swift-${SWIFT_VERSION}-RELEASE"
SWIFT_BRANCH="swift-$(echo $SWIFT_TAG | cut -d- -f2)-release"
SWIFT_BASE=$SWIFT_TAG-$HOST_OS

if [[ ! -d $SWIFT_ROOT ]]; then
mkdir -p $SWIFT_ROOT
pushd $SWIFT_ROOT

SWIFT_URL="https://download.swift.org/$SWIFT_BRANCH/$(echo $HOST_OS | tr -d '.')/$SWIFT_TAG/$SWIFT_BASE.tar.gz"
wget -q $SWIFT_URL
tar xzf $SWIFT_BASE.tar.gz

popd
fi

#HOST_TOOLCHAIN=${HOST_TOOLCHAIN:-$(dirname $(dirname $(which swiftc)))}
HOST_TOOLCHAIN=$SWIFT_ROOT/$SWIFT_BASE/usr
$HOST_TOOLCHAIN/bin/swift --version

# ensure the correct Swift is first in the PATH
export PATH=$HOST_TOOLCHAIN/bin:$PATH

export ANDROID_NDK_HOME=${SDKROOT}/ndk/${ANDROID_NDK_VERSION}
export ANDROID_NDK=${ANDROID_NDK_HOME}

if [[ ! -d ${ANDROID_NDK_HOME} ]]; then
mkdir -p $(dirname ${ANDROID_NDK_HOME})
pushd $(dirname ${ANDROID_NDK_HOME})
NDKFILE=$(basename $ANDROID_NDK_HOME)-linux.zip
wget -q https://dl.google.com/android/repository/${NDKFILE}
unzip -q ${NDKFILE}
popd
fi

mkdir -p ${SDKROOT}/products

# Check-out the sources
if [[ ! -d ${SDKROOT}/src ]]; then
scripts/fetch-source.sh --source-dir ${SDKROOT}/src --swift-tag ${SWIFT_TAG}
fi

# fetch and apply the patches
PATCHDIR=${SDKROOT}/patches
if [[ ! -d ${PATCHDIR} ]]; then
git clone https://github.com/finagolfin/swift-android-sdk.git ${PATCHDIR}

# TODO: need to selectively apply patches based on release or not release
pushd ${SDKROOT}/src/swift-project
echo "Applying patches"

# patch the patch, which seems to only be needed for an API less than 28
# https://github.com/finagolfin/swift-android-sdk/blob/main/swift-android.patch#L110
perl -pi -e 's/#if os\(Windows\)/#if os\(Android\)/g' $PATCHDIR/swift-android.patch

# remove the need to link in android-execinfo
perl -pi -e 's/dispatch android-execinfo/dispatch/g' $PATCHDIR/swift-android.patch

git apply -v $PATCHDIR/swift-android.patch
# swift-android-ci.patch is not needed, since it is only used for llbuild, etc.
#git apply -C1 $PATCHDIR/swift-android-ci.patch
#git apply -v $PATCHDIR/swift-android-ci-release.patch
git apply -v $PATCHDIR/swift-android-testing-release.patch

perl -pi -e 's%String\(cString: getpass%\"fake\" //%' swiftpm/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift
# disable backtrace() for Android (needs either API33+ or libandroid-execinfo, or to manually add in backtrace backport)
perl -pi -e 's/os\(Android\)/os\(AndroidDISABLED\)/g' swift-testing/Sources/Testing/SourceAttribution/Backtrace.swift

# need to un-apply libandroid-spawn since we don't need it for API28+
perl -pi -e 's/MATCHES "Android"/MATCHES "AndroidDISABLED"/g' llbuild/lib/llvm/Support/CMakeLists.txt
perl -pi -e 's/ STREQUAL Android\)/ STREQUAL AndroidDISABLED\)/g' swift-corelibs-foundation/Sources/Foundation/CMakeLists.txt
popd
fi

./scripts/build.sh --products-dir ${SDKROOT}/products --source-dir ${SDKROOT}/src --build-dir ${SDKROOT}/build --ndk-home ${ANDROID_NDK_HOME} --android-api ${ANDROID_API} --host-toolchain ${HOST_TOOLCHAIN} --archs ${TARGET_ARCHS}

Loading
Loading