Skip to content

Commit 6565052

Browse files
marcpruxshahmishalcmcgee1024justice-adams-applesookach
authored
Build Android image (#1)
* Build Android image * Checkout without ssh * Retry build if it fails * Swift 6.1 Release Dockerfiles (swiftlang#456) * Change binutils-gold package dependency on Debian 12 to binutils (swiftlang#457) * Update installed packages after nightly platform expansion (swiftlang#458) * update nightly-6.1 dependencies * update nightly-main dependencies * fix ubuntu images * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Fedora 41 Dockerfile (swiftlang#464) * Build Android image * Build Android image * Swift 6.1 Release Dockerfiles (swiftlang#456) * Change binutils-gold package dependency on Debian 12 to binutils (swiftlang#457) * Build Android image * Build Android image * Build Android image * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Android SDK build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Androd build * Swift Android build * Swift Android build * Swift Android build * Swift Android build --------- Co-authored-by: Mishal Shah <[email protected]> Co-authored-by: Chris McGee <[email protected]> Co-authored-by: Justice Adams <[email protected]> Co-authored-by: Andrew Sukach <[email protected]>
1 parent dd6d09f commit 6565052

File tree

5 files changed

+974
-5
lines changed

5 files changed

+974
-5
lines changed

.github/workflows/pull_request.yml

+121-5
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,129 @@ jobs:
3333
run: ./build
3434

3535
android-build:
36-
name: Build Android image
37-
runs-on: ubuntu-latest
38-
if: false
36+
name: Build Android ${{ matrix.arch }} SDK
37+
strategy:
38+
fail-fast: false
39+
matrix:
40+
# blank arch builds all (aarch64,x86_64,armv7)
41+
#arch: ['']
42+
# builds only x86_64 to speed up the validation
43+
#arch: ['x86_64']
44+
# build both the quick (x86_64) and complete (aarch64,x86_64,armv7) SDKs
45+
arch: ['x86_64', '']
46+
runs-on: ubuntu-24.04
3947
steps:
4048
- name: Checkout repository
4149
uses: actions/checkout@v4
42-
- name: Build Docker images
50+
- name: Install Dependencies
51+
run: |
52+
sudo apt install -q ninja-build patchelf
53+
- name: Build Android SDK
4354
working-directory: swift-ci/sdks/android
44-
run: ./build
55+
run: |
56+
TARGET_ARCHS=${{ matrix.arch }} ./build
57+
- name: Get artifact info
58+
id: info
59+
shell: bash
60+
run: |
61+
set -ex
62+
SWIFT_ROOT=$(dirname ${{ runner.temp }}/swift-android-sdk/host-toolchain/*/usr)
63+
echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT
64+
echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT
65+
66+
ARTIFACT_BUILD=$(realpath ${{ runner.temp }}/swift-android-sdk/build/*.artifactbundle)
67+
ARTIFACT_PATH=$(realpath ${{ runner.temp }}/swift-android-sdk/products/*.artifactbundle.tar.gz)
68+
echo "artifact-path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT
69+
echo "sdk-id=x86_64-unknown-linux-android28" >> $GITHUB_OUTPUT
70+
71+
ARTIFACT_EXT=".artifactbundle.tar.gz"
72+
ARTIFACT_NAME="$(basename ${ARTIFACT_PATH} ${ARTIFACT_EXT})"
73+
# artifacts need a unique name so we suffix with the matrix arch(s)
74+
if [[ ! -z "${{ matrix.arch }}" ]]; then
75+
ARTIFACT_NAME="${ARTIFACT_NAME}-$(echo ${{ matrix.arch }} | tr ',' '-')"
76+
fi
77+
ARTIFACT_NAME="${ARTIFACT_NAME}${ARTIFACT_EXT}"
78+
79+
# There is no way to prevent even a single-file artifact from being zipped:
80+
# https://github.com/actions/upload-artifact?tab=readme-ov-file#zip-archives
81+
# so the actual artifact download will look like:
82+
# swift-6.1-RELEASE_android-0.1-x86_64.artifactbundle.tar.gz.zip
83+
echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT
84+
85+
# validate some required paths in the artifactbundle
86+
pushd ${ARTIFACT_BUILD}/*/*/usr
87+
ls lib/swift/android
88+
ls lib/swift/android/*
89+
ls lib/swift/android/*/swiftrt.o
90+
ls lib/*-linux-android/*/crtbegin_dynamic.o
91+
92+
ls lib/swift_static-*
93+
ls lib/swift_static-*/android
94+
ls lib/swift_static-*/android/libFoundationEssentials.a
95+
96+
ls lib/*-linux-android/libFoundationEssentials.so
97+
ls lib/*-linux-android/libFoundationNetworking.so
98+
ls lib/*-linux-android/libFoundationInternationalization.so
99+
ls lib/*-linux-android/lib_FoundationICU.so
100+
ls lib/*-linux-android/libFoundationXML.so
101+
ls lib/*-linux-android/libTesting.so
102+
103+
ls lib/swift/clang/lib
104+
ls lib/swift/clang/lib/linux
105+
ls lib/swift/clang/lib/linux/*/libunwind.a
106+
popd
107+
- name: Upload SDK artifactbundle
108+
uses: actions/upload-artifact@v4
109+
with:
110+
compression-level: 0
111+
name: ${{ steps.info.outputs.artifact-name }}
112+
path: ${{ steps.info.outputs.artifact-path }}
113+
- name: Cleanup
114+
run: |
115+
# need to free up some space or else when installing we get: No space left on device
116+
rm -rf ${{ runner.temp }}/swift-android-sdk/{build,src}
117+
- name: Install artifactbundle
118+
shell: bash
119+
run: |
120+
set -ex
121+
${{ steps.info.outputs.swift-path }} sdk install ${{ steps.info.outputs.artifact-path }}
122+
${{ steps.info.outputs.swift-path }} sdk configure --show-configuration $(${{ steps.info.outputs.swift-path }} sdk list | head -n 1) ${{ steps.info.outputs.sdk-id }}
123+
# recent releases require that ANDROID_NDK_ROOT *not* be set
124+
# see https://github.com/finagolfin/swift-android-sdk/issues/207
125+
echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV
126+
127+
- name: Create Demo Project
128+
run: |
129+
cd ${{ runner.temp }}
130+
mkdir DemoProject
131+
cd DemoProject
132+
${{ steps.info.outputs.swift-path }} --version
133+
${{ steps.info.outputs.swift-path }} package init
134+
echo 'import Foundation' >> Sources/DemoProject/DemoProject.swift
135+
echo 'import FoundationEssentials' >> Sources/DemoProject/DemoProject.swift
136+
echo 'import FoundationXML' >> Sources/DemoProject/DemoProject.swift
137+
echo 'import FoundationNetworking' >> Sources/DemoProject/DemoProject.swift
138+
echo 'import Dispatch' >> Sources/DemoProject/DemoProject.swift
139+
echo 'import Android' >> Sources/DemoProject/DemoProject.swift
140+
- name: Test Demo Project on Android
141+
uses: skiptools/swift-android-action@v2
142+
with:
143+
# only test for the complete arch SDK build to speed up CI
144+
run-tests: ${{ matrix.arch == '' }}
145+
package-path: ${{ runner.temp }}/DemoProject
146+
installed-sdk: ${{ steps.info.outputs.sdk-id }}
147+
installed-swift: ${{ steps.info.outputs.swift-root }}
148+
149+
- name: Checkout swift-algorithms
150+
uses: actions/checkout@v4
151+
with:
152+
repository: apple/swift-algorithms
153+
path: swift-algorithms
154+
- name: Test swift-algorithms
155+
uses: skiptools/swift-android-action@v2
156+
with:
157+
run-tests: ${{ matrix.arch == '' }}
158+
package-path: swift-algorithms
159+
installed-sdk: ${{ steps.info.outputs.sdk-id }}
160+
installed-swift: ${{ steps.info.outputs.swift-root }}
45161

swift-ci/sdks/android/README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Build scripts for Swift Android SDK
2+
3+
This folder contains scripts to build a Swift Android SDK
4+
in the form of an artifactbundle.
5+
6+
## Running
7+
8+
The top-level `./build` script installs a host toolchain and the
9+
Android NDK, and then invokes `scripts/fetch-source.sh` which will
10+
fetch tagged sources for libxml2, curl, boringssl, and swift.
11+
12+
It then applies some patches and invokes `scripts/build.sh`,
13+
which will build the sources for each of the specified
14+
architectures. Finally, it combines the NDK and the newly built
15+
SDKs into a single artifactbundle.
16+
17+
## Specifying Architectures
18+
19+
By default all the supported Android architectures
20+
(`aarch64`, `x86_64`, `aarmv7`)
21+
will be built, but this can be reduced in order to speed
22+
up the build. This can be useful, e.g., as part of a CI that
23+
validates a pull request, as building a single architecture
24+
takes around 30 minutes on a standard ubuntu-24.04 GitHub runner,
25+
whereas building for all the architectures takes over an hour.
26+
27+
To build an artifactbundle for just the `x86_64` architecture, run:
28+
29+
```
30+
TARGET_ARCHS=x86_64 ./build
31+
```
32+
33+
## Installing and validating the SDK
34+
35+
The `.github/workflows/pull_request.yml` workflow
36+
will create and upload an installable SDK named something like:
37+
`swift-6.1-RELEASE_android-0.1.artifactbundle.tar.gz`
38+
39+
The workflow will also install the SDK locally and use
40+
[swift-android-action](https://github.com/marketplace/actions/swift-android-action)
41+
to build and test various Swift packages in an Android emulator.
42+
43+

swift-ci/sdks/android/build

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/bin/bash -e
2+
# Swift Android SDK: Top-level Build Script
3+
4+
# default architectures to build for
5+
TARGET_ARCHS=${TARGET_ARCHS:-aarch64,x86_64,armv7}
6+
7+
ANDROID_NDK_VERSION=android-ndk-r27c
8+
ANDROID_API=28
9+
10+
SDKROOT=${RUNNER_TEMP:-${TMPDIR:-'/tmp'}}/swift-android-sdk
11+
mkdir -p ${SDKROOT}
12+
13+
# Install a Swift host toolchain if it isn't already present
14+
SWIFT_ROOT=${SDKROOT}/host-toolchain
15+
HOST_OS=ubuntu$(lsb_release -sr)
16+
SWIFT_VERSION=6.1
17+
SWIFT_TAG="swift-${SWIFT_VERSION}-RELEASE"
18+
SWIFT_BRANCH="swift-$(echo $SWIFT_TAG | cut -d- -f2)-release"
19+
SWIFT_BASE=$SWIFT_TAG-$HOST_OS
20+
21+
if [[ ! -d $SWIFT_ROOT ]]; then
22+
mkdir -p $SWIFT_ROOT
23+
pushd $SWIFT_ROOT
24+
25+
SWIFT_URL="https://download.swift.org/$SWIFT_BRANCH/$(echo $HOST_OS | tr -d '.')/$SWIFT_TAG/$SWIFT_BASE.tar.gz"
26+
wget -q $SWIFT_URL
27+
tar xzf $SWIFT_BASE.tar.gz
28+
29+
popd
30+
fi
31+
32+
#HOST_TOOLCHAIN=${HOST_TOOLCHAIN:-$(dirname $(dirname $(which swiftc)))}
33+
HOST_TOOLCHAIN=$SWIFT_ROOT/$SWIFT_BASE/usr
34+
$HOST_TOOLCHAIN/bin/swift --version
35+
36+
# ensure the correct Swift is first in the PATH
37+
export PATH=$HOST_TOOLCHAIN/bin:$PATH
38+
39+
export ANDROID_NDK_HOME=${SDKROOT}/ndk/${ANDROID_NDK_VERSION}
40+
export ANDROID_NDK=${ANDROID_NDK_HOME}
41+
42+
if [[ ! -d ${ANDROID_NDK_HOME} ]]; then
43+
mkdir -p $(dirname ${ANDROID_NDK_HOME})
44+
pushd $(dirname ${ANDROID_NDK_HOME})
45+
NDKFILE=$(basename $ANDROID_NDK_HOME)-linux.zip
46+
wget -q https://dl.google.com/android/repository/${NDKFILE}
47+
unzip -q ${NDKFILE}
48+
popd
49+
fi
50+
51+
mkdir -p ${SDKROOT}/products
52+
53+
# Check-out the sources
54+
if [[ ! -d ${SDKROOT}/src ]]; then
55+
scripts/fetch-source.sh --source-dir ${SDKROOT}/src --swift-tag ${SWIFT_TAG}
56+
fi
57+
58+
# fetch and apply the patches
59+
PATCHDIR=${SDKROOT}/patches
60+
if [[ ! -d ${PATCHDIR} ]]; then
61+
git clone https://github.com/finagolfin/swift-android-sdk.git ${PATCHDIR}
62+
63+
# TODO: need to selectively apply patches based on release or not release
64+
pushd ${SDKROOT}/src/swift-project
65+
echo "Applying patches"
66+
67+
# patch the patch, which seems to only be needed for an API less than 28
68+
# https://github.com/finagolfin/swift-android-sdk/blob/main/swift-android.patch#L110
69+
perl -pi -e 's/#if os\(Windows\)/#if os\(Android\)/g' $PATCHDIR/swift-android.patch
70+
71+
# remove the need to link in android-execinfo
72+
perl -pi -e 's/dispatch android-execinfo/dispatch/g' $PATCHDIR/swift-android.patch
73+
74+
git apply -v $PATCHDIR/swift-android.patch
75+
# swift-android-ci.patch is not needed, since it is only used for llbuild, etc.
76+
#git apply -C1 $PATCHDIR/swift-android-ci.patch
77+
#git apply -v $PATCHDIR/swift-android-ci-release.patch
78+
git apply -v $PATCHDIR/swift-android-testing-release.patch
79+
80+
perl -pi -e 's%String\(cString: getpass%\"fake\" //%' swiftpm/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift
81+
# disable backtrace() for Android (needs either API33+ or libandroid-execinfo, or to manually add in backtrace backport)
82+
perl -pi -e 's/os\(Android\)/os\(AndroidDISABLED\)/g' swift-testing/Sources/Testing/SourceAttribution/Backtrace.swift
83+
84+
# need to un-apply libandroid-spawn since we don't need it for API28+
85+
perl -pi -e 's/MATCHES "Android"/MATCHES "AndroidDISABLED"/g' llbuild/lib/llvm/Support/CMakeLists.txt
86+
perl -pi -e 's/ STREQUAL Android\)/ STREQUAL AndroidDISABLED\)/g' swift-corelibs-foundation/Sources/Foundation/CMakeLists.txt
87+
popd
88+
fi
89+
90+
./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}
91+

0 commit comments

Comments
 (0)