@@ -18,6 +18,7 @@ error() { printf -- "** ERROR: %s\n" "$*" >&2; }
1818fatal () { error " $@ " ;  exit  1;  }
1919
2020#  Parse command line options
21+ INSTALL_ANDROID=false
2122INSTALL_STATIC_LINUX=false
2223INSTALL_WASM=false
2324BUILD_EMBEDDED_WASM=false
@@ -27,6 +28,18 @@ SWIFT_BUILD_COMMAND="swift build"
2728
2829while  [[ $#  -gt  0 ]];  do 
2930    case  $1  in 
31+         --android)
32+             INSTALL_ANDROID=true
33+             shift 
34+             ;;
35+         --android-ndk-version=* )
36+             ANDROID_NDK_VERSION=" ${1#* =} " 
37+             shift 
38+             ;;
39+         --android-sdk-triple=* )
40+             ANDROID_SDK_TRIPLE=" ${1#* =} " 
41+             shift 
42+             ;;
3043        --static)
3144            INSTALL_STATIC_LINUX=true
3245            shift 
6477
6578#  Validate arguments
6679if  [[ -z  " $SWIFT_VERSION_INPUT " ;  then 
67-     fatal " Usage: $0  [--static] [--wasm] [--flags=\" <build-flags>\" ] [--build-command=\" <build-command>\" ] <swift-version>" 
80+     fatal " Usage: $0  [--android] [-- static] [--wasm] [--flags=\" <build-flags>\" ] [--build-command=\" <build-command>\" ] <swift-version>" 
6881fi 
6982
70- if  [[ " $INSTALL_STATIC_LINUX " ==  false  &&  " $INSTALL_WASM " ==  false  ]];  then 
71-     fatal " At least one of --static or --wasm must be specified" 
83+ if  [[ " $INSTALL_ANDROID  "   ==   false   &&   " $ INSTALL_STATIC_LINUX" ==  false  &&  " $INSTALL_WASM " ==  false  ]];  then 
84+     fatal " At least one of --android or -- static or --wasm must be specified" 
7285fi 
7386
7487log " Requested Swift version: $SWIFT_VERSION_INPUT " 
88+ log " Install Android Swift SDK: $INSTALL_ANDROID " 
7589log " Install Static Linux Swift SDK: $INSTALL_STATIC_LINUX " 
7690log " Install Wasm Swift SDK: $INSTALL_WASM " 
7791if  [[ -n  " $SWIFT_BUILD_FLAGS " ;  then 
7892    log " Additional build flags: $SWIFT_BUILD_FLAGS " 
7993fi 
8094
81- #  Detect package manager
82- if  command  -v apt > /dev/null 2>&1 ;  then 
83-     INSTALL_PACKAGE_COMMAND=" apt update -q && apt install -yq" 
84- elif  command  -v dnf > /dev/null 2>&1 ;  then 
85-     INSTALL_PACKAGE_COMMAND=" dnf install -y" 
86- elif  command  -v yum > /dev/null 2>&1 ;  then 
87-     INSTALL_PACKAGE_COMMAND=" yum install -y" 
88- else 
89-     fatal " No supported package manager found" 
90- fi 
91- 
9295install_package () {
96+     #  Detect package manager
97+     if  command  -v apt > /dev/null 2>&1 ;  then 
98+         INSTALL_PACKAGE_COMMAND=" apt update -q && apt install -yq" 
99+     elif  command  -v dnf > /dev/null 2>&1 ;  then 
100+         INSTALL_PACKAGE_COMMAND=" dnf install -y" 
101+     elif  command  -v yum > /dev/null 2>&1 ;  then 
102+         INSTALL_PACKAGE_COMMAND=" yum install -y" 
103+     else 
104+         fatal " No supported package manager found" 
105+     fi 
93106    eval  " $INSTALL_PACKAGE_COMMAND  $1 " 
94107}
95108
@@ -103,7 +116,7 @@ SWIFT_API_INSTALL_ROOT="https://www.swift.org/api/v1/install"
103116#  and gets the checksum for the patch version's Static Linux and/or Wasm Swift SDK.
104117# 
105118#  $1 (string): A minor Swift version, e.g. "6.1"
106- #  Output: A string of the form "<patch-version>|<static-checksum>|<wasm-checksum>
119+ #  Output: A string of the form "<patch-version>|<android-checksum>|< static-checksum>|<wasm-checksum>
107120find_latest_swift_version () {
108121    local  minor_version=" $1 " 
109122
@@ -128,6 +141,23 @@ find_latest_swift_version() {
128141
129142    log " Found latest patch version: $latest_version " 
130143
144+     local  android_sdk_checksum=" " 
145+     if  [[ " $INSTALL_ANDROID " ==  true  ]];  then 
146+         android_sdk_checksum=$( echo " $releases_json " |  jq -r --arg version " $latest_version " ' 
147+             .[] 
148+             | select(.name == $version) 
149+             | .platforms[] 
150+             | select(.platform == "android") 
151+             | .checksum 
152+         '  ) 
153+ 
154+         if  [[ -z  " $android_sdk_checksum " ;  then 
155+             fatal " No Android Swift SDK checksum found for Swift $latest_version " 
156+         fi 
157+ 
158+         log " Found Android Swift SDK checksum: ${android_sdk_checksum: 0: 12} ..." 
159+     fi 
160+ 
131161    local  static_linux_sdk_checksum=" " 
132162    if  [[ " $INSTALL_STATIC_LINUX " ==  true  ]];  then 
133163        static_linux_sdk_checksum=$( echo " $releases_json " |  jq -r --arg version " $latest_version " ' 
@@ -162,14 +192,15 @@ find_latest_swift_version() {
162192        log " Found Swift SDK for Wasm checksum: ${wasm_sdk_checksum: 0: 12} ..." 
163193    fi 
164194
165-     echo  " ${latest_version} |${static_linux_sdk_checksum} |${wasm_sdk_checksum} " 
195+     echo  " ${latest_version} |${android_sdk_checksum}  | ${ static_linux_sdk_checksum}${wasm_sdk_checksum} " 
166196}
167197
168- #  Finds the latest Static Linux or Wasm Swift SDK development snapshot
169- #  for the inputted Swift version and its checksum.
198+ #  Finds the latest Android or Static Linux or Wasm
199+ #  Swift SDK development snapshot for the inputted
200+ #  Swift version and its checksum.
170201# 
171202#  $1 (string): Nightly Swift version, e.g. "6.2" or "main"
172- #  $2 (string): "static" or "wasm"
203+ #  $2 (string): "android" or " static" or "wasm"
173204#  Output: A string of the form "<snapshot>|<sdk-checksum>",
174205#  e.g. "swift-6.2-DEVELOPMENT-SNAPSHOT-2025-07-29-a|<sdk-checksum>"
175206find_latest_sdk_snapshot () {
@@ -206,6 +237,12 @@ find_latest_sdk_snapshot() {
206237}
207238
208239SWIFT_VERSION_BRANCH=" " 
240+ ANDROID_SDK_TAG=" " 
241+ ANDROID_SDK_CHECKSUM=" " 
242+ #  TODO: we will be removing the "-0.1" suffix in a future nightly 
243+ ANDROID_SDK_PATH_SUFFIX=" -0.1" 
244+ ANDROID_SDK_PATH_SEP=" -" 
245+ 
209246STATIC_LINUX_SDK_TAG=" " 
210247STATIC_LINUX_SDK_CHECKSUM=" " 
211248WASM_SDK_TAG=" " 
@@ -220,6 +257,13 @@ if [[ "$SWIFT_VERSION_INPUT" == nightly-* ]]; then
220257        SWIFT_VERSION_BRANCH=" swift-${version} -branch" 
221258    fi 
222259
260+     if  [[ " $INSTALL_ANDROID " ==  true  ]];  then 
261+         android_sdk_info=$( find_latest_sdk_snapshot " $version " " android" ) 
262+ 
263+         ANDROID_SDK_TAG=$( echo " $android_sdk_info " |  cut -d' |' ) 
264+         ANDROID_SDK_CHECKSUM=$( echo " $android_sdk_info " |  cut -d' |' ) 
265+     fi 
266+ 
223267    if  [[ " $INSTALL_STATIC_LINUX " ==  true  ]];  then 
224268        static_linux_sdk_info=$( find_latest_sdk_snapshot " $version " " static" ) 
225269
@@ -239,14 +283,21 @@ else
239283    latest_version=$( echo " $latest_version_info " |  cut -d' |' ) 
240284    SWIFT_VERSION_BRANCH=" swift-${latest_version} -release" 
241285
286+     ANDROID_SDK_TAG=" swift-${latest_version} -RELEASE" 
287+     ANDROID_SDK_CHECKSUM=$( echo " $latest_version_info " |  cut -d' |' ) 
288+ 
242289    STATIC_LINUX_SDK_TAG=" swift-${latest_version} -RELEASE" 
243-     STATIC_LINUX_SDK_CHECKSUM=$( echo " $latest_version_info " |  cut -d' |' f2 ) 
290+     STATIC_LINUX_SDK_CHECKSUM=$( echo " $latest_version_info " |  cut -d' |' f3 ) 
244291
245292    WASM_SDK_TAG=" swift-${latest_version} -RELEASE" 
246-     WASM_SDK_CHECKSUM=$( echo " $latest_version_info " |  cut -d' |' f3 ) 
293+     WASM_SDK_CHECKSUM=$( echo " $latest_version_info " |  cut -d' |' f4 ) 
247294fi 
248295
249296#  Validate that required Swift SDK tags are set
297+ if  [[ " $INSTALL_ANDROID " ==  true  &&  -z  " $ANDROID_SDK_TAG " ;  then 
298+     fatal " ANDROID_SDK_TAG is not set but Android Swift SDK installation was requested" 
299+ fi 
300+ 
250301if  [[ " $INSTALL_STATIC_LINUX " ==  true  &&  -z  " $STATIC_LINUX_SDK_TAG " ;  then 
251302    fatal " STATIC_LINUX_SDK_TAG is not set but Static Linux Swift SDK installation was requested" 
252303fi 
@@ -439,9 +490,25 @@ download_and_extract_toolchain() {
439490}
440491
441492INSTALLED_SWIFT_TAG=$( get_installed_swift_tag) 
493+ SWIFT_EXECUTABLE_FOR_ANDROID_SDK=" " 
442494SWIFT_EXECUTABLE_FOR_STATIC_LINUX_SDK=" " 
443495SWIFT_EXECUTABLE_FOR_WASM_SDK=" " 
444496
497+ if  [[ " $INSTALL_ANDROID " ==  true  ]];  then 
498+     if  [[ " $INSTALLED_SWIFT_TAG " ==  " $ANDROID_SDK_TAG " ;  then 
499+         log " Current toolchain matches Android Swift SDK snapshot: $ANDROID_SDK_TAG " 
500+         SWIFT_EXECUTABLE_FOR_ANDROID_SDK=" swift" 
501+     else 
502+         log " Installing Swift toolchain to match Android Swift SDK snapshot: $ANDROID_SDK_TAG " 
503+         initialize_os_info
504+         SWIFT_EXECUTABLE_FOR_ANDROID_SDK=$( download_and_extract_toolchain " $ANDROID_SDK_TAG " ) 
505+         if  [[ $?  -eq  $EXIT_TOOLCHAIN_NOT_FOUND  ]];  then 
506+             #  Don't fail the workflow if we can't find the right toolchain
507+             exit  0
508+         fi 
509+     fi 
510+ fi 
511+ 
445512if  [[ " $INSTALL_STATIC_LINUX " ==  true  ]];  then 
446513    if  [[ " $INSTALLED_SWIFT_TAG " ==  " $STATIC_LINUX_SDK_TAG " ;  then 
447514        log " Current toolchain matches Static Linux Swift SDK snapshot: $STATIC_LINUX_SDK_TAG " 
@@ -472,9 +539,57 @@ if [[ "$INSTALL_WASM" == true ]]; then
472539    fi 
473540fi 
474541
542+ ANDROID_SDK_DOWNLOAD_ROOT=" ${SWIFT_DOWNLOAD_ROOT} /${SWIFT_VERSION_BRANCH} /android-sdk" 
475543STATIC_LINUX_SDK_DOWNLOAD_ROOT=" ${SWIFT_DOWNLOAD_ROOT} /${SWIFT_VERSION_BRANCH} /static-sdk" 
476544WASM_SDK_DOWNLOAD_ROOT=" ${SWIFT_DOWNLOAD_ROOT} /${SWIFT_VERSION_BRANCH} /wasm-sdk" 
477545
546+ install_android_sdk () {
547+     #  Check if the Android Swift SDK is already installed
548+     if  " $SWIFT_EXECUTABLE_FOR_ANDROID_SDK " 2> /dev/null |  grep -q " ^${ANDROID_SDK_TAG} _android" ;  then 
549+         log " ✅ Android Swift SDK ${ANDROID_SDK_TAG}  is already installed, skipping installation" 
550+         return  0
551+     fi 
552+ 
553+     log " Installing Android Swift SDK: $ANDROID_SDK_TAG " 
554+ 
555+     local  android_sdk_name=" ${ANDROID_SDK_TAG} _android${ANDROID_SDK_PATH_SUFFIX} " 
556+     local  android_sdk_bundle_name=" ${android_sdk_name} .artifactbundle" 
557+     #  TODO: remove once the next nightly changes the "-" to "_" in the name 
558+     local  android_sdk_bundle_dir=" ${android_sdk_bundle_name// _android/ ${ANDROID_SDK_PATH_SEP} android} " 
559+     local  android_sdk_filename=" ${android_sdk_bundle_name} .tar.gz" 
560+     local  sdk_url=" ${ANDROID_SDK_DOWNLOAD_ROOT} /${ANDROID_SDK_TAG} /${android_sdk_filename} " 
561+ 
562+     log " Running: ${SWIFT_EXECUTABLE_FOR_ANDROID_SDK}  sdk install ${sdk_url}  --checksum ${ANDROID_SDK_CHECKSUM} " 
563+ 
564+     if  " $SWIFT_EXECUTABLE_FOR_ANDROID_SDK " " $sdk_url " " $ANDROID_SDK_CHECKSUM " ;  then 
565+         log " ✅ Android Swift SDK installed successfully" 
566+     else 
567+         fatal " Failed to install Android Swift SDK" 
568+     fi 
569+ 
570+     #  now setup the link to the local ANDROID_NDK_HOME
571+     swift sdk configure --show-configuration " $( swift sdk list |  grep android |  tail -n 1) " 
572+ 
573+     #  guess some common places where the swift-sdks file lives
574+     cd  ~ /Library/org.swift.swiftpm ||  cd  ~ /.config/swiftpm ||  cd  ~ /.local/swiftpm ||  cd  ~ /.swiftpm ||  cd  /root/.swiftpm
575+ 
576+     #  Download and install the Android NDK.
577+     #  Note that we could use the system package manager, but it is
578+     #  named different things for different distributions
579+     #  (e.g., "google-android-ndk-r26-installer" on Debian)
580+     if  [[ !  -d  " ${ANDROID_NDK_HOME:- } " ;  then 
581+         #  permit the "--android-ndk" flag to override the default
582+         local  android_ndk_version=" ${ANDROID_NDK_VERSION:- r27d} " 
583+         curl -fsSL -o ndk.zip --retry 3 https://dl.google.com/android/repository/android-ndk-" ${android_ndk_version} " " $( uname -s) " 
584+         unzip -q ndk.zip
585+         rm ndk.zip
586+         export  ANDROID_NDK_HOME=" ${PWD} " " ${android_ndk_version} " 
587+     fi 
588+ 
589+     ./swift-sdks/" ${android_sdk_bundle_dir} " 
590+     cd  -
591+ }
592+ 
478593install_static_linux_sdk () {
479594    #  Check if the Static Linux Swift SDK is already installed
480595    if  " $SWIFT_EXECUTABLE_FOR_STATIC_LINUX_SDK " 2> /dev/null |  grep -q " ^${STATIC_LINUX_SDK_TAG} _static-linux-0.0.1" ;  then 
@@ -518,6 +633,11 @@ install_wasm_sdk() {
518633}
519634
520635install_sdks () {
636+     if  [[ " $INSTALL_ANDROID " ==  true  ]];  then 
637+         log " Starting install of Swift ${SWIFT_VERSION_INPUT}  Android Swift SDK" 
638+         install_android_sdk
639+     fi 
640+ 
521641    if  [[ " $INSTALL_STATIC_LINUX " ==  true  ]];  then 
522642        log " Starting install of Swift ${SWIFT_VERSION_INPUT}  Static Linux Swift SDK" 
523643        install_static_linux_sdk
@@ -533,6 +653,31 @@ build() {
533653    #  Enable alias expansion to use a 'swift' alias for the executable path
534654    shopt  -s expand_aliases
535655
656+     if  [[ " $INSTALL_ANDROID " ==  true  ]];  then 
657+         log " Running Swift build with Android Swift SDK" 
658+ 
659+         local  sdk_name=" ${ANDROID_SDK_TAG}${ANDROID_SDK_PATH_SEP} android${ANDROID_SDK_PATH_SUFFIX} " 
660+ 
661+         alias  swift=' $SWIFT_EXECUTABLE_FOR_ANDROID_SDK' 
662+         local  build_command=" $SWIFT_BUILD_COMMAND  --swift-sdk ${ANDROID_SDK_TRIPLE:- $sdk_name } " 
663+         if  [[ -n  " $SWIFT_BUILD_FLAGS " ;  then 
664+             build_command=" $build_command  $SWIFT_BUILD_FLAGS " 
665+         fi 
666+ 
667+         log " Running: $build_command " 
668+ 
669+         #  clear the ANDROID_NDK_ROOT environment variable if it is set
670+         #  due to https://github.com/swiftlang/swift-driver/pull/1879
671+         #  otherwise build error: missing required module 'SwiftAndroid'
672+         export  ANDROID_NDK_ROOT=" " 
673+ 
674+         if  eval  " $build_command " ;  then 
675+             log " ✅ Swift build with Android Swift SDK completed successfully" 
676+         else 
677+             fatal " Swift build with Android Swift SDK failed" 
678+         fi 
679+     fi 
680+ 
536681    if  [[ " $INSTALL_STATIC_LINUX " ==  true  ]];  then 
537682        log " Running Swift build with Static Linux Swift SDK" 
538683
0 commit comments