Cache latest Android NDK sysroot on the CI and update some Foundation patches #2128
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: SDKs | |
on: | |
pull_request: | |
schedule: | |
- cron: '0 9 * * *' | |
jobs: | |
get-latest-toolchain: | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
version: [release, devel, trunk] | |
outputs: | |
release-version: ${{ steps.check.outputs.release-tag }} | |
devel-version: ${{ steps.check.outputs.devel-tag }} | |
trunk-version: ${{ steps.check.outputs.trunk-tag }} | |
new-devel-tag: ${{ steps.download.outputs.devel-updated == 'true' }} | |
steps: | |
- name: Check for latest Swift ${{ matrix.version }} toolchain | |
id: check | |
run: | | |
if [ ${{ matrix.version }} = 'release' ]; then | |
LATEST_TOOLCHAIN_VERSION=$(curl -sL https://github.com/apple/swift/releases | grep -m1 swift-6.0 | cut -d- -f2) | |
SWIFT_TAG="swift-${LATEST_TOOLCHAIN_VERSION}-RELEASE" | |
echo "release-tag=$SWIFT_TAG" >> $GITHUB_OUTPUT | |
elif [ ${{ matrix.version }} = 'devel' ]; then | |
LATEST_TOOLCHAIN_VERSION=$(curl -sL https://github.com/apple/swift/tags | grep -m1 swift-6.0-DEV | cut -d- -f8-10) | |
SWIFT_TAG="swift-6.0-DEVELOPMENT-SNAPSHOT-${LATEST_TOOLCHAIN_VERSION}-a" | |
echo "devel-tag=$SWIFT_TAG" >> $GITHUB_OUTPUT | |
else | |
LATEST_TOOLCHAIN_VERSION=$(curl -sL https://github.com/apple/swift/tags | grep -m1 swift-DEV | cut -d- -f7-9) | |
SWIFT_TAG="swift-DEVELOPMENT-SNAPSHOT-${LATEST_TOOLCHAIN_VERSION}-a" | |
echo "trunk-tag=$SWIFT_TAG" >> $GITHUB_OUTPUT | |
fi | |
echo "latest-tag=$SWIFT_TAG" >> $GITHUB_OUTPUT | |
- name: Get cached Ubuntu toolchain | |
id: cache-toolchain-ubuntu | |
uses: actions/cache@v4 | |
with: | |
path: ~/${{ steps.check.outputs.latest-tag }}-ubuntu22.04.tar.gz | |
key: swift-ubuntu-22.04-${{ steps.check.outputs.latest-tag }}-toolchain | |
lookup-only: true | |
- name: Get cached macOS toolchain | |
id: cache-toolchain-macos | |
uses: actions/cache@v4 | |
with: | |
path: ~/${{ steps.check.outputs.latest-tag }}-osx.pkg | |
key: swift-macos-13-${{ steps.check.outputs.latest-tag }}-toolchain | |
lookup-only: true | |
- name: Download toolchain | |
id: download | |
if: ${{ steps.cache-toolchain-ubuntu.outputs.cache-hit != 'true' || steps.cache-toolchain-macos.outputs.cache-hit != 'true' }} | |
run: | | |
SWIFT_TAG="${{ steps.check.outputs.latest-tag }}" | |
if [ ${{ matrix.version }} = 'release' ]; then | |
SWIFT_BRANCH="swift-$(echo ${{ steps.check.outputs.release-tag }} | cut -d- -f2)-release" | |
elif [ ${{ matrix.version }} = 'devel' ]; then | |
SWIFT_BRANCH="swift-6.0-branch" | |
echo "devel-updated='true'" >> $GITHUB_OUTPUT | |
else | |
SWIFT_BRANCH="development" | |
fi | |
cd | |
if [[ "${{ steps.cache-toolchain-macos.outputs.cache-hit }}" != 'true' ]]; then | |
wget -q https://download.swift.org/$SWIFT_BRANCH/xcode/$SWIFT_TAG/$SWIFT_TAG-osx.pkg | |
echo "downloaded latest macOS toolchain: ${SWIFT_TAG}" | |
fi | |
if [[ "${{ steps.cache-toolchain-ubuntu.outputs.cache-hit }}" != 'true' ]]; then | |
wget -q https://download.swift.org/$SWIFT_BRANCH/ubuntu2204/$SWIFT_TAG/$SWIFT_TAG-ubuntu22.04.tar.gz | |
echo "downloaded latest Ubuntu toolchain: ${SWIFT_TAG}" | |
fi | |
- name: Get cached Android NDK sysroot and runtime libraries | |
id: cache-ndk | |
uses: actions/cache@v4 | |
with: | |
path: ~/android-sysroot.tar.xz | |
key: android-ndk-27b | |
lookup-only: true | |
- name: Download Android NDK if not cached before | |
if: ${{ steps.cache-ndk.outputs.cache-hit != 'true' }} | |
run: | | |
wget -q https://dl.google.com/android/repository/android-ndk-r27b-linux.zip | |
if [ "$(sha1sum android-ndk-r27b-linux.zip | cut -f1 -d" ")" != '6fc476b2e57d7c01ac0c95817746b927035b9749' ]; then | |
echo "NDK checksum didn't match" | |
exit 1 | |
fi | |
unzip -q android-ndk-r27b-linux.zip | |
mv android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/sysroot . | |
rm -r sysroot/usr/{include,lib}/{i686,riscv64}-linux-android | |
mv android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/*/lib/linux sysroot | |
rm -r sysroot/linux/*{i[36]86,riscv64}* | |
tar cJf ~/android-sysroot.tar.xz sysroot | |
build-sdk-and-tests: | |
runs-on: ${{ matrix.os }} | |
needs: get-latest-toolchain | |
strategy: | |
fail-fast: false | |
matrix: | |
version: [release, devel, trunk] | |
arch: [x86_64, aarch64, armv7] | |
os: [ubuntu-22.04, macos-13] | |
exclude: | |
- os: macos-13 | |
version: trunk | |
- os: macos-13 | |
version: ${{ needs.get-latest-toolchain.outputs.new-devel-tag == 'true' && 'devel' || 'none' }} | |
env: | |
ANDROID_API_LEVEL: 24 | |
BUNDLE_VERSION: 0.1 | |
NDK_VERSION: 27b | |
steps: | |
- name: Extract the latest version string | |
id: version | |
run: | | |
if [[ ${{ matrix.version }} = 'release' ]]; then | |
TAG="${{ needs.get-latest-toolchain.outputs.release-version }}" | |
elif [ ${{ matrix.version }} = 'devel' ]; then | |
TAG="${{ needs.get-latest-toolchain.outputs.devel-version }}" | |
else | |
TAG="${{ needs.get-latest-toolchain.outputs.trunk-version }}" | |
fi | |
echo "tag=$TAG" >> $GITHUB_OUTPUT | |
KEY="$TAG-${{ matrix.arch }}-ndk-${NDK_VERSION}-arch-sdk" | |
echo "arch-key=$KEY" >> $GITHUB_OUTPUT | |
echo "key=$TAG-ndk-${NDK_VERSION}-bundle" >> $GITHUB_OUTPUT | |
if ${{ matrix.arch == 'x86_64' }}; then | |
echo "aarch64-key=${KEY/x86_64/aarch64}" >> $GITHUB_OUTPUT | |
echo "arm-key=${KEY/x86_64/armv7}" >> $GITHUB_OUTPUT | |
fi | |
- name: Get cached SDK bundle | |
id: cache-bundle | |
uses: actions/cache@v4 | |
if: ${{ matrix.version != 'trunk' }} | |
with: | |
path: ~/${{ steps.version.outputs.tag }}-android-${{ env.ANDROID_API_LEVEL }}-${{ env.BUNDLE_VERSION }}.artifactbundle.tar.gz | |
key: ${{ steps.version.outputs.key }} | |
- name: Get cached ${{ matrix.arch }} SDK otherwise | |
id: cache-sdk | |
uses: actions/cache/restore@v4 | |
if: ${{ steps.cache-bundle.outputs.cache-hit != 'true' }} | |
with: | |
path: ~/swift-${{ matrix.version }}-android-${{ matrix.arch }}-*-sdk.tar.xz | |
key: ${{ steps.version.outputs.arch-key }} | |
- name: Clone | |
uses: actions/checkout@v4 | |
with: | |
path: sdk-config | |
- name: Get cached ${{ matrix.os }} ${{ steps.version.outputs.tag }} toolchain | |
id: cache-toolchain | |
uses: actions/cache/restore@v4 | |
with: | |
path: ~/${{ steps.version.outputs.tag }}-${{ startsWith(matrix.os, 'macos') && 'osx.pkg' || 'ubuntu22.04.tar.gz' }} | |
key: swift-${{ matrix.os }}-${{ steps.version.outputs.tag }}-toolchain | |
fail-on-cache-miss: true | |
- name: Setup Swift Toolchain | |
env: | |
SWIFT_TAG: ${{ steps.version.outputs.tag }} | |
run: | | |
set -x | |
cd sdk-config | |
if ${{ startsWith(matrix.os, 'macos') }}; then | |
mkdir ${SWIFT_TAG} | |
pushd ${SWIFT_TAG} | |
xar -x -C . -f ~/${SWIFT_TAG}-osx.pkg | |
tar xz -C . -f ${SWIFT_TAG}-osx-package.pkg/Payload | |
TOOLCHAIN=${PWD}/usr | |
popd | |
elif ${{ startsWith(matrix.os, 'ubuntu') }}; then | |
tar xf ~/$SWIFT_TAG-ubuntu22.04.tar.gz | |
TOOLCHAIN=${PWD}/$SWIFT_TAG-ubuntu22.04/usr | |
fi | |
if [ ${{ matrix.version }} == 'release' ]; then | |
perl -pi -e 's%canImport\(Bionic%canImport\(Android%' $TOOLCHAIN/bin/swift-package | |
perl -pi -e 's%import Bionic%import Android%' $TOOLCHAIN/bin/swift-package | |
perl -pi -e 's%TSCBasic, would be%TSCBasic, would %' $TOOLCHAIN/bin/swift-package | |
fi | |
echo "TOOLCHAIN=${TOOLCHAIN}" >> $GITHUB_ENV | |
${TOOLCHAIN}/bin/swift --version | |
- name: Build Swift ${{ matrix.version }} Android SDK if not the latest | |
# build-script currently only works on ubuntu | |
if: ${{ (steps.cache-bundle.outputs.cache-hit != 'true') && (steps.cache-sdk.outputs.cache-hit != 'true') && startsWith(matrix.os, 'ubuntu') }} | |
env: | |
SWIFT_TAG: ${{ steps.version.outputs.tag }} | |
ANDROID_ARCH: ${{ matrix.arch }} | |
run: | | |
set -x | |
if ${{ startsWith(matrix.os, 'macos') }}; then | |
brew install ninja patchelf | |
elif ${{ startsWith(matrix.os, 'ubuntu') }}; then | |
sudo apt install ninja-build | |
fi | |
cd sdk-config | |
BUILD_SWIFT_PM=1 ${TOOLCHAIN}/bin/swift get-packages-and-swift-source.swift | |
SDK_NAME=$(ls | grep swift-${{ matrix.version }}-android-${{ matrix.arch }}) | |
SDK=`pwd`/$SDK_NAME | |
git apply swift-android.patch swift-android-foundation.patch swift-android-ci.patch swift-crypto.patch swift-system.patch | |
if [ ${{ matrix.version }} = 'trunk' ]; then | |
git apply swift-android-ci-trunk.patch swift-android-foundation-trunk.patch | |
else | |
git apply swift-android-ci-except-trunk.patch swift-android-foundation-except-trunk.patch | |
git apply -C1 swift-android-foundation-armv7-except-trunk.patch | |
if [ ${{ matrix.version }} = 'devel' ]; then | |
perl -pi -e 's%Musl%Bionic%g' swift-corelibs-foundation/Sources/Testing/Testing.swift | |
else | |
git apply swift-android-foundation-release.patch | |
fi | |
fi | |
perl -pi -e 's%r26%ndk/27%' swift/stdlib/cmake/modules/AddSwiftStdlib.cmake | |
perl -pi -e "s%/data/data/com.termux/files%$SDK%g" $SDK/usr/lib/pkgconfig/sqlite3.pc | |
perl -pi -e 's%String\(cString: getpass%\"fake\" //%' swiftpm/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift | |
./swift/utils/build-script -RA --skip-build-cmark --build-llvm=0 --android --android-ndk $ANDROID_NDK_LATEST_HOME --android-arch ${{ matrix.arch }} --android-api-level $ANDROID_API_LEVEL --build-swift-tools=0 --native-swift-tools-path=${TOOLCHAIN}/bin --native-clang-tools-path=${TOOLCHAIN}/bin --cross-compile-hosts=android-${{ matrix.arch }} --cross-compile-deps-path=$SDK --skip-local-build --build-swift-static-stdlib --xctest --skip-early-swift-driver --install-swift --install-libdispatch --install-foundation --install-xctest --install-destdir=$SDK --swift-install-components='clang-resource-dir-symlink;license;stdlib;sdk-overlay' --cross-compile-append-host-target-to-destdir=False -b -p --install-llbuild --sourcekit-lsp --skip-early-swiftsyntax | |
cp $ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/$(echo ${{ matrix.arch }} | sed "s/v7//")-linux-android*/libc++_shared.so $SDK/usr/lib | |
patchelf --set-rpath \$ORIGIN $SDK/usr/lib/swift/android/lib[dFXs]*.so | |
# Remove executables and unused toolchain headers/libraries | |
pushd $SDK_NAME/usr | |
rm -r bin lib/swift/pm lib/libsqlite3.so lib/lib{curses,ncurses}.so lib/terminfo share/{tabset,terminfo} | |
mv include/curl include/libxml2 include/spawn.h . | |
rm -r include/* | |
mv curl libxml2 spawn.h include/ | |
popd | |
tar cJf ~/$SDK_NAME.tar.xz $SDK_NAME | |
rm -rf build/ $SDK_NAME llvm-project/ | |
- name: Cache newly built ${{ matrix.version }} ${{ matrix.arch }} SDK on linux | |
if: ${{ (steps.cache-bundle.outputs.cache-hit != 'true') && (steps.cache-sdk.outputs.cache-hit != 'true') && startsWith(matrix.os, 'ubuntu') }} | |
uses: actions/cache/save@v4 | |
with: | |
path: ~/swift-${{ matrix.version }}-android-${{ matrix.arch }}-*-sdk.tar.xz | |
key: ${{ steps.version.outputs.arch-key }} | |
- name: Setup Swift ${{ matrix.version }} Android SDK | |
id: sdk-setup | |
run: | | |
set -x | |
cd sdk-config | |
ARCH_TARGET="${{ matrix.arch }}-unknown-linux-android${ANDROID_API_LEVEL}" | |
if ${{ matrix.arch == 'armv7' }}; then | |
ARCH_TARGET="armv7-unknown-linux-androideabi${ANDROID_API_LEVEL}" | |
fi | |
if ${{ steps.cache-bundle.outputs.cache-hit != 'true' }}; then | |
SDK_PATH=$(basename ~/swift-${{ matrix.version }}-android-${{ matrix.arch }}*-sdk.tar.xz .tar.xz) | |
tar xf ~/$SDK_PATH.tar.xz | |
# fix the clang symlink | |
ls -la ${SDK_PATH}/usr/lib/swift/clang | |
rm -vf ${SDK_PATH}/usr/lib/swift/clang | |
# Swift 5.10: usr/lib/clang/15.0.0 Trunk and Devel: usr/lib/clang/17 | |
${TOOLCHAIN}/bin/clang --version | |
ln -sfv ${TOOLCHAIN}/lib/clang/* ${SDK_PATH}/usr/lib/swift/clang | |
ls -l ${SDK_PATH}/usr/lib/swift/clang/lib/ | |
ARCH_JSON="$PWD/android-${{ matrix.arch }}.json" | |
NDK_PREBUILT=${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${{ startsWith(matrix.os, 'macos') && 'darwin' || 'linux' }}-x86_64 | |
if ${{ startsWith(matrix.os, 'macos') }}; then | |
cp -r ${NDK_PREBUILT}/lib/clang/*/lib/linux ${SDK_PATH}/usr/lib/swift/clang/lib | |
else | |
cp -r ${NDK_PREBUILT}/lib/clang/*/lib/linux/* ${SDK_PATH}/usr/lib/swift/clang/lib/linux | |
fi | |
cat > ${ARCH_JSON} << EOF | |
{ | |
"schemaVersion": "4.0", | |
"targetTriples": { | |
"${ARCH_TARGET}": { | |
"sdkRootPath": "${NDK_PREBUILT}/sysroot", | |
"swiftResourcesPath": "${SDK_PATH}/usr/lib/swift", | |
} | |
} | |
} | |
EOF | |
cat ${ARCH_JSON} | |
FLAGS="--destination ${ARCH_JSON}" | |
if ${{ matrix.version == 'trunk' }}; then | |
ln -sf $PWD/$SDK_PATH/usr/lib/swift $NDK_PREBUILT/sysroot/usr/lib/swift | |
FLAGS="-Xswiftc -use-ld=lld --destination ${ARCH_JSON}" | |
fi | |
else | |
${TOOLCHAIN}/bin/swift sdk install ~/${{ steps.version.outputs.tag }}-android-*.artifactbundle.tar.gz | |
${TOOLCHAIN}/bin/swift sdk configure --show-configuration ${{ steps.version.outputs.tag }}-android-${ANDROID_API_LEVEL}-${BUNDLE_VERSION} $ARCH_TARGET | |
FLAGS="--swift-sdk ${ARCH_TARGET}" | |
fi | |
echo "SWIFTPM_FLAGS=${FLAGS}" >> $GITHUB_ENV | |
- name: Get Swift Argument Parser package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-argument-parser | |
path: swift-argument-parser | |
- name: Build Swift Argument Parser package | |
run: | | |
cd swift-argument-parser | |
rm Examples/count-lines/CountLines.swift Tools/changelog-authors/*.swift | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift crypto package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-crypto | |
path: swift-crypto | |
- name: Build Swift crypto package | |
run: | | |
git apply sdk-config/swift-crypto.patch | |
cd swift-crypto | |
perl -pi -e 's%\\\\(testsDirectory)/.*Vectors%/data/local/tmp/pack/crypto-vectors%' Tests/{Crypto,_CryptoExtras}Tests/Utils/{RFCVector,Wycheproof}.swift | |
perl -pi -e 's%#file%"/data/local/tmp/pack/crypto-vectors"%;s%../_CryptoExtrasVectors/%%' Tests/_CryptoExtrasTests/TestRSABlindSigning.swift | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift NIO package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-nio | |
path: swift-nio | |
- name: Build Swift NIO package | |
run: | | |
cd swift-nio | |
git apply ../sdk-config/swift-nio-disable-ecn-tests.patch ../sdk-config/swift-nio-filesystem.patch ../sdk-config/swift-nio-ndk27.patch | |
${TOOLCHAIN}/bin/swift package update | |
cd .build/checkouts/ | |
patch -p1 < ../../../sdk-config/swift-system.patch | |
cd ../.. | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift Numerics package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-numerics | |
path: swift-numerics | |
- name: Build Swift Numerics package | |
run: | | |
cd swift-numerics | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift System package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-system | |
path: swift-system | |
- name: Build Swift System package | |
run: | | |
git apply sdk-config/swift-system-tests.patch | |
cd swift-system | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift Collections package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-collections | |
path: swift-collections | |
- name: Build Swift Collections package | |
run: | | |
cd swift-collections | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift Atomics package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-atomics | |
path: swift-atomics | |
ref: 1.1.0 | |
- name: Get Swift NIO SSH package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-nio-ssh | |
path: sns | |
- name: Build Swift NIO SSH package | |
run: | | |
cd sns | |
perl -pi -e 's%url: .*swift-([a-z]*)\.git.*$%path: \"../swift-\1\"),%g' Package.swift | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift NIO SSL package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-nio-ssl | |
path: snl | |
- name: Build Swift NIO SSL package | |
run: | | |
cd snl | |
git apply ../sdk-config/swift-nio-ssl-test.patch | |
SWIFTCI_USE_LOCAL_DEPS=1 ${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Yams package | |
uses: actions/checkout@v4 | |
with: | |
repository: jpsim/Yams | |
path: yams | |
- name: Build Yams package | |
run: | | |
cd yams | |
perl -pi -e 's% fixturesDirectory + \"/SourceKitten#289% \"/data/local/tmp/pack%' Tests/YamsTests/PerformanceTests.swift | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift NIO HTTP/2 package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-nio-http2 | |
path: snh | |
- name: Build Swift NIO HTTP/2 package | |
if: ${{ matrix.arch != 'armv7' }} | |
run: | | |
cd snh | |
git apply ../sdk-config/swift-nio-http2-test.patch | |
perl -pi -e 's%url: .*swift-([a-z]*)\.git.*$%path: \"../swift-\1\"),%g' Package.swift | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get Swift Algorithms package | |
uses: actions/checkout@v4 | |
with: | |
repository: apple/swift-algorithms | |
path: sa | |
- name: Build Swift Algorithms package | |
run: | | |
cd sa | |
perl -pi -e 's%url: .*$%path: \"../swift-numerics\"),%' Package.swift | |
${TOOLCHAIN}/bin/swift build --build-tests ${SWIFTPM_FLAGS} | |
- name: Get cached Termux debug app for NIO tests | |
if: ${{ matrix.arch == 'x86_64' }} | |
id: cache-termux | |
uses: actions/cache@v4 | |
with: | |
path: ~/termux-debug.apk | |
key: termux-app | |
- name: Get Termux debug app if not cached | |
if: ${{ (matrix.arch == 'x86_64') && (steps.cache-termux.outputs.cache-hit != 'true') }} | |
run: wget -O ~/termux-debug.apk https://github.com/termux/termux-app/releases/download/v0.118.0/termux-app_v0.118.0+github-debug_x86_64.apk | |
- name: Prepare Android emulator test package | |
if: ${{ matrix.arch == 'x86_64' }} | |
run: | | |
set -x | |
# create the test runner script | |
cat > ~/test-toolchain.sh << EOF | |
adb install ~/termux-debug.apk | |
adb push pack /data/local/tmp | |
adb shell "run-as com.termux mkdir /data/data/com.termux/pack" | |
adb shell "run-as com.termux cp /data/local/tmp/pack/{lib*.so,swift-nioPackageTests.xctest,FileHandleTests.swift} /data/data/com.termux/pack" | |
adb shell "run-as com.termux cp -r /data/local/tmp/pack/Test\ Data /data/data/com.termux/pack" | |
adb shell "run-as com.termux ln -s README.md /data/data/com.termux/pack/Test\ Data/README.md.symlink" | |
adb shell "run-as com.termux ln -s Foo /data/data/com.termux/pack/Test\ Data/Foo.symlink" | |
adb shell "run-as com.termux sh -c 'TMPDIR=/data/data/com.termux /data/data/com.termux/pack/swift-nioPackageTests.xctest'" | |
adb shell "TMPDIR=/data/local/tmp /data/local/tmp/pack/swift-systemPackageTests.xctest" | |
EOF | |
mkdir pack | |
TARGET="x86_64-unknown-linux-android$ANDROID_API_LEVEL" | |
cp swift-argument-parser/.build/$TARGET/debug/{generate-manual,math,repeat,roll,swift-argument-parserPackageTests.xctest} pack | |
echo 'adb shell /data/local/tmp/pack/swift-argument-parserPackageTests.xctest' >> ~/test-toolchain.sh | |
wget -q https://raw.githubusercontent.com/termux/termux-elf-cleaner/v2.1.1/elf-cleaner.cpp | |
wget -q https://raw.githubusercontent.com/termux/termux-elf-cleaner/v2.1.1/elf.h | |
wget -q https://raw.githubusercontent.com/termux/termux-elf-cleaner/v2.1.1/arghandling.h | |
wget -q https://raw.githubusercontent.com/termux/termux-elf-cleaner/v2.1.1/arghandling.c | |
clang -c arghandling.c | |
clang -o elf-cleaner arghandling.o elf-cleaner.cpp -DCOPYRIGHT=\"foo\" -DPACKAGE_NAME=\"termux-elf-cleaner\" -DPACKAGE_VERSION=\"2.2.1\" | |
./elf-cleaner --api-level $ANDROID_API_LEVEL pack/{generate-manual,math,repeat,roll} || true | |
cp swift-crypto/.build/$TARGET/debug/swift-cryptoPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-cryptoPackageTests.xctest' >> ~/test-toolchain.sh | |
cp swift-nio/.build/$TARGET/debug/swift-nioPackageTests.xctest pack | |
cp swift-numerics/.build/$TARGET/debug/swift-numericsPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-numericsPackageTests.xctest' >> ~/test-toolchain.sh | |
cp swift-system/.build/$TARGET/debug/swift-systemPackageTests.xctest pack | |
cp swift-collections/.build/$TARGET/debug/swift-collectionsPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-collectionsPackageTests.xctest' >> ~/test-toolchain.sh | |
cp sns/.build/$TARGET/debug/swift-nio-sshPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-nio-sshPackageTests.xctest' >> ~/test-toolchain.sh | |
cp snl/.build/$TARGET/debug/swift-nio-sslPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-nio-sslPackageTests.xctest' >> ~/test-toolchain.sh | |
cp snh/.build/$TARGET/debug/swift-nio-http2PackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-nio-http2PackageTests.xctest' >> ~/test-toolchain.sh | |
cp yams/.build/$TARGET/debug/YamsPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/YamsPackageTests.xctest' >> ~/test-toolchain.sh | |
cp sa/.build/$TARGET/debug/swift-algorithmsPackageTests.xctest pack | |
echo 'adb shell /data/local/tmp/pack/swift-algorithmsPackageTests.xctest' >> ~/test-toolchain.sh | |
mkdir pack/crypto-vectors pack/swift-crypto_CryptoTests.resources | |
cp swift-crypto/Tests/Test\ Vectors/* swift-crypto/Tests/_CryptoExtrasVectors/* pack/crypto-vectors | |
cp swift-crypto/Tests/CryptoTests/HPKE/hpke-test-vectors.json pack/swift-crypto_CryptoTests.resources | |
rm swift-nio/Tests/NIOFileSystemIntegrationTests/Test\ Data/*symlink | |
cp -r swift-nio/Tests/NIOFileSystemIntegrationTests/Test\ Data/ swift-nio/Tests/NIOFileSystemIntegrationTests/FileHandleTests.swift pack | |
cp yams/Tests/YamsTests/Fixtures/SourceKitten#289/debug.yaml pack | |
if ${{ steps.cache-bundle.outputs.cache-hit != 'true' }}; then | |
cp sdk-config/swift-*-android-x86_64-*${ANDROID_API_LEVEL}-sdk/usr/lib/lib*so pack | |
cp sdk-config/swift-*-android-x86_64-*${ANDROID_API_LEVEL}-sdk/usr/lib/swift/android/lib*so pack | |
else | |
cp ~/.${{ startsWith(matrix.os, 'ubuntu') && 'config/' || '' }}swiftpm/swift-sdks/${{ steps.version.outputs.tag }}-android-${ANDROID_API_LEVEL}-*.artifactbundle/swift*sdk/android*sysroot/usr/lib/$(echo ${{ matrix.arch }} | sed "s/v7//")-linux-android*/${ANDROID_API_LEVEL}/lib*so pack | |
rm pack/lib{c,dl,log,m}.so | |
fi | |
# need to free up some space or else the emulator fails to launch: | |
# ERROR | Not enough space to create userdata partition. Available: 6086.191406 MB at /home/runner/.android/avd/../avd/test.avd, need 7372.800000 MB. | |
rm -rf sdk-config/${{ steps.version.outputs.tag }}-ubuntu22.04/usr/{bin,lib/*swift*} */.build | |
chmod +x ~/test-toolchain.sh | |
echo "TEST SCRIPT:" | |
cat ~/test-toolchain.sh | |
if ${{ startsWith(matrix.os, 'ubuntu') }}; then | |
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 | |
fi | |
- name: Run tests on Android x86_64 emulator | |
if: ${{ matrix.arch == 'x86_64' }} | |
uses: reactivecircus/android-emulator-runner@v2 | |
with: | |
api-level: 29 | |
arch: x86_64 | |
script: ~/test-toolchain.sh | |
- name: Get cached aarch64 SDK on x86_64 runner | |
if: ${{ steps.cache-bundle.outputs.cache-hit != 'true' && startsWith(matrix.os, 'ubuntu') && matrix.arch == 'x86_64' }} | |
uses: actions/cache/restore@v4 | |
with: | |
path: ~/swift-${{ matrix.version }}-android-aarch64-*-sdk.tar.xz | |
key: ${{ steps.version.outputs.aarch64-key }} | |
fail-on-cache-miss: true | |
- name: Get cached arm SDK on x86_64 runner | |
if: ${{ steps.cache-bundle.outputs.cache-hit != 'true' && startsWith(matrix.os, 'ubuntu') && matrix.arch == 'x86_64' }} | |
uses: actions/cache/restore@v4 | |
with: | |
path: ~/swift-${{ matrix.version }}-android-armv7-*-sdk.tar.xz | |
key: ${{ steps.version.outputs.arm-key }} | |
fail-on-cache-miss: true | |
- name: Get previously cached Android NDK sysroot and runtime libraries | |
uses: actions/cache/restore@v4 | |
with: | |
path: ~/android-sysroot.tar.xz | |
key: android-ndk-${{ env.NDK_VERSION }} | |
fail-on-cache-miss: true | |
- name: Assemble SDK bundle | |
if: ${{ steps.cache-bundle.outputs.cache-hit != 'true' && startsWith(matrix.os, 'ubuntu') && matrix.arch == 'x86_64' }} | |
run: | | |
set -x | |
ls -lah ~/swift-*-sdk.tar.xz | |
VERSION="$(echo ${{ steps.version.outputs.tag }} | cut -f1,2 -d-)-${{ matrix.version }}" | |
# e.g. swift-6.0.1-release-android-24-sdk | |
SDK_DIR=$VERSION-android-${ANDROID_API_LEVEL}-sdk | |
ROOT=android-${NDK_VERSION}-sysroot | |
SYSROOT=$SDK_DIR/$ROOT | |
mkdir ${SDK_DIR} | |
tar xf ~/android-sysroot.tar.xz | |
mv sysroot $SYSROOT | |
for SDK_PATH in ~/swift-*-sdk.tar.xz; do | |
MERGEDIR=$(basename $SDK_PATH .tar.xz) | |
tar xf ${SDK_PATH} | |
tree ${MERGEDIR} | |
pushd ${MERGEDIR}/usr | |
ARCH=$(ls lib/swift_static/android/*/swiftrt.o | cut -f 4 -d '/') | |
TRIPLE="${ARCH}-linux-android" | |
if [[ $ARCH == 'armv7' ]]; then | |
TRIPLE="arm-linux-androideabi" | |
fi | |
echo "Creating ${TRIPLE} from ${MERGEDIR}…" | |
mkdir -p lib/${TRIPLE}/${ANDROID_API_LEVEL} | |
mv lib/swift_static lib/swift_static-${ARCH} | |
mv lib/libandroid-spawn.a lib/swift_static-${ARCH}/android | |
patchelf --set-rpath \$ORIGIN:\$ORIGIN/termux-zlib lib/lib{curl,ssh2,xml2}.so | |
cp ../../$SYSROOT/usr/lib/$TRIPLE/libc++_shared.so lib | |
mv lib/lib[a-x]*.so lib/swift/android/lib*.so lib/${TRIPLE}/${ANDROID_API_LEVEL} | |
mv lib/pkgconfig lib/${TRIPLE} | |
mkdir lib/${TRIPLE}/${ANDROID_API_LEVEL}/termux-zlib | |
mv lib/libz.so lib/${TRIPLE}/${ANDROID_API_LEVEL}/termux-zlib | |
rm lib/swift{,_static-$ARCH}/clang | |
popd | |
# copy all the processed SDK files into the Android sysroot | |
rsync -ar ${MERGEDIR}/ $SYSROOT | |
done | |
# Copy necessary headers and libraries from the toolchain and NDK clang resource directories | |
mkdir -p $SYSROOT/usr/lib/swift/clang/lib | |
cp -r $TOOLCHAIN/lib/clang/*/include $SYSROOT/usr/lib/swift/clang | |
mv $SYSROOT/linux $SYSROOT/usr/lib/swift/clang/lib | |
ln -s ../swift/clang $SYSROOT/usr/lib/swift_static-aarch64/clang | |
ln -s ../swift/clang $SYSROOT/usr/lib/swift_static-armv7/clang | |
ln -s ../swift/clang $SYSROOT/usr/lib/swift_static-x86_64/clang | |
BUNDLE=${{ steps.version.outputs.tag }}-android-${ANDROID_API_LEVEL}-${BUNDLE_VERSION} | |
BUNDLE_DIR=$BUNDLE.artifactbundle | |
mkdir ${BUNDLE_DIR} | |
mv ${SDK_DIR} ${BUNDLE_DIR} | |
cat > $BUNDLE_DIR/info.json << EOF | |
{ | |
"schemaVersion": "1.0", | |
"artifacts": { | |
"${BUNDLE}": { | |
"variants": [ { "path": "${SDK_DIR}" } ], | |
"version": "${BUNDLE_VERSION}", | |
"type": "swiftSDK" | |
} | |
} | |
} | |
EOF | |
cat > $BUNDLE_DIR/$SDK_DIR/swift-sdk.json << EOF | |
{ | |
"schemaVersion": "4.0", | |
"targetTriples": { | |
"aarch64-unknown-linux-android24": { | |
"sdkRootPath": "${ROOT}", | |
"swiftResourcesPath": "${ROOT}/usr/lib/swift", | |
"swiftStaticResourcesPath": "${ROOT}/usr/lib/swift_static-aarch64" | |
}, | |
"x86_64-unknown-linux-android24": { | |
"sdkRootPath": "${ROOT}", | |
"swiftResourcesPath": "${ROOT}/usr/lib/swift", | |
"swiftStaticResourcesPath": "${ROOT}/usr/lib/swift_static-x86_64" | |
}, | |
"armv7-unknown-linux-androideabi24": { | |
"sdkRootPath": "${ROOT}", | |
"swiftResourcesPath": "${ROOT}/usr/lib/swift", | |
"swiftStaticResourcesPath": "${ROOT}/usr/lib/swift_static-armv7" | |
} | |
} | |
} | |
EOF | |
cat > $BUNDLE_DIR/$SYSROOT/SDKSettings.json << EOF | |
{ | |
"DisplayName": "Android NDK ${NDK_VERSION} sysroot with ${VERSION} runtime libraries for API 24", | |
"Version": "27.1.12297006", | |
"VersionMap": {}, | |
"CanonicalName": "${VERSION}-android24" | |
} | |
EOF | |
# output visualization of the SDK bundle file tree | |
tree $BUNDLE_DIR | |
du -skh "${BUNDLE_DIR}" | |
tar czf ~/${BUNDLE_DIR}.tar.gz "${BUNDLE_DIR}" | |
du -skh ~/${BUNDLE_DIR}.tar.gz | |
shasum -a 256 ~/${BUNDLE_DIR}.tar.gz | |
- name: Upload SDK bundle | |
if: ${{ startsWith(matrix.os, 'ubuntu') && matrix.arch == 'x86_64' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.version.outputs.tag }}-android-${{ env.ANDROID_API_LEVEL }}-${{ env.BUNDLE_VERSION }}.artifactbundle.tar.gz | |
path: ~/${{ steps.version.outputs.tag }}-android-${{ env.ANDROID_API_LEVEL }}-${{ env.BUNDLE_VERSION }}.artifactbundle.tar.gz | |
compression-level: 0 |