Skip to content

Commit 72964f5

Browse files
authored
Build SDK in Docker container (#4)
* Add static libraries to post-install script * Add post-install script to SDK bundle * Add post-install script to SDK bundle * Update submodules
1 parent 53e361a commit 72964f5

File tree

13 files changed

+611
-218
lines changed

13 files changed

+611
-218
lines changed

.github/workflows/pull_request.yml

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ env:
88
jobs:
99
build:
1010
name: Build Docker images
11-
# disabled for CI testing
12-
if: false
1311
runs-on: ubuntu-latest
1412
steps:
1513
- name: Checkout repository
@@ -26,8 +24,6 @@ jobs:
2624
2725
static-linux-build:
2826
name: Build Static Linux image
29-
# disabled for CI testing
30-
if: false
3127
runs-on: ubuntu-latest
3228
steps:
3329
- name: Checkout repository
@@ -37,16 +33,18 @@ jobs:
3733
run: ./build
3834

3935
android-build:
40-
name: Build Android ${{ matrix.swift-version }} ${{ matrix.arch }} SDK
36+
name: Build Android ${{ matrix.build-type }} ${{ matrix.swift-version }} ${{ matrix.arch }} SDK
4137
strategy:
4238
fail-fast: false
4339
matrix:
40+
build-type: ['docker']
41+
#build-type: ['docker', 'local']
4442
# blank arch builds all (aarch64,x86_64,armv7)
45-
#arch: ['']
43+
arch: ['']
4644
# builds only x86_64 to speed up the validation
4745
#arch: ['x86_64']
4846
# build both the quick (x86_64) and complete (aarch64,x86_64,armv7) SDKs
49-
arch: ['x86_64', '']
47+
#arch: ['x86_64', '']
5048
swift-version: ['release', 'devel', 'trunk']
5149
runs-on: ubuntu-24.04
5250
steps:
@@ -59,31 +57,60 @@ jobs:
5957
sudo docker image prune --all --force
6058
sudo docker builder prune -a
6159
df -h
60+
- name: Setup
61+
id: config
62+
run: |
63+
# these variabes are used by build-docker and build-local
64+
# to determine which Swift version to build for
65+
echo "BUILD_VERSION=${{ matrix.swift-version }}" >> $GITHUB_ENV
66+
echo "TARGET_ARCHS=${{ matrix.arch }}" >> $GITHUB_ENV
67+
echo "WORKDIR=${{ runner.temp }}/swift-android-sdk" >> $GITHUB_ENV
6268
- name: Checkout repository
6369
uses: actions/checkout@v4
64-
- name: Install Dependencies
70+
with:
71+
submodules: 'true'
72+
- name: Build Android SDK (Local)
73+
if: ${{ matrix.build-type == 'local' }}
74+
working-directory: swift-ci/sdks/android
6575
run: |
6676
sudo apt install -q ninja-build patchelf
67-
- name: Build Android SDK
77+
./build-local ${BUILD_VERSION} ${WORKDIR}
78+
- name: Build Android SDK (Docker)
79+
if: ${{ matrix.build-type == 'docker' }}
80+
working-directory: swift-ci/sdks/android
81+
run: |
82+
./build-docker ${BUILD_VERSION} ${WORKDIR}
83+
- name: Install Host Toolchain
84+
if: ${{ matrix.build-type == 'docker' }}
6885
working-directory: swift-ci/sdks/android
6986
run: |
70-
BUILD_VERSION=${{ matrix.swift-version }} TARGET_ARCHS=${{ matrix.arch }} ./build
87+
# when building in a Docker container, we don't have a local host toolchain,
88+
# but we need one in order to run the SDK validation tests, so we install it now
89+
HOST_OS=ubuntu$(lsb_release -sr)
90+
source ./scripts/toolchain-vars.sh
91+
mkdir -p ${WORKDIR}/host-toolchain
92+
./scripts/install-swift.sh ${WORKDIR}/host-toolchain/$SWIFT_BASE/usr
93+
ls ${WORKDIR}/host-toolchain
94+
${WORKDIR}/host-toolchain/*/usr/bin/swift --version
7195
- name: Get artifact info
7296
id: info
7397
shell: bash
7498
run: |
7599
set -ex
76-
SWIFT_ROOT=$(dirname ${{ runner.temp }}/swift-android-sdk/host-toolchain/*/usr)
100+
SWIFT_ROOT=$(dirname ${WORKDIR}/host-toolchain/*/usr)
77101
echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT
78102
echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT
79103
80-
ARTIFACT_BUILD=$(realpath ${{ runner.temp }}/swift-android-sdk/build/*.artifactbundle)
81-
ARTIFACT_PATH=$(realpath ${{ runner.temp }}/swift-android-sdk/products/*.artifactbundle.tar.gz)
104+
ARTIFACT_PATH=$(realpath ${WORKDIR}/products/*.artifactbundle.tar.gz)
82105
echo "artifact-path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT
83106
echo "sdk-id=x86_64-unknown-linux-android28" >> $GITHUB_OUTPUT
84107
85108
ARTIFACT_EXT=".artifactbundle.tar.gz"
86109
ARTIFACT_NAME="$(basename ${ARTIFACT_PATH} ${ARTIFACT_EXT})"
110+
# depending on whether we are building locally or in a container, add a maker to the name
111+
if [[ "${{ matrix.build-type }}" == 'local' ]]; then
112+
ARTIFACT_NAME="${ARTIFACT_NAME}-local"
113+
fi
87114
# artifacts need a unique name so we suffix with the matrix arch(s)
88115
if [[ ! -z "${{ matrix.arch }}" ]]; then
89116
ARTIFACT_NAME="${ARTIFACT_NAME}-$(echo ${{ matrix.arch }} | tr ',' '-')"
@@ -95,9 +122,6 @@ jobs:
95122
# so the actual artifact download will look like:
96123
# swift-6.1-RELEASE_android-0.1-x86_64.artifactbundle.tar.gz.zip
97124
echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT
98-
99-
# show an abridged tree
100-
tree ${ARTIFACT_BUILD} --filesfirst --prune -P 'Android.swiftmodule' -P 'libswiftAndroid.*' -P 'libFoundation.*' -P 'swiftrt.o' -P 'swift*.json' -P 'info.json' -P 'api-level.h' -P 'android.modulemap' -P 'SwiftAndroidNDK.h' -P 'bridging.modulemap' -P 'linux' -P 'libclang*.a' -P 'libunwind.a' -P 'libclang_rt.builtins-*-android.a'
101125
- name: Upload SDK artifactbundle
102126
uses: actions/upload-artifact@v4
103127
with:
@@ -108,7 +132,9 @@ jobs:
108132
run: |
109133
# need to free up some space or else when installing we get: No space left on device
110134
df -h
111-
rm -rf ${{ runner.temp }}/swift-android-sdk/{build,src}
135+
rm -rf ${WORKDIR}/{build,source}
136+
sudo docker image prune --all --force
137+
sudo docker builder prune -a
112138
df -h
113139
- name: Install artifactbundle
114140
shell: bash
@@ -117,7 +143,7 @@ jobs:
117143
${{ steps.info.outputs.swift-path }} sdk install ${{ steps.info.outputs.artifact-path }}
118144
${{ steps.info.outputs.swift-path }} sdk configure --show-configuration $(${{ steps.info.outputs.swift-path }} sdk list | head -n 1) ${{ steps.info.outputs.sdk-id }}
119145
# recent releases require that ANDROID_NDK_ROOT *not* be set
120-
# see https://github.com/finagolfin/swift-android-sdk/issues/207
146+
# see https://github.com/swiftlang/swift-driver/pull/1879
121147
echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV
122148
123149
- name: Create Demo Project

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "swift-ci/sdks/android/resources/patches"]
2+
path = swift-ci/sdks/android/resources/patches
3+
url = https://github.com/swift-android-sdk/swift-android-sdk

swift-ci/sdks/android/Dockerfile

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# ===----------------------------------------------------------------------===
2+
#
3+
# Swift Android SDK: Docker-based build
4+
#
5+
# ===----------------------------------------------------------------------===
6+
7+
FROM ubuntu:24.04
8+
9+
# Architecture to build on (empty means x86-64)
10+
ARG OS_ARCH_SUFFIX=
11+
12+
# the Swift toolchain URL to download
13+
ARG SWIFT_TOOLCHAIN_URL=
14+
15+
# ............................................................................
16+
17+
# Install development tools
18+
RUN apt-get -q update \
19+
&& DEBIAN_FRONTEND=noninteractive apt-get -q install -y \
20+
build-essential \
21+
cmake \
22+
ninja-build \
23+
python3 \
24+
golang \
25+
git \
26+
gnupg2 \
27+
libsqlite3-dev \
28+
libcurl4-openssl-dev \
29+
libedit-dev \
30+
libicu-dev \
31+
libncurses5-dev \
32+
libpython3-dev \
33+
libsqlite3-dev \
34+
libxml2-dev \
35+
rsync \
36+
uuid-dev \
37+
uuid-runtime \
38+
tzdata \
39+
curl \
40+
unzip \
41+
&& rm -rf /var/lib/apt-lists/*
42+
43+
# Install Swift
44+
ARG SWIFT_SIGNING_KEY=E813C892820A6FA13755B268F167DF1ACF9CE069
45+
ARG SWIFT_PLATFORM=ubuntu
46+
ARG OS_MAJOR_VER=24
47+
ARG OS_MINOR_VER=04
48+
49+
ENV SWIFT_SIGNING_KEY=$SWIFT_SIGNING_KEY \
50+
SWIFT_PLATFORM=$SWIFT_PLATFORM \
51+
OS_MAJOR_VER=$OS_MAJOR_VER \
52+
OS_MINOR_VER=$OS_MINOR_VER \
53+
OS_VER=$SWIFT_PLATFORM$OS_MAJOR_VER.$OS_MINOR_VER
54+
55+
COPY scripts/install-swift.sh /scripts/install-swift.sh
56+
RUN chmod ugo+x /scripts/install-swift.sh
57+
RUN /scripts/install-swift.sh /usr/local/swift
58+
ENV PATH="/usr/local/swift/bin:${PATH}"
59+
60+
ARG ANDROID_NDK_VERSION=
61+
62+
ENV ANDROID_NDK_VERSION=$ANDROID_NDK_VERSION
63+
64+
COPY scripts/install-ndk.sh /scripts/install-ndk.sh
65+
RUN chmod ugo+x /scripts/install-ndk.sh
66+
RUN /scripts/install-ndk.sh
67+
ENV ANDROID_NDK_HOME="/usr/local/ndk/${ANDROID_NDK_VERSION}"
68+
69+
ENV SWIFT_VERSION=$SWIFT_VERSION \
70+
LIBXML2_VERSION=$LIBXML2_VERSION \
71+
CURL_VERSION=$CURL_VERSION \
72+
BORINGSSL_VERSION=$BORINGSSL_VERSION \
73+
ICU_VERSION=$ICU_VERSION \
74+
ZLIB_VERSION=$ZLIB_VERSION
75+
76+
ENV SWIFT_BUILD_DOCKER="1"
77+
78+
COPY scripts /scripts
79+
RUN chmod ugo+x /scripts/*
80+
81+
COPY resources /resources
82+
83+
# Create a user
84+
RUN groupadd -g 998 build-user && \
85+
useradd -m -r -u 998 -g build-user build-user
86+
87+
USER build-user
88+
89+
WORKDIR /home/build-user

swift-ci/sdks/android/README.md

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,39 @@
1-
# Build scripts for Swift Android SDK
1+
# Dockerfile-based build for Swift Android SDK
22

3-
This folder contains scripts to build a Swift Android SDK
4-
in the form of an artifactbundle.
3+
This is a Dockerfile-based build set-up for the Swift Android SDK.
4+
5+
The top-level `./build-docker` script will create a
6+
Docker container and install a host toolchain and the
7+
Android NDK, and then invoke `scripts/fetch-source.sh` which will
8+
fetch tagged sources for libxml2, curl, boringssl, and swift.
9+
10+
It can be run with:
11+
12+
```
13+
$ ./build-docker <version> <workdir>
14+
```
15+
16+
for example:
17+
18+
```
19+
$ ./build-docker release /tmp/android-sdk
20+
```
21+
22+
This will create an Ubuntu 24.04 container with the necessary dependencies
23+
to build the Android SDK, including a Swift host toolchain and the
24+
Android NDK that will be used for cross-compilation.
25+
26+
The `version` argument can be one of the following values:
27+
28+
| version | Swift version |
29+
| --- | --- |
30+
| `release` | swift-6.1-RELEASE |
31+
| `devel` | swift-6.2-DEVELOPMENT-SNAPSHOT-yyyy-mm-dd |
32+
| `trunk` | swift-DEVELOPMENT-SNAPSHOT-yyyy-mm-dd |
533

634
## Running
735

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

@@ -27,7 +55,7 @@ whereas building for all the architectures takes over an hour.
2755
To build an artifactbundle for just the `x86_64` architecture, run:
2856

2957
```
30-
TARGET_ARCHS=x86_64 ./build
58+
TARGET_ARCHS=aarch64 ./build-docker release /tmp/android-sdk
3159
```
3260

3361
## Installing and validating the SDK
@@ -38,6 +66,5 @@ will create and upload an installable SDK named something like:
3866

3967
The workflow will also install the SDK locally and use
4068
[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-
69+
to build and test various Swift packages in an Android emulator using the
70+
freshly-created SDK bundle.

0 commit comments

Comments
 (0)