BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Using Swift to Build Code for Android

Using Swift to Build Code for Android

Leia em Português

This item in japanese

A “Port to Android” pull request that was recently merged into the official Swift repository master branch makes it possible to create simple programs for Android. The pull request added an Android target for Swift stdlib and allows developers to use a Linux environment to cross-compile for Android on the ARMv7 processor.

For the most part, the Swift port to Android was the effort of two developers: Zhuowei Zhang, who started the project at the end of 2015, and Facebook’s Brian Gesiak, who submitted the PR and addressed all feedback that was provided before it was eventually merged into master. Due to the sheer size of the PR, which originally included 54 changed files, the whole process took almost two months from submit to merge.

As mentioned, at the moment it is only possible to cross-compile to Android from a Linux environment. Additionally, the latest version of the Android NDK is required, plus libiconv and libicu libraries built for Android. With those dependencies in place, Swift for Android can be built by invoking:

$ utils/build-script \
  -R \                                           # Build in ReleaseAssert mode.
  -T \                                           # Run all tests.
  --android \                                    # Build for Android.
  --android-deploy-device-path /data/local/tmp \ # Temporary directory on the device where Android tests are run.
  --android-ndk ~/android-ndk-r10e \             # Path to an Android NDK.
  --android-ndk-version 21 \
  --android-icu-uc ~/libicu-android/armeabi-v7a/libicuuc.so \
  --android-icu-uc-include ~/libicu-android/armeabi-v7a/icu/source/common \
  --android-icu-i18n ~/libicu-android/armeabi-v7a/libicui18n.so \
  --android-icu-i18n-include
  ~/libicu-android/armeabi-v7a/icu/source/i18n/

Once the compiler is available, it can be used to create an Android executable:

$ build/Ninja/ReleaseAssert/swift-linux-x86_64/swiftc \                   # The Swift compiler built in the previous step.
    -target armv7-none-linux-androideabi \                                # Targeting android-armv7.
    -sdk ~/android-ndk-r11c/platforms/android-21/arch-arm \               # Use the same NDK path and API version as you used to build the stdlib in the previous step.
    -L ~/android-ndk-r11c/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a \  # Link the Android NDK's libc++ and libgcc.
    -L ~/android-ndk-r11c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9 \
    hello.swift

This can be deployed to a real Android device along with Swift stdlib and Android NDK libc++ using the adb push command:

$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftCore.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftGlibc.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftSwiftOnoneSupport.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftRemoteMirror.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftSwiftExperimental.so /data/local/tmp

$ adb push ~/android-ndk-r11c/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so /data/local/tmp

$ adb push hello /data/local/tmp

Finally, the program can be executed using the adb shell command.

Since this port currently includes only Swift stdlib, there is still a lot of work to do before Swift can be effectively used to create fully-fledged Android apps, i.e. apps that provide a graphical user interface. This could be accomplished in two different ways, either by using some sort of Swift UI framework able to run on Android, or by interfacing with Android Java frameworks. It should be kept in mind, though, that the Swift compiler does not currently include any provisions to make it easier to bridge Swift to Java code as it happens with Objective C code.

Another possibility of using Swift code inside of a real Android app is using JNI/NDK to call Swift code from Java. Zhang also provided a prototype sample app to show how Swift code can be accessed over JNI from an Android Java app.

Rate this Article

Adoption
Style

BT