diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 1ed0a799..ad586a0d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -21,3 +21,172 @@ jobs: name: docker-logs path: | *.log + + android-build: + name: Android ${{ matrix.build-type }} ${{ matrix.swift-version }} ${{ matrix.arch }} ${{ matrix.runner }} (compiler=${{ matrix.build-compiler }}) + strategy: + fail-fast: false + matrix: + include: + - swift-version: 'swift-6.2-branch' + build-type: 'docker' + build-compiler: '1' + runner: 'self-hosted' + - swift-version: 'development' + build-type: 'docker' + build-compiler: '1' + runner: 'self-hosted' + - swift-version: 'swift-6.2-branch' + build-type: 'docker' + build-compiler: '0' + runner: 'ubuntu-24.04' + - swift-version: 'development' + build-type: 'docker' + build-compiler: '0' + runner: 'ubuntu-24.04' + runs-on: ${{ matrix.runner }} + # 15 hour timeout + timeout-minutes: 900 + steps: + - name: Free Disk Space + if: ${{ matrix.runner != 'self-hosted' }} + run: | + df -h + # brings available space from 25G to 32G + # otherwise we sometimes run out of space during the build + sudo rm -rf /usr/share/miniconda /usr/share/az* /usr/share/glade* /usr/local/share/chromium /usr/local/share/powershell /usr/share/dotnet /opt/ghc /opt/hostedtoolcache /usr/local/graalvm/ /usr/local/.ghcup/ /usr/local/lib/node_modules /usr/local/share/boost + sudo docker image prune --all --force + sudo docker builder prune -a + df -h + - name: Setup + id: config + run: | + # these variabes are used by build-docker and build-local + # to determine which Swift version to build for + echo "BUILD_SCHEME=${{ matrix.swift-version }}" >> $GITHUB_ENV + # pass the build-compiler matrix through to the build script + echo "BUILD_COMPILER=${{ matrix.build-compiler }}" >> $GITHUB_ENV + echo "TARGET_ARCHS=${{ matrix.arch }}" >> $GITHUB_ENV + echo "WORKDIR=${{ runner.temp }}/swift-android-sdk" >> $GITHUB_ENV + - name: Checkout repository + uses: actions/checkout@v4 + - name: Build Android SDK (Local) + if: ${{ matrix.build-type == 'local' }} + working-directory: swift-ci/sdks/android + run: | + sudo apt install -q patchelf build-essential cmake ninja-build python3 golang git gnupg2 libcurl4-openssl-dev libedit-dev libicu-dev libncurses5-dev libpython3-dev libsqlite3-dev libxml2-dev rsync uuid-dev uuid-runtime tzdata curl unzip + ./build-local ${BUILD_SCHEME} ${WORKDIR} + - name: Build Android SDK (Docker) + if: ${{ matrix.build-type == 'docker' }} + working-directory: swift-ci/sdks/android + run: | + ./build-docker ${BUILD_SCHEME} ${WORKDIR} + - name: Install Host Toolchain + if: ${{ matrix.build-type == 'docker' }} + working-directory: swift-ci/sdks/android + run: | + # when building in a Docker container, we don't have a local host toolchain, + # but we need one in order to run the SDK validation tests, so we install it now + HOST_OS=ubuntu$(lsb_release -sr) + source ./scripts/toolchain-vars.sh + mkdir -p ${WORKDIR}/host-toolchain + ./scripts/install-swift.sh ${WORKDIR}/host-toolchain/$SWIFT_BASE/usr + ls ${WORKDIR}/host-toolchain + ${WORKDIR}/host-toolchain/*/usr/bin/swift --version + - name: Get artifact info + id: info + shell: bash + run: | + set -ex + SWIFT_ROOT=$(dirname ${WORKDIR}/host-toolchain/*/usr) + echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT + echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT + + ARTIFACT_PATH=$(realpath ${WORKDIR}/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})" + # depending on whether we are building locally or in a container, add a maker to the name + if [[ "${{ matrix.build-type }}" == 'local' ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-local" + fi + if [[ "${{ matrix.build-compiler }}" == '1' ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-hostbuild" + fi + # 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 + - 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 + if: ${{ matrix.runner != 'self-hosted' }} + run: | + # need to free up some space or else when installing we get: No space left on device + df -h + rm -rf ${WORKDIR}/{build,source} + sudo docker image prune --all --force + sudo docker builder prune -a + df -h + - name: Install artifactbundle + if: ${{ matrix.runner != 'self-hosted' }} + 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/swiftlang/swift-driver/pull/1879 + echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV + + - name: Create Demo Project + if: ${{ matrix.runner != 'self-hosted' }} + 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@main + if: ${{ matrix.runner != 'self-hosted' }} + 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 + if: ${{ matrix.runner != 'self-hosted' }} + uses: actions/checkout@v4 + with: + repository: apple/swift-algorithms + path: swift-algorithms + - name: Test swift-algorithms + if: ${{ matrix.runner != 'self-hosted' }} + uses: skiptools/swift-android-action@main + with: + package-path: swift-algorithms + installed-sdk: ${{ steps.info.outputs.sdk-id }} + installed-swift: ${{ steps.info.outputs.swift-root }} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a01ee289 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.*.swp diff --git a/swift-ci/sdks/android/Dockerfile b/swift-ci/sdks/android/Dockerfile new file mode 100644 index 00000000..8708586a --- /dev/null +++ b/swift-ci/sdks/android/Dockerfile @@ -0,0 +1,87 @@ +# ===----------------------------------------------------------------------=== +# +# Swift Android SDK: Docker-based build +# +# ===----------------------------------------------------------------------=== + +FROM ubuntu:24.04 + +# Architecture to build on (empty means x86-64) +ARG OS_ARCH_SUFFIX= + +# the Swift toolchain URL to download +ARG SWIFT_TOOLCHAIN_URL= + +# ............................................................................ + +# Install development tools +RUN apt-get -q update \ + && DEBIAN_FRONTEND=noninteractive apt-get -q install -y \ + build-essential \ + clang-19 \ + cmake \ + ninja-build \ + python3 \ + golang \ + git \ + gnupg2 \ + libcurl4-openssl-dev \ + libedit-dev \ + libicu-dev \ + libncurses5-dev \ + libpython3-dev \ + libsqlite3-dev \ + libxml2-dev \ + rsync \ + uuid-dev \ + uuid-runtime \ + tzdata \ + curl \ + unzip \ + && rm -rf /var/lib/apt-lists/* + +# Install Swift +ARG SWIFT_SIGNING_KEY=E813C892820A6FA13755B268F167DF1ACF9CE069 +ARG SWIFT_PLATFORM=ubuntu +ARG OS_MAJOR_VER=24 +ARG OS_MINOR_VER=04 + +ENV SWIFT_SIGNING_KEY=$SWIFT_SIGNING_KEY \ + SWIFT_PLATFORM=$SWIFT_PLATFORM \ + OS_MAJOR_VER=$OS_MAJOR_VER \ + OS_MINOR_VER=$OS_MINOR_VER \ + OS_VER=$SWIFT_PLATFORM$OS_MAJOR_VER.$OS_MINOR_VER + +COPY scripts/install-swift.sh /scripts/install-swift.sh +RUN chmod ugo+x /scripts/install-swift.sh +RUN /scripts/install-swift.sh /usr/local/swift +ENV PATH="/usr/lib/llvm-19/bin:/usr/local/swift/bin:${PATH}" + +ARG ANDROID_NDK_VERSION= + +ENV ANDROID_NDK_VERSION=$ANDROID_NDK_VERSION + +COPY scripts/install-ndk.sh /scripts/install-ndk.sh +RUN chmod ugo+x /scripts/install-ndk.sh +RUN /scripts/install-ndk.sh +ENV ANDROID_NDK_HOME="/usr/local/ndk/${ANDROID_NDK_VERSION}" + +ENV SWIFT_VERSION=$SWIFT_VERSION \ + LIBXML2_VERSION=$LIBXML2_VERSION \ + CURL_VERSION=$CURL_VERSION \ + BORINGSSL_VERSION=$BORINGSSL_VERSION \ + ICU_VERSION=$ICU_VERSION \ + ZLIB_VERSION=$ZLIB_VERSION + +ENV SWIFT_BUILD_DOCKER="1" + +COPY scripts /scripts +RUN chmod ugo+x /scripts/* + +# Create a user +RUN groupadd -g 998 build-user && \ + useradd -m -r -u 998 -g build-user build-user + +USER build-user + +WORKDIR /home/build-user diff --git a/swift-ci/sdks/android/README.md b/swift-ci/sdks/android/README.md new file mode 100644 index 00000000..1e57edd1 --- /dev/null +++ b/swift-ci/sdks/android/README.md @@ -0,0 +1,85 @@ +# Dockerfile-based build for Swift Android SDK + +This is a Dockerfile-based build set-up for the Swift Android SDK. + +The top-level `./build-docker` script will create a +Docker container and install a host toolchain and the +Android NDK, and then invoke `scripts/fetch-source.sh` which will +fetch tagged sources for libxml2, curl, boringssl, and swift. + +It can be run with: + +``` +$ ./build-docker +``` + +for example: + +``` +$ ./build-docker release /tmp/android-sdk +``` + +This will create an Ubuntu 24.04 container with the necessary dependencies +to build the Android SDK, including a Swift host toolchain and the +Android NDK that will be used for cross-compilation. + +The `version` argument can be one of the following values: + +| version | Swift version example | +| --- | --- | +| `release` | swift-6.1-RELEASE | +| `swift-6.2-branch` | swift-6.2-DEVELOPMENT-SNAPSHOT-yyyy-mm-dd | +| `development` | swift-DEVELOPMENT-SNAPSHOT-yyyy-mm-dd | + +> [!WARNING] +> The workdir argument must not be located in a git repository (e.g., it cannot be the +> current directory) + +## Running + +The top-level `./build-docker` 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 and then combines the SDKs into a single +artifactbundle with targetTriples for each of the supported +architectures (`aarch64`, `x86_64`, `aarmv7`) +and Android API levels (28-35). + +## Specifying Architectures + +By default all the supported Android architectures +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-docker release /tmp/android-sdk +``` + +## 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 GitHub 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 using the +freshly-created SDK bundle. + +## Building locally + +Instead of building within a Docker container, the script can also +perform the build locally on an Ubuntu 24.04 machine with all the +build prerequisites already installed. This will generate +the same artifacts in approximately half the time, and +may be suitable to an already containerized envrionment (such as +a GitHub runner). + diff --git a/swift-ci/sdks/android/build-docker b/swift-ci/sdks/android/build-docker new file mode 100755 index 00000000..e8f1f3f1 --- /dev/null +++ b/swift-ci/sdks/android/build-docker @@ -0,0 +1,68 @@ +#!/bin/bash -e +# +# ===----------------------------------------------------------------------=== +# +# Swift Android SDK: Docker Container Build Script +# +# ===----------------------------------------------------------------------=== + +# default architectures to build for +TARGET_ARCHS=${TARGET_ARCHS:-aarch64,x86_64,armv7} + +ANDROID_NDK_VERSION=android-ndk-r27c +ANDROID_API=28 + +export BUILD_SCHEME=${1} +# note that WORKDIR must not be under the current checkout or the patches will fail to apply +WORKDIR=${2} +if [[ "${WORKDIR}" == '' ]]; then + echo "Usage: $(basename $0) " + exit 1 +fi +mkdir -p ${WORKDIR} +WORKDIR=$(realpath ${WORKDIR}) + +HOST_OS=ubuntu24.04 +source ./scripts/toolchain-vars.sh + +# Check-out and patch the sources +./scripts/fetch-source.sh --source-dir ${WORKDIR}/source --swift-tag ${SWIFT_TAG} +./patches/apply-patches.sh ${WORKDIR}/source/swift-project + +mkdir -p ${WORKDIR}/products +chmod ugo+rwx ${WORKDIR}/products + +if [[ "$DOCKER" == "" ]]; then + DOCKER=docker +fi + +case $(arch) in + arm64|aarch64) + OS_ARCH_SUFFIX=-aarch64 + ;; + amd64|x86_64) + OS_ARCH_SUFFIX= + ;; + *) + echo "Unknown architecture $(arch)" + exit 1 + ;; +esac + +CONTAINER_NAME="swift-android" + +# Build the Docker image +$DOCKER build --build-arg OS_ARCH_SUFFIX=$OS_ARCH_SUFFIX --build-arg SWIFT_TOOLCHAIN_URL=$SWIFT_TOOLCHAIN_URL --build-arg ANDROID_NDK_VERSION=$ANDROID_NDK_VERSION -t ${CONTAINER_NAME} . + +$DOCKER run -i --rm \ + -v ${WORKDIR}/source:/source \ + -v ${WORKDIR}/products:/products:rw \ + ${CONTAINER_NAME} \ + /scripts/build.sh \ + --source-dir "/source" \ + --products-dir "/products" \ + --host-toolchain "/usr/local/swift" \ + --build-compiler "${BUILD_COMPILER}" \ + --android-api "${ANDROID_API}" \ + --ndk-home "/usr/local/ndk/${ANDROID_NDK_VERSION}" \ + --archs "${TARGET_ARCHS}" diff --git a/swift-ci/sdks/android/build-local b/swift-ci/sdks/android/build-local new file mode 100755 index 00000000..31eaf1e3 --- /dev/null +++ b/swift-ci/sdks/android/build-local @@ -0,0 +1,67 @@ +#!/bin/bash -e +# +# ===----------------------------------------------------------------------=== +# +# Swift Android SDK: Local (non-Docker-containerized) Build Script +# +# ===----------------------------------------------------------------------=== + +# default architectures to build for +TARGET_ARCHS=${TARGET_ARCHS:-aarch64,x86_64,armv7} + +ANDROID_NDK_VERSION=android-ndk-r27c +ANDROID_API=28 + +export BUILD_SCHEME=${1} +# note that WORKDIR must not be under the current checkout or the patches will fail to apply +WORKDIR=${2} +if [[ "${WORKDIR}" == '' ]]; then + echo "Usage: $(basename $0) " + exit 1 +fi +mkdir -p ${WORKDIR} +WORKDIR=$(realpath ${WORKDIR}) + +HOST_OS=ubuntu$(lsb_release -sr) +source ./scripts/toolchain-vars.sh + +if [[ "${BUILD_COMPILER}" != "1" ]]; then + SWIFT_ROOT=${WORKDIR}/host-toolchain + HOST_TOOLCHAIN=$SWIFT_ROOT/$SWIFT_BASE/usr + if [[ ! -d "$HOST_TOOLCHAIN" ]]; then + ./scripts/install-swift.sh ${HOST_TOOLCHAIN} + fi + + $HOST_TOOLCHAIN/bin/swift --version + + # ensure the correct Swift is first in the PATH + export PATH=$HOST_TOOLCHAIN/bin:$PATH +fi + +export ANDROID_NDK_HOME=${WORKDIR}/ndk/${ANDROID_NDK_VERSION} + +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 + + +# Check-out and patch the sources +./scripts/fetch-source.sh --source-dir ${WORKDIR}/source --swift-tag ${SWIFT_TAG} +./patches/apply-patches.sh ${WORKDIR}/source/swift-project + +mkdir -p ${WORKDIR}/products + +./scripts/build.sh \ + --source-dir "${WORKDIR}/source" \ + --products-dir "${WORKDIR}/products" \ + --build-dir "${WORKDIR}/build" \ + --build-compiler "${BUILD_COMPILER}" \ + --host-toolchain "${HOST_TOOLCHAIN}" \ + --android-api "${ANDROID_API}" \ + --ndk-home "${ANDROID_NDK_HOME}" \ + --archs "${TARGET_ARCHS}" diff --git a/swift-ci/sdks/android/patches/apply-patches.sh b/swift-ci/sdks/android/patches/apply-patches.sh new file mode 100755 index 00000000..36f234f1 --- /dev/null +++ b/swift-ci/sdks/android/patches/apply-patches.sh @@ -0,0 +1,23 @@ +#!/bin/bash -ex + +patches_dir=$(dirname $(realpath -- "${BASH_SOURCE[0]}")) +cd ${1} + +case "${BUILD_SCHEME}" in + swift-*-branch) + git apply -v -C1 ${patches_dir}/swift-android.patch + git apply -v -C1 ${patches_dir}/swift-android-testing-except-release.patch + ;; + development) + git apply -v -C1 ${patches_dir}/swift-android.patch + git apply -v -C1 ${patches_dir}/swift-android-trunk-libdispatch.patch + git apply -v -C1 ${patches_dir}/swift-android-testing-except-release.patch + ;; + *) + echo "$0: invalid BUILD_SCHEME=${BUILD_SCHEME}" + exit 1 + ;; +esac + +# 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 diff --git a/swift-ci/sdks/android/patches/swift-android-testing-except-release.patch b/swift-ci/sdks/android/patches/swift-android-testing-except-release.patch new file mode 100644 index 00000000..4d6fea0d --- /dev/null +++ b/swift-ci/sdks/android/patches/swift-android-testing-except-release.patch @@ -0,0 +1,156 @@ +diff --git a/swift/test/ClangImporter/pcm-emit-direct-cc1-mode.swift b/swift/test/ClangImporter/pcm-emit-direct-cc1-mode.swift +index f5048b9e3d5..c227ef7b77d 100644 +--- a/swift/test/ClangImporter/pcm-emit-direct-cc1-mode.swift ++++ b/swift/test/ClangImporter/pcm-emit-direct-cc1-mode.swift +@@ -9,7 +9,7 @@ + // CHECK-DUMP: Module map file: {{.*[/\\]}}Inputs{{/|\\}}custom-modules{{/|\\}}module.modulemap + + // Verify that the clang command-line used is cc1 +-// RUN: %FileCheck -check-prefix CHECK-CLANG -DTRIPLE=%target-triple %s < %t.diags.txt ++// RUN: %FileCheck -check-prefix CHECK-CLANG -DTRIPLE=%module-target-triple %s < %t.diags.txt + // CHECK-CLANG: clang importer cc1 args + // CHECK-CLANG-SAME: '-o' '{{.*[/\\]}}script.pcm' '-fsyntax-only' '-x' 'objective-c' '{{.*[/\\]}}module.modulemap' '-triple' '[[TRIPLE]]' + // CHECK-CLANG-SAME: '-fmodules' +diff --git a/swift/test/IRGen/abitypes_arm.swift b/swift/test/IRGen/abitypes_arm.swift +index 9428294483d..52bd8b10145 100644 +--- a/swift/test/IRGen/abitypes_arm.swift ++++ b/swift/test/IRGen/abitypes_arm.swift +@@ -11,6 +11,6 @@ class Foo { + } + } + +-// armv7: define internal void @makeOne(ptr noalias sret({{.*}}) align 4 %agg.result, float{{( noundef)?}} %f, float{{( noundef)?}} %s) ++// armv7: define internal void @makeOne(ptr{{( dead_on_unwind)?}} noalias{{( writable)?}} sret({{.*}}) align 4 %agg.result, float{{( noundef)?}} %f, float{{( noundef)?}} %s) + // armv7s: define internal void @makeOne(ptr noalias sret({{.*}}) align 4 %agg.result, float %f, float %s) + // armv7k: define internal %struct.One @makeOne(float {{.*}}%f, float {{.*}}%s) +diff --git a/swift/test/Interop/Cxx/class/constructors-copy-module-interface.swift b/swift/test/Interop/Cxx/class/constructors-copy-module-interface.swift +index 042c10e7d1d..254f6543b58 100644 +--- a/swift/test/Interop/Cxx/class/constructors-copy-module-interface.swift ++++ b/swift/test/Interop/Cxx/class/constructors-copy-module-interface.swift +@@ -1,4 +1,5 @@ + // RUN: %target-swift-ide-test -print-module -module-to-print=Constructors -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s ++// XFAIL: OS=linux-androideabi + + // CHECK: struct TemplatedCopyConstructor + // CHECK: struct TemplatedCopyConstructorWithExtraArg +diff --git a/swift/test/Interop/Cxx/class/constructors-diagnostics.swift b/swift/test/Interop/Cxx/class/constructors-diagnostics.swift +index aac01480660..8fa99fae7fb 100644 +--- a/swift/test/Interop/Cxx/class/constructors-diagnostics.swift ++++ b/swift/test/Interop/Cxx/class/constructors-diagnostics.swift +@@ -2,6 +2,7 @@ + + // This test uses -verify-additional-file, which do not work well on Windows. + // UNSUPPORTED: OS=windows-msvc ++// XFAIL: OS=linux-androideabi + + import Constructors + +diff --git a/swift/test/Interop/Cxx/class/constructors-module-interface.swift b/swift/test/Interop/Cxx/class/constructors-module-interface.swift +index bf189b6e302..d2c3d65f03e 100644 +--- a/swift/test/Interop/Cxx/class/constructors-module-interface.swift ++++ b/swift/test/Interop/Cxx/class/constructors-module-interface.swift +@@ -1,4 +1,5 @@ + // RUN: %target-swift-ide-test -print-module -module-to-print=Constructors -I %S/Inputs/ -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s ++// XFAIL: OS=linux-androideabi + + // CHECK: struct ExplicitDefaultConstructor { + // CHECK-NEXT: init() +diff --git a/swift/test/Interop/Cxx/class/constructors-silgen.swift b/swift/test/Interop/Cxx/class/constructors-silgen.swift +index b1624ccccfe..79cbdf170de 100644 +--- a/swift/test/Interop/Cxx/class/constructors-silgen.swift ++++ b/swift/test/Interop/Cxx/class/constructors-silgen.swift +@@ -1,4 +1,5 @@ + // RUN: %target-swiftxx-frontend -I %S/Inputs -Xllvm -sil-print-types -emit-silgen %s | %FileCheck %s ++// XFAIL: OS=linux-androideabi + + import Constructors + +diff --git a/swift/test/Interop/Cxx/class/constructors-typechecker.swift b/swift/test/Interop/Cxx/class/constructors-typechecker.swift +index 8ce10b1ca75..52ff4104b83 100644 +--- a/swift/test/Interop/Cxx/class/constructors-typechecker.swift ++++ b/swift/test/Interop/Cxx/class/constructors-typechecker.swift +@@ -1,4 +1,5 @@ + // RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -enable-experimental-cxx-interop ++// XFAIL: OS=linux-androideabi + + import Constructors + +diff --git a/swift/test/Interop/Cxx/class/custom-new-operator-irgen.swift b/swift/test/Interop/Cxx/class/custom-new-operator-irgen.swift +index 74e692c9db2..0423493afac 100644 +--- a/swift/test/Interop/Cxx/class/custom-new-operator-irgen.swift ++++ b/swift/test/Interop/Cxx/class/custom-new-operator-irgen.swift +@@ -5,4 +5,4 @@ import CustomNewOperator + var x = callsCustomNew() + + // Make sure the definition of `operator new` is emitted. +-// CHECK: define {{.*}} @{{_ZnwmPv15container_new_t|"\?\?2@YAPEAX_KPEAXUcontainer_new_t@@@Z"}} ++// CHECK: define {{.*}} @{{_Znw(j|m)Pv15container_new_t|"\?\?2@YAPEAX_KPEAXUcontainer_new_t@@@Z"}} +diff --git a/swift/test/SILOptimizer/package-cmo-serialize-tables.swift b/swift/test/SILOptimizer/package-cmo-serialize-tables.swift +index 382ff2e8080..f061374b2a1 100644 +--- a/swift/test/SILOptimizer/package-cmo-serialize-tables.swift ++++ b/swift/test/SILOptimizer/package-cmo-serialize-tables.swift +@@ -19,7 +19,7 @@ + + // Temporarily disabling on watchOS (both arm64_32 & armv7k): + // rdar://140330692 (🟠 OSS Swift CI: oss-swift_tools-RA_stdlib-DA_test-device-non_executable failed... +-// UNSUPPORTED: OS=watchos ++// UNSUPPORTED: OS=watchos, OS=linux-androideabi + + //--- main.swift + +diff --git a/swift/test/SILOptimizer/throws_prediction.swift b/swift/test/SILOptimizer/throws_prediction.swift +index f7f2664b2de..01d36e127c6 100644 +--- a/swift/test/SILOptimizer/throws_prediction.swift ++++ b/swift/test/SILOptimizer/throws_prediction.swift +@@ -16,7 +16,7 @@ + // RUN: -sil-verify-all -module-name=test -emit-sil \ + // RUN: | %FileCheck --check-prefix CHECK-DISABLED %s + +-// UNSUPPORTED: CPU=armv7k || CPU=arm64_32 ++// UNSUPPORTED: CPU=armv7k, CPU=arm64_32, CPU=armv7 + + // CHECK-DISABLED-NOT: normal_count + +diff --git a/swift/utils/swift_build_support/swift_build_support/products/product.py b/swift/utils/swift_build_support/swift_build_support/products/product.py +index 274b6037305..bf0f7fcf671 100644 +--- a/swift/utils/swift_build_support/swift_build_support/products/product.py ++++ b/swift/utils/swift_build_support/swift_build_support/products/product.py +@@ -212,7 +212,7 @@ class Product(object): + if self.args.cross_compile_hosts: + if self.is_darwin_host(host_target): + install_destdir = self.host_install_destdir(host_target) +- else: ++ elif self.args.cross_compile_append_host_target_to_destdir: + install_destdir = os.path.join(install_destdir, self.args.host_target) + return targets.toolchain_path(install_destdir, + self.args.install_prefix) +diff --git a/swift-corelibs-xctest/cmake/modules/PlatformInfo.cmake b/swift-corelibs-xctest/cmake/modules/PlatformInfo.cmake +index 468dc61..a90ae3d 100644 +--- a/swift-corelibs-xctest/cmake/modules/PlatformInfo.cmake ++++ b/swift-corelibs-xctest/cmake/modules/PlatformInfo.cmake +@@ -2,6 +2,10 @@ + set(print_target_info_invocation "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND print_target_info_invocation -target ${CMAKE_Swift_COMPILER_TARGET}) ++else() ++ set(arg_list ${CMAKE_Swift_FLAGS}) ++ separate_arguments(arg_list) ++ list(APPEND print_target_info_invocation ${arg_list}) + endif() + execute_process(COMMAND ${print_target_info_invocation} OUTPUT_VARIABLE target_info_json) + message(CONFIGURE_LOG "Swift Target Info: ${print_target_info_invocation}\n" +diff --git a/swift-testing/cmake/modules/PlatformInfo.cmake b/swift-testing/cmake/modules/PlatformInfo.cmake +index 94c60ef..ab8a491 100644 +--- a/swift-testing/cmake/modules/PlatformInfo.cmake ++++ b/swift-testing/cmake/modules/PlatformInfo.cmake +@@ -9,6 +9,10 @@ + set(print_target_info_invocation "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND print_target_info_invocation -target ${CMAKE_Swift_COMPILER_TARGET}) ++else() ++ set(arg_list ${CMAKE_Swift_FLAGS}) ++ separate_arguments(arg_list) ++ list(APPEND print_target_info_invocation ${arg_list}) + endif() + execute_process(COMMAND ${print_target_info_invocation} OUTPUT_VARIABLE target_info_json) + message(CONFIGURE_LOG "Swift Target Info: ${print_target_info_invocation}\n" diff --git a/swift-ci/sdks/android/patches/swift-android-testing-release.patch b/swift-ci/sdks/android/patches/swift-android-testing-release.patch new file mode 100644 index 00000000..923d1194 --- /dev/null +++ b/swift-ci/sdks/android/patches/swift-android-testing-release.patch @@ -0,0 +1,61 @@ +diff --git a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py +index b6bfa5760ef..324d1a77eea 100644 +--- a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py ++++ b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py +@@ -51,7 +51,7 @@ class SwiftTesting(product.Product): + return False + + def should_install(self, host_target): +- return self.args.install_swift_testing_macros ++ return self.args.install_swift_testing + + def _cmake_product(self, host_target): + build_root = os.path.dirname(self.build_dir) +diff --git a/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c b/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c +index 90f4aa78..0429425b 100644 +--- a/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c ++++ b/swift-corelibs-foundation/Sources/CoreFoundation/CFPlatform.c +@@ -1948,7 +1948,7 @@ CF_CROSS_PLATFORM_EXPORT void *_CFReallocf(void *ptr, size_t size) { + #endif + } + +-#if TARGET_OS_ANDROID ++#if TARGET_OS_ANDROID && __ANDROID_API__ < 28 + + #include + #include +@@ -2277,6 +2277,10 @@ CF_EXPORT int _CFPosixSpawnFileActionsAddClose(_CFPosixSpawnFileActionsRef file_ + return _CFPosixSpawnFileActionsAddCloseImpl(file_actions, filedes); + } + ++CF_EXPORT int _CFPosixSpawnFileActionsChdir(_CFPosixSpawnFileActionsRef file_actions, const char *path) { ++ return ENOSYS; ++} ++ + CF_EXPORT int _CFPosixSpawn(pid_t *_CF_RESTRICT pid, const char *_CF_RESTRICT path, _CFPosixSpawnFileActionsRef file_actions, _CFPosixSpawnAttrRef _Nullable _CF_RESTRICT attrp, char *_Nullable const argv[_Nullable _CF_RESTRICT], char *_Nullable const envp[_Nullable _CF_RESTRICT]) { + _CFPosixSpawnInitialize(); + return _CFPosixSpawnImpl(pid, path, file_actions, attrp, argv, envp); +@@ -2279,7 +2279,7 @@ CF_EXPORT int _CFPosixSpawnFileActionsAddClose(_CFPosixSpawnFileActionsRef file_ + } + + CF_EXPORT int _CFPosixSpawnFileActionsChdir(_CFPosixSpawnFileActionsRef file_actions, const char *path) { +- #if defined(__GLIBC__) && !__GLIBC_PREREQ(2, 29) ++ #if defined(__GLIBC__) && !__GLIBC_PREREQ(2, 29) || (defined(__ANDROID__) && __ANDROID_API__ < 34) + // Glibc versions prior to 2.29 don't support posix_spawn_file_actions_addchdir_np, impacting: + // - Amazon Linux 2 (EoL mid-2025) + return ENOSYS; +diff --git a/swift-testing/cmake/modules/SwiftModuleInstallation.cmake b/swift-testing/cmake/modules/SwiftModuleInstallation.cmake +index 1553725..d9f9e5b 100644 +--- a/swift-testing/cmake/modules/SwiftModuleInstallation.cmake ++++ b/swift-testing/cmake/modules/SwiftModuleInstallation.cmake +@@ -75,6 +75,10 @@ function(_swift_testing_install_target module) + set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET}) ++ else() ++ set(arg_list ${CMAKE_Swift_FLAGS}) ++ separate_arguments(arg_list) ++ list(APPEND module_triple_command ${arg_list}) + endif() + execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json) + string(JSON module_triple GET "${target_info_json}" "target" "moduleTriple") diff --git a/swift-ci/sdks/android/patches/swift-android-trunk-libdispatch.patch b/swift-ci/sdks/android/patches/swift-android-trunk-libdispatch.patch new file mode 100644 index 00000000..4e824fad --- /dev/null +++ b/swift-ci/sdks/android/patches/swift-android-trunk-libdispatch.patch @@ -0,0 +1,63 @@ +diff --git a/swift/test/Misc/verify-swift-feature-testing.test-sh b/swift/test/Misc/verify-swift-feature-testing.test-sh +index 3f36fc979cb..8713ae8fea8 100755 +--- a/swift/test/Misc/verify-swift-feature-testing.test-sh ++++ b/swift/test/Misc/verify-swift-feature-testing.test-sh +@@ -98,7 +98,6 @@ def find_matches(swift_src_root): + # `-enable-upcoming-feature` in the test directories. + output = subprocess.check_output( + [ +- "git", + "grep", + "--extended-regexp", + "--recursive", +diff --git a/swift/test/Reflection/conformance_descriptors.swift b/swift/test/Reflection/conformance_descriptors.swift +index b114f764552..e1bd98c08f4 100644 +--- a/swift/test/Reflection/conformance_descriptors.swift ++++ b/swift/test/Reflection/conformance_descriptors.swift +@@ -5,6 +5,7 @@ + // + // Temporarily disable on AArch64 Linux (rdar://88451721) + // UNSUPPORTED: OS=linux-gnu && CPU=aarch64 ++// XFAIL: OS=linux-android + + // rdar://100558042 + // UNSUPPORTED: CPU=arm64e +diff --git a/swift/test/Reflection/typeref_decoding.swift b/swift/test/Reflection/typeref_decoding.swift +index e0a3b4465a3..c01af893eda 100644 +--- a/swift/test/Reflection/typeref_decoding.swift ++++ b/swift/test/Reflection/typeref_decoding.swift +@@ -10,6 +10,7 @@ + + // FIXME: rdar://127796117 + // UNSUPPORTED: OS=linux-gnu && CPU=aarch64 ++// XFAIL: OS=linux-android + + // RUN: %target-build-swift -target %target-swift-5.2-abi-triple -Xfrontend -enable-anonymous-context-mangled-names %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift -parse-as-library -emit-module -emit-library %no-fixup-chains -module-name TypesToReflect -o %t/%target-library-name(TypesToReflect) + // RUN: %target-build-swift -target %target-swift-5.2-abi-triple -Xfrontend -enable-anonymous-context-mangled-names %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift %S/Inputs/main.swift -emit-module -emit-executable %no-fixup-chains -module-name TypesToReflect -o %t/TypesToReflect +diff --git a/swift-corelibs-libdispatch/cmake/modules/SwiftSupport.cmake b/swift-corelibs-libdispatch/cmake/modules/SwiftSupport.cmake +index 3da519e..e2dd8ed 100644 +--- a/swift-corelibs-libdispatch/cmake/modules/SwiftSupport.cmake ++++ b/swift-corelibs-libdispatch/cmake/modules/SwiftSupport.cmake +@@ -4,6 +4,10 @@ if(NOT dispatch_MODULE_TRIPLE) + set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET}) ++ else() ++ set(arg_list ${CMAKE_Swift_FLAGS}) ++ separate_arguments(arg_list) ++ list(APPEND module_triple_command ${arg_list}) + endif() + execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json) + +diff --git a/swift-corelibs-libdispatch/src/swift/CMakeLists.txt b/swift-corelibs-libdispatch/src/swift/CMakeLists.txt +index 38bef37..d0ddf98 100644 +--- a/swift-corelibs-libdispatch/src/swift/CMakeLists.txt ++++ b/swift-corelibs-libdispatch/src/swift/CMakeLists.txt +@@ -15,6 +15,7 @@ add_library(swiftDispatch + Source.swift + Time.swift + Wrapper.swift) ++set(CMAKE_SHARED_LINKER_FLAGS "") + target_compile_options(swiftDispatch PRIVATE + "SHELL:-Xcc -fblocks" + "SHELL:-Xcc -fmodule-map-file=${PROJECT_SOURCE_DIR}/dispatch/module.modulemap" diff --git a/swift-ci/sdks/android/patches/swift-android.patch b/swift-ci/sdks/android/patches/swift-android.patch new file mode 100644 index 00000000..2d465ea2 --- /dev/null +++ b/swift-ci/sdks/android/patches/swift-android.patch @@ -0,0 +1,103 @@ +diff --git a/swift/utils/build-script-impl b/swift/utils/build-script-impl +index 16e05052609..7ab8cebfab8 100755 +--- a/swift/utils/build-script-impl ++++ b/swift/utils/build-script-impl +@@ -2622,6 +2622,7 @@ for host in "${ALL_HOSTS[@]}"; do + echo "Cleaning the libdispatch build directory" + call rm -rf "${LIBDISPATCH_BUILD_DIR}" + fi ++ call ln -sf "${SWIFT_BUILD_PATH}/lib/swift" "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib" + + cmake_options=( + -DENABLE_SWIFT=YES +diff --git a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py +index 324d1a77eea..e88601a8701 100644 +--- a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py ++++ b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py +@@ -13,6 +13,9 @@ + import os + + from build_swift.build_swift.versions import Version ++from ..host_specific_configuration \ ++ import HostSpecificConfiguration ++from ..targets import StdlibDeploymentTarget + + from . import cmake_product + from . import product +@@ -115,6 +117,22 @@ class SwiftTestingCMakeShim(cmake_product.CMakeProduct): + # FIXME: If we build macros for the builder, specify the path. + self.cmake_options.define('SwiftTesting_MACRO', 'NO') + ++ if host_target.startswith('android') and self.is_cross_compile_target(host_target): ++ host_config = HostSpecificConfiguration(host_target, self.args) ++ self.cmake_options.extend(host_config.cmake_options) ++ flags = '-target %s-unknown-linux-android%s ' % (self.args.android_arch, ++ self.args.android_api_level) ++ ++ flags += '-resource-dir %s/lib/swift ' % ( ++ self.host_install_destdir(host_target) + self.args.install_prefix) ++ ++ ndk_path = StdlibDeploymentTarget.get_target_for_name(host_target).platform.ndk_toolchain_path(self.args) ++ flags += '-sdk %s/sysroot ' % (ndk_path) ++ flags += '-tools-directory %s/bin' % (ndk_path) ++ self.cmake_options.define('CMAKE_Swift_FLAGS', flags) ++ self.cmake_options.define('CMAKE_CXX_COMPILER_WORKS', 'True') ++ self.cmake_options.define('CMAKE_FIND_ROOT_PATH', self.args.cross_compile_deps_path) ++ + self.generate_toolchain_file_for_darwin_or_linux( + host_target, override_macos_deployment_version=override_deployment_version) + self.build_with_cmake([], self.args.build_variant, [], +diff --git a/swift-corelibs-foundation/CMakeLists.txt b/swift-corelibs-foundation/CMakeLists.txt +index 7f290d16..95366592 100644 +--- a/swift-corelibs-foundation/CMakeLists.txt ++++ b/swift-corelibs-foundation/CMakeLists.txt +@@ -51,6 +51,7 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows) + endif() + endif() + ++set(CMAKE_SHARED_LINKER_FLAGS "") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +diff --git a/swift-foundation/cmake/modules/SwiftFoundationSwiftSupport.cmake b/swift-foundation/cmake/modules/SwiftFoundationSwiftSupport.cmake +index cbdfc2a..bb4121d 100644 +--- a/swift-foundation/cmake/modules/SwiftFoundationSwiftSupport.cmake ++++ b/swift-foundation/cmake/modules/SwiftFoundationSwiftSupport.cmake +@@ -37,6 +37,10 @@ function(_swift_foundation_install_target module) + set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET}) ++ else() ++ set(arg_list ${CMAKE_Swift_FLAGS}) ++ separate_arguments(arg_list) ++ list(APPEND module_triple_command ${arg_list}) + endif() + execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json) + string(JSON module_triple GET "${target_info_json}" "target" "moduleTriple") +diff --git a/swift-testing/CMakeLists.txt b/swift-testing/CMakeLists.txt +index 1be9a4b..bd7b1bd 100644 +--- a/swift-testing/CMakeLists.txt ++++ b/swift-testing/CMakeLists.txt +@@ -28,6 +28,7 @@ list(APPEND CMAKE_MODULE_PATH + ${PROJECT_SOURCE_DIR}/cmake/modules + ${PROJECT_SOURCE_DIR}/cmake/modules/shared) + ++set(CMAKE_SHARED_LINKER_FLAGS "") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +diff --git a/swift-testing/cmake/modules/TargetTriple.cmake b/swift-testing/cmake/modules/TargetTriple.cmake +index e087cc4..02f3a95 100644 +--- a/swift-testing/cmake/modules/TargetTriple.cmake ++++ b/swift-testing/cmake/modules/TargetTriple.cmake +@@ -10,6 +10,10 @@ + set(SWT_TARGET_INFO_COMMAND "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND SWT_TARGET_INFO_COMMAND -target ${CMAKE_Swift_COMPILER_TARGET}) ++else() ++ set(arg_list ${CMAKE_Swift_FLAGS}) ++ separate_arguments(arg_list) ++ list(APPEND SWT_TARGET_INFO_COMMAND ${arg_list}) + endif() + execute_process(COMMAND ${SWT_TARGET_INFO_COMMAND} OUTPUT_VARIABLE SWT_TARGET_INFO_JSON) + string(JSON SWT_TARGET_TRIPLE GET "${SWT_TARGET_INFO_JSON}" "target" "unversionedTriple") diff --git a/swift-ci/sdks/android/scripts/build.sh b/swift-ci/sdks/android/scripts/build.sh new file mode 100755 index 00000000..b388f025 --- /dev/null +++ b/swift-ci/sdks/android/scripts/build.sh @@ -0,0 +1,699 @@ +#!/bin/bash +# Swift SDK for Android: Build Script +set -e + +# Docker sets TERM to xterm if using a pty; we probably want +# xterm-256color, otherwise we only get eight colors +if [ -t 1 ]; then + if [[ "$TERM" == "xterm" ]]; then + export TERM=xterm-256color + fi +fi + +if [[ -n "$TERM" ]]; then + bold="" + white="" + grey="" + reset="" +else + bold=$(tput bold) + white=$(tput setaf 15) + grey=$(tput setaf 8) + reset=$(tput sgr0) +fi + +function cleanup { + echo "${reset}" +} +trap cleanup EXIT + +function header { + local text="$1" + echo "" + echo "${white}${bold}*** ${text} ***${reset}${grey}" + echo "" +} + +function groupstart { + local text="$1" + if [[ ! -z "$CI" ]]; then + echo "::group::${text}" + fi + header $text +} + +function groupend { + if [[ ! -z "$CI" ]]; then + echo "::endgroup::" + fi +} + +function usage { + cat < --products-dir --ndk-home + [--name ] [--version ] [--build-dir ] + [--archs [, ...]] + +Build the Swift Android SDK. + +Options: + + --name Specify the name of the SDK bundle. + --version Specify the version of the Android SDK. + --source-dir Specify the path in which the sources can be found. + --ndk-home Specify the path to the Android NDK + --host-toolchain Specify the path to the host Swift toolchain + --build-compiler Whether to build and validate the host compiler + --products-dir Specify the path in which the products should be written. + --build-dir Specify the path in which intermediates should be stored. + --android-api Specify the Android API level + (Default is ${android_api}). + --archs [, ...] + Specify the architectures for which we should build + the SDK. + (Default is ${archs}). + --build Specify the CMake build type to use (Release, Debug, + RelWithDebInfo). + (Default is ${build_type}). + -j + --jobs Specify the number of parallel jobs to run at a time. + (Default is ${parallel_jobs}.) +EOF +} + +# Declare all the packages we depend on +declare -a packages + +function declare_package +{ + local name=$1 + local userVisibleName=$2 + local license=$3 + local url=$4 + + local snake=$(echo ${name} | tr '_' '-') + + declare -g ${name}_snake="$snake" + declare -g ${name}_name="$userVisibleName" + declare -g ${name}_license="$license" + declare -g ${name}_url="$url" + + packages+=(${name}) +} + +declare_package android_sdk \ + "Swift SDK for Android" \ + "Apache-2.0" "https://swift.org/install" +declare_package swift "swift" "Apache-2.0" "https://swift.org" +declare_package libxml2 "libxml2" "MIT" \ + "https://github.com/GNOME/libxml2" +declare_package curl "curl" "MIT" "https://curl.se" +declare_package boringssl "boringssl" "OpenSSL AND ISC AND MIT" \ + "https://boringssl.googlesource.com/boringssl/" + +# Parse command line arguments +android_sdk_version=0.1 +sdk_name= +archs=aarch64,armv7,x86_64 +android_api=28 +build_type=Release +parallel_jobs=$(($(nproc --all) + 2)) +source_dir= +ndk_home=${ANDROID_NDK} +build_dir=$(pwd)/build +products_dir= + +while [ "$#" -gt 0 ]; do + case "$1" in + --source-dir) + source_dir="$2"; shift ;; + --ndk-home) + ndk_home="$2"; shift ;; + --host-toolchain) + host_toolchain="$2"; shift ;; + --build-compiler) + build_compiler="$2"; shift ;; + --build-dir) + build_dir="$2"; shift ;; + --android-api) + android_api="$2"; shift ;; + --products-dir) + products_dir="$2"; shift ;; + --name) + sdk_name="$2"; shift ;; + --archs) + archs="$2"; shift ;; + --build) + build_type="$2"; shift ;; + --version) + android_sdk_version="$2"; shift ;; + -j|--jobs) + parallel_jobs=$2; shift ;; + *) + echo "Unknown argument '$1'"; usage; exit 0 ;; + esac + shift +done + +# Change the commas for spaces +archs="${archs//,/ }" + +if [[ -z "$source_dir" || -z "$products_dir" || -z "$ndk_home" ]]; then + usage + exit 1 +fi + +if ! swiftc=$(which swiftc); then + echo "build.sh: Unable to find Swift compiler. You must have a Swift toolchain installed to build the Android SDK." + exit 1 +fi + +# Find the version numbers of the various dependencies +function describe { + pushd $1 >/dev/null 2>&1 + # this is needed for docker containers or else we get the error: + # fatal: detected dubious ownership in repository at '/source/curl' + if [[ "${SWIFT_BUILD_DOCKER}" == "1" ]]; then + git config --global --add safe.directory $(pwd) + fi + git describe --tags + popd >/dev/null 2>&1 +} +function versionFromTag { + desc=$(describe $1) + if [[ $desc == v* ]]; then + echo "${desc#v}" + else + echo "${desc}" + fi +} + +swift_version=$(describe ${source_dir}/swift-project/swift) +swift_tag_date=$(git -C ${source_dir}/swift-project/swift log -1 --format=%ct 2>/dev/null) + +if [[ $swift_version == swift-* ]]; then + swift_version=${swift_version#swift-} +fi + +if [[ -z "$sdk_name" ]]; then + sdk_name=swift-${swift_version}-android-${android_sdk_version} +fi + +libxml2_version=$(versionFromTag ${source_dir}/libxml2) + +curl_desc=$(describe ${source_dir}/curl | tr '_' '.') +curl_version=${curl_desc#curl-} + +boringssl_version=$(describe ${source_dir}/boringssl) + +function quiet_pushd { + pushd "$1" >/dev/null 2>&1 +} +function quiet_popd { + popd >/dev/null 2>&1 +} + +header "Swift Android SDK build script" + +swift_dir=$(realpath $(dirname "$swiftc")/..) +HOST=linux-x86_64 +#HOST=$(uname -s -m | tr '[:upper:]' '[:lower:]' | tr ' ' '-') + +# in a Docker container, the pre-installed NDK is read-only, +# but the build script needs to write to it to work around +# https://github.com/swiftlang/swift-driver/pull/1822 +# so we copy it to a read-write location for the purposes of the build +# this can all be removed once that PR lands +mkdir -p ${build_dir}/ndk/ +ndk_home_tmp=${build_dir}/ndk/$(basename $ndk_home) +cp -a $ndk_home $ndk_home_tmp +ndk_home=$ndk_home_tmp + +ndk_installation=$ndk_home/toolchains/llvm/prebuilt/$HOST + +# ANDROID_NDK env needed by the swift-android.patch for: +# call ln -sf "${SWIFT_BUILD_PATH}/lib/swift" "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib" +export ANDROID_NDK_HOME=$ndk_home +export ANDROID_NDK=$ndk_home + +echo "Swift found at ${swift_dir}" +if [[ ! -z "${host_toolchain}" ]]; then + echo "Host toolchain found at ${host_toolchain}" + ${host_toolchain}/bin/swift --version +fi +echo "Android NDK found at ${ndk_home}" +${ndk_installation}/bin/clang --version +echo "Building for ${archs}" +echo "Sources are in ${source_dir}" +echo "Build will happen in ${build_dir}" +echo "Products will be placed in ${products_dir}" +echo +echo "Building from:" +echo " - Swift ${swift_version}" +echo " - libxml2 ${libxml2_version}" +echo " - curl ${curl_version}" +echo " - BoringSSL ${boringssl_version}" + +# make sure the products_dir is writeable +ls -lad $products_dir +touch $products_dir/products_dir_write_test.tmp +rm $products_dir/products_dir_write_test.tmp +#chown -R $(id -u):$(id -g) $products_dir + +function run() { + echo "$@" + "$@" +} + +for arch in $archs; do + case $arch in + armv7) + target_host="arm-linux-androideabi" + compiler_target_host="armv7a-linux-androideabi$android_api" + android_abi="armeabi-v7a" + ;; + aarch64) + target_host="aarch64-linux-android" + compiler_target_host="$target_host$android_api" + android_abi="arm64-v8a" + ;; + x86_64) + target_host="x86_64-linux-android" + compiler_target_host="$target_host$android_api" + android_abi="x86_64" + ;; + x86) + target_host="x86-linux-android" + compiler_target_host="$target_host$android_api" + android_abi="x86" + ;; + *) + echo "Unknown architecture '$1'" + usage + exit 0 + ;; + esac + + sdk_root=${build_dir}/sdk_root/${arch} + mkdir -p "$sdk_root" + + groupstart "Building libxml2 for $arch" + quiet_pushd ${source_dir}/libxml2 + run cmake \ + -G Ninja \ + -S ${source_dir}/libxml2 \ + -B ${build_dir}/$arch/libxml2 \ + -DANDROID_ABI=$android_abi \ + -DANDROID_PLATFORM=android-$android_api \ + -DCMAKE_TOOLCHAIN_FILE=$ndk_home/build/cmake/android.toolchain.cmake \ + -DCMAKE_BUILD_TYPE=$build_type \ + -DCMAKE_EXTRA_LINK_FLAGS="-rtlib=compiler-rt -unwindlib=libunwind -stdlib=libc++ -fuse-ld=lld -lc++ -lc++abi -Wl,-z,max-page-size=16384" \ + -DCMAKE_BUILD_TYPE=$build_type \ + -DCMAKE_INSTALL_PREFIX=$sdk_root/usr \ + -DLIBXML2_WITH_PYTHON=NO \ + -DLIBXML2_WITH_ICU=NO \ + -DLIBXML2_WITH_ICONV=NO \ + -DLIBXML2_WITH_LZMA=NO \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_STATIC_LIBS=ON + + quiet_pushd ${build_dir}/$arch/libxml2 + run ninja -j$parallel_jobs + quiet_popd + + header "Installing libxml2 for $arch" + quiet_pushd ${build_dir}/$arch/libxml2 + run ninja -j$parallel_jobs install + quiet_popd + quiet_popd + groupend + + groupstart "Building boringssl for ${compiler_target_host}" + quiet_pushd ${source_dir}/boringssl + run cmake \ + -GNinja \ + -B ${build_dir}/$arch/boringssl \ + -DANDROID_ABI=$android_abi \ + -DANDROID_PLATFORM=android-$android_api \ + -DCMAKE_TOOLCHAIN_FILE=$ndk_home/build/cmake/android.toolchain.cmake \ + -DCMAKE_BUILD_TYPE=$build_type \ + -DCMAKE_INSTALL_PREFIX=$sdk_root/usr \ + -DCMAKE_EXTRA_LINK_FLAGS="-Wl,-z,max-page-size=16384" \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_STATIC_LIBS=ON \ + -DBUILD_TESTING=OFF + + quiet_pushd ${build_dir}/$arch/boringssl + run ninja -j$parallel_jobs + quiet_popd + + header "Installing BoringSSL for $arch" + quiet_pushd ${build_dir}/$arch/boringssl + run ninja -j$parallel_jobs install + quiet_popd + quiet_popd + groupend + + groupstart "Building libcurl for ${compiler_target_host}" + quiet_pushd ${source_dir}/curl + run cmake \ + -G Ninja \ + -S ${source_dir}/curl \ + -B ${build_dir}/$arch/curl \ + -DANDROID_ABI=$android_abi \ + -DANDROID_PLATFORM=android-$android_api \ + -DCMAKE_TOOLCHAIN_FILE=$ndk_home/build/cmake/android.toolchain.cmake \ + -DCMAKE_BUILD_TYPE=$build_type \ + -DCMAKE_INSTALL_PREFIX=$sdk_root/usr \ + -DCMAKE_EXTRA_LINK_FLAGS="-Wl,-z,max-page-size=16384" \ + -DOPENSSL_ROOT_DIR=$sdk_root/usr \ + -DOPENSSL_INCLUDE_DIR=$sdk_root/usr/include \ + -DOPENSSL_SSL_LIBRARY=$sdk_root/usr/lib/libssl.a \ + -DOPENSSL_CRYPTO_LIBRARY=$sdk_root/usr/lib/libcrypto.a \ + -DCURLSSLOPT_NATIVE_CA=ON \ + -DCURL_USE_OPENSSL=ON \ + -DCURL_USE_LIBSSH2=OFF \ + -DCURL_USE_LIBPSL=OFF \ + -DTHREADS_PREFER_PTHREAD_FLAG=OFF \ + -DCMAKE_THREAD_PREFER_PTHREAD=OFF \ + -DCMAKE_THREADS_PREFER_PTHREAD_FLAG=OFF \ + -DCMAKE_HAVE_LIBC_PTHREAD=YES \ + -DBUILD_CURL_EXE=NO \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_STATIC_LIBS=ON \ + -DCURL_BUILD_TESTS=OFF + + quiet_pushd ${build_dir}/$arch/curl + run ninja -j$parallel_jobs + quiet_popd + + header "Installing libcurl for $arch" + quiet_pushd ${build_dir}/$arch/curl + run ninja -j$parallel_jobs install + quiet_popd + quiet_popd + groupend + + groupstart "Building Android SDK for ${compiler_target_host}" + quiet_pushd ${source_dir}/swift-project + build_type_flag="--debug" + case $build_type in + Debug) build_type_flag="--debug" ;; + Release) build_type_flag="--release" ;; + RelWithDebInfo) build_type_flag="--release-debuginfo" ;; + esac + + case $build_compiler in + 1|true|yes|YES) + build_cmark="" + local_build="" + build_llvm="1" + build_swift_tools="1" + validation_test="1" + native_swift_tools_path="" + native_clang_tools_path="" + ;; + *) + build_cmark="--skip-build-cmark" + local_build="--skip-local-build" + build_llvm="0" + build_swift_tools="0" + validation_test="0" + native_swift_tools_path="--native-swift-tools-path=$host_toolchain/bin" + native_clang_tools_path="--native-clang-tools-path=$host_toolchain/bin" + ;; + esac + + # use an out-of-tree build folder + export SWIFT_BUILD_ROOT=${build_dir}/swift-project + + ./swift/utils/build-script \ + $build_type_flag \ + --reconfigure \ + --no-assertions \ + --validation-test=$validation_test \ + --android \ + --android-ndk=$ndk_home \ + --android-arch=$arch \ + --android-api-level=$android_api \ + --cross-compile-hosts=android-$arch \ + --cross-compile-deps-path=$sdk_root \ + --install-destdir=$sdk_root \ + --build-llvm=$build_llvm \ + --build-swift-tools=$build_swift_tools \ + ${native_swift_tools_path} \ + ${native_clang_tools_path} \ + ${build_cmark} \ + ${local_build} \ + --host-test \ + --skip-test-linux \ + --skip-test-xctest --skip-test-foundation \ + --build-swift-static-stdlib \ + --swift-install-components='compiler;clang-resource-dir-symlink;license;stdlib;sdk-overlay' \ + --install-swift \ + --install-libdispatch \ + --install-foundation \ + --xctest --install-xctest \ + --swift-testing --install-swift-testing \ + --cross-compile-build-swift-tools=0 \ + --llvm-ninja-targets-for-cross-compile-hosts=help \ + --cross-compile-append-host-target-to-destdir=False + # --extra-cmake-options='-DCMAKE_EXTRA_LINK_FLAGS="-Wl,-z,max-page-size=16384"' + # need to remove symlink that gets created in the NDK to the previous arch's build + # or else we get errors like: + # error: could not find module '_Builtin_float' for target 'x86_64-unknown-linux-android'; found: aarch64-unknown-linux-android, at: /home/runner/work/_temp/swift-android-sdk/ndk/android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/swift/android/_Builtin_float.swiftmodule + rm -f $ndk_installation/sysroot/usr/lib/swift + quiet_popd + groupend +done + +# Now generate the bundle +groupstart "Bundling SDK" + +sdk_base=swift-android +sdk_staging="sdk_staging" + +bundle="${sdk_name}.artifactbundle" + +rm -rf ${build_dir}/$bundle +mkdir -p ${build_dir}/$bundle +quiet_pushd ${build_dir}/$bundle + +# First the info.json, for SwiftPM +cat > info.json < $swift_res_root/SDKSettings.json < scripts/setup-android-sdk.sh <<'EOF' +#/bin/bash +# this script will setup the ndk-sysroot with links to the +# local installation indicated by ANDROID_NDK_HOME +set -e +if [ -z "${ANDROID_NDK_HOME}" ]; then + echo "$(basename $0): error: missing environment variable ANDROID_NDK_HOME" + exit 1 +fi + +ndk_prebuilt="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt" +if [ ! -d "${ndk_prebuilt}" ]; then + echo "$(basename $0): error: ANDROID_NDK_HOME not found: ${ndk_prebuilt}" + exit 1 +fi + +#Pkg.Revision = 27.0.12077973 +#Pkg.Revision = 28.1.13356709 +ndk_version=$(grep '^Pkg.Revision = ' "${ANDROID_NDK_HOME}/source.properties" | cut -f3- -d' ' | cut -f 1 -d '.') +if [[ "${ndk_version}" -lt 27 ]]; then + echo "$(basename $0): error: minimum NDK version 27 required; found ${ndk_version} in ${ANDROID_NDK_HOME}/source.properties" + exit 1 +fi + +cd $(dirname $(dirname $(realpath -- "${BASH_SOURCE[0]}"))) +swift_resources=swift-resources +ndk_sysroot=ndk-sysroot + +if [[ -d "${ndk_sysroot}" ]]; then + # clear out any previous NDK setup + rm -rf ${ndk_sysroot} + ndk_re="re-" +fi + +# link vs. copy the NDK files +SWIFT_ANDROID_NDK_LINK=${SWIFT_ANDROID_NDK_LINK:-1} +if [[ "${SWIFT_ANDROID_NDK_LINK}" == 1 ]]; then + ndk_action="${ndk_re}linked" + mkdir -p ${ndk_sysroot}/usr/lib + ln -s ${ndk_prebuilt}/*/sysroot/usr/include ${ndk_sysroot}/usr/include + for triplePath in ${ndk_prebuilt}/*/sysroot/usr/lib/*; do + triple=$(basename ${triplePath}) + ln -s ${triplePath} ${ndk_sysroot}/usr/lib/${triple} + done +else + ndk_action="${ndk_re}copied" + cp -a ${ndk_prebuilt}/*/sysroot ${ndk_sysroot} +fi + +# copy each architecture's swiftrt.o into the sysroot, +# working around https://github.com/swiftlang/swift/pull/79621 +for folder in swift swift_static; do + for swiftrt in ${swift_resources}/usr/lib/${folder}-*/android/*/swiftrt.o; do + arch=$(basename $(dirname ${swiftrt})) + mkdir -p ${ndk_sysroot}/usr/lib/${folder}/android/${arch} + if [[ "${SWIFT_ANDROID_NDK_LINK}" == 1 ]]; then + ln -s ../../../../../../${swiftrt} ${ndk_sysroot}/usr/lib/${folder}/android/${arch}/ + else + cp -a ${swiftrt} ${ndk_sysroot}/usr/lib/${folder}/android/${arch}/ + fi + done +done + +echo "$(basename $0): success: ndk-sysroot ${ndk_action} to Android NDK at ${ndk_prebuilt}" +EOF + +chmod +x scripts/setup-android-sdk.sh + +cat > swift-sdk.json <> swift-sdk.json <> swift-sdk.json <> swift-sdk.json < swift-toolset.json <|--swift-tag + |--swift-version ] + [--curl-version ] + [--boringssl-version ] + [--clone-with-ssh] + [--source-dir ] + +Fetch all the sources required to build the fully statically linked Linux +SDK for Swift. Options are: + + --clone-with-ssh Use git-over-SSH rather than HTTPS where possible. + --source-dir Specify the path in which the sources should be checked + out. This directory will be created it if does not exist. + --swift-scheme + --swift-tag + --swift-version + Select the version of Swift to check out sources for. + If starts with "scheme:" or "tag:", it will + select a scheme or tag; otherwise it will be treated as + a version number. + --libxml2-version + --curl-version + --boringssl-version +EOF +} + +# Defaults +if [[ -z "${SWIFT_VERSION}" ]]; then + SWIFT_VERSION=scheme:release/6.1 +fi +if [[ -z "${LIBXML2_VERSION}" ]]; then + LIBXML2_VERSION=2.14.2 +fi +if [[ -z "${CURL_VERSION}" ]]; then + CURL_VERSION=8.13.0 +fi +if [[ -z "${BORINGSSL_VERSION}" ]]; then + BORINGSSL_VERSION=fips-20220613 +fi +if [[ -z "${YAMS_VERSION}" ]]; then + YAMS_VERSION=5.0.6 +fi + +clone_with_ssh=false +while [ "$#" -gt 0 ]; do + case "$1" in + --swift-scheme) + SWIFT_VERSION="scheme:$2"; shift ;; + --swift-tag) + SWIFT_VERSION="tag:$2"; shift ;; + --swift-version) + SWIFT_VERSION="$2"; shift ;; + --libxml2-version) + LIBXML2_VERSION="$2"; shift ;; + --curl-version) + CURL_VERSION="$2"; shift ;; + --boringssl-version) + BORINGSSL_VERSION="$2"; shift ;; + --clone-with-ssh) + clone_with_ssh=true ;; + --source-dir) + source_dir="$2"; shift ;; + *) + usage; exit 0 ;; + esac + shift +done + +if [[ ! -z "$source_dir" ]]; then + mkdir -p "$source_dir" +else + source_dir=. +fi + +if [[ "$clone_with_ssh" == "true" ]]; then + github=git@github.com: + clone_arg=--clone-with-ssh +else + github=https://github.com/ + clone_arg=--clone +fi + +cd "$source_dir" + +# Fetch Swift +mkdir -p swift-project + +groupstart "Fetching Swift" +pushd swift-project >/dev/null + +[[ -d swift ]] || git clone ${github}swiftlang/swift.git +cd swift + +# Get its dependencies +header "Fetching Swift Dependencies" + +extra_args="--skip-history --all-repositories" +if [[ $SWIFT_VERSION == scheme:* ]]; then + utils/update-checkout ${clone_arg} --scheme ${SWIFT_VERSION#scheme:} ${extra_args} +elif [[ $SWIFT_VERSION == tag:* ]]; then + utils/update-checkout ${clone_arg} --tag ${SWIFT_VERSION#tag:} ${extra_args} +else + utils/update-checkout ${clone_arg} --tag swift-${SWIFT_VERSION}-RELEASE ${extra_args} +fi + +popd >/dev/null +groupend + +# Fetch yams (needed for Swift 6.1.x) +groupstart "Fetching yams" +pushd swift-project >/dev/null +[[ -d yams ]] || git clone ${github}jpsim/Yams.git yams +pushd yams >/dev/null 2>&1 +git checkout ${YAMS_VERSION} +popd >/dev/null 2>&1 +popd >/dev/null +groupend + +# Fetch libxml2 +groupstart "Fetching libxml2" +[[ -d libxml2 ]] || git clone ${github}GNOME/libxml2.git +pushd libxml2 >/dev/null 2>&1 +git checkout v${LIBXML2_VERSION} +popd >/dev/null 2>&1 +groupend + +# Fetch curl +groupstart "Fetching curl" +[[ -d curl ]] || git clone ${github}curl/curl.git +pushd curl >/dev/null 2>&1 +git checkout curl-$(echo ${CURL_VERSION} | tr '.' '_') +popd >/dev/null 2>&1 +groupend + +# Fetch BoringSSL +groupstart "Fetching BoringSSL" +[[ -d boringssl ]] || git clone https://boringssl.googlesource.com/boringssl +pushd boringssl >/dev/null 2>&1 +git checkout ${BORINGSSL_VERSION} +popd >/dev/null 2>&1 +groupend + diff --git a/swift-ci/sdks/android/scripts/install-ndk.sh b/swift-ci/sdks/android/scripts/install-ndk.sh new file mode 100755 index 00000000..876d730a --- /dev/null +++ b/swift-ci/sdks/android/scripts/install-ndk.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# ===----------------------------------------------------------------------=== +# +# Swift Android SDK: Install NDK +# +# ===----------------------------------------------------------------------=== + +set -e + +echo "Installing Android NDK" + +mkdir -p /usr/local/ndk +pushd /usr/local/ndk >/dev/null + +if [[ "${ANDROID_NDK_VERSION}" == "" ]]; then + echo "$0: Missing ANDROID_NDK_VERSION environment" + exit 1 +fi + + +NDKFILE=${ANDROID_NDK_VERSION}-linux.zip + +NDKURL="https://dl.google.com/android/repository/${NDKFILE}" +echo "Going to fetch ${NDKURL}" + +curl -fsSL "${NDKURL}" -o ${NDKFILE} + +echo "Extracting NDK" +unzip -q ${NDKFILE} + +rm ${NDKFILE} + +popd >/dev/null + diff --git a/swift-ci/sdks/android/scripts/install-swift.sh b/swift-ci/sdks/android/scripts/install-swift.sh new file mode 100755 index 00000000..0acd9e02 --- /dev/null +++ b/swift-ci/sdks/android/scripts/install-swift.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# ===----------------------------------------------------------------------=== +# +# Swift Android SDK: Install Swift +# +# ===----------------------------------------------------------------------=== + +set -e + +if [[ "${SWIFT_TOOLCHAIN_URL}" == "" ]]; then + echo "$0: Missing SWIFT_TOOLCHAIN_URL environment" + exit 1 +fi + +destination=$1 +if [[ "${destination}" == "" ]]; then + echo "$0: Usage: $(basename $0) " + exit 1 +fi + +echo "Installing Swift from: ${SWIFT_TOOLCHAIN_URL} into: ${destination}" + +# Make a temporary directory +tmpdir=$(mktemp -d) +function cleanup { + rm -rf "$tmpdir" +} +trap cleanup EXIT + +pushd "$tmpdir" >/dev/null +export GNUPGHOME="$tmpdir" + +# Fetch the toolchain and signature +echo "Going to fetch ${SWIFT_TOOLCHAIN_URL}" +curl -fsSL "${SWIFT_TOOLCHAIN_URL}" -o toolchain.tar.gz + +echo "Going to fetch ${SWIFT_TOOLCHAIN_URL}.sig" +curl -fsSL "${SWIFT_TOOLCHAIN_URL}.sig" -o toolchain.sig + +echo "Fetching keys" +curl -fsSL --compressed https://swift.org/keys/all-keys.asc | gpg --import - + +echo "Verifying signature" +gpg --batch --verify toolchain.sig toolchain.tar.gz + +# Extract and install the toolchain +echo "Extracting Swift" +mkdir -p ${destination} +tar -xzf toolchain.tar.gz --directory ${destination} --strip-components=2 +chmod -R o+r ${destination}/lib/swift + +popd >/dev/null + diff --git a/swift-ci/sdks/android/scripts/toolchain-vars.sh b/swift-ci/sdks/android/scripts/toolchain-vars.sh new file mode 100644 index 00000000..4bf5b5ed --- /dev/null +++ b/swift-ci/sdks/android/scripts/toolchain-vars.sh @@ -0,0 +1,47 @@ +#!/bin/bash -e +# +# ===----------------------------------------------------------------------=== +# +# Swift Android SDK: Toolchain source variables +# +# ===----------------------------------------------------------------------=== + +# This script is meant to be sourced from another script that sets the +# BUILD_SCHEME environment variable to one of "release", "swift-VERSION-branch", or "development" +# and will set check the latest builds for each build type in order +# to provide information about the Swift tag name in use and where to +# obtain the latest toolchain for building. + +OS=$(echo $HOST_OS | tr -d '.') +# e.g., "swift-6.1-RELEASE" +# there is no latest-build.yml for releases, so we need to get it from the API +RELEASE_TAG=$(curl -fsSL https://www.swift.org/api/v1/install/releases.json | jq -r '.[-1].tag') +# e.g., "swift-6.1-release" +RELEASE_BRANCH=$(echo "${RELEASE_TAG}" | tr '[A-Z]' '[a-z]') + +case "${BUILD_SCHEME}" in + release) + export SWIFT_TAG=$RELEASE_TAG + export SWIFT_BRANCH=$RELEASE_BRANCH + ;; + development|swift-*-branch) + # e.g., swift-6.2-DEVELOPMENT-SNAPSHOT-2025-05-15-a + # e.g., swift-DEVELOPMENT-SNAPSHOT-2025-05-14-a + export SWIFT_TAG=$(curl -fsSL https://download.swift.org/$BUILD_SCHEME/$OS/latest-build.yml | grep '^dir: ' | cut -f 2 -d ' ') + export SWIFT_BRANCH=$BUILD_SCHEME + ;; + *) + echo "$0: invalid BUILD_SCHEME=${BUILD_SCHEME}" + exit 1 + ;; +esac + +SWIFT_BASE=$SWIFT_TAG-$HOST_OS +case $BUILD_COMPILER in + 1|true|yes|YES) + export SWIFT_TOOLCHAIN_URL="https://download.swift.org/$RELEASE_BRANCH/$OS/$RELEASE_TAG/$RELEASE_TAG-$HOST_OS.tar.gz" + ;; + *) + export SWIFT_TOOLCHAIN_URL="https://download.swift.org/$SWIFT_BRANCH/$OS/$SWIFT_TAG/$SWIFT_BASE.tar.gz" + ;; +esac