Skip to content

Commit 9618fe3

Browse files
committed
[docs][Android] Add a "Getting Started" guide
Until now the best instructions on how to get started with Swift on Android were in the original pull request. This spruces those up and places them in the documentation directory.
1 parent 92848eb commit 9618fe3

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

docs/Android.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Getting Started with Swift on Android
2+
3+
The Swift stdlib can be compiled for Android armv7 targets, which makes it
4+
possible to execute Swift code on a mobile device running Android. This guide
5+
explains how to run a simple "Hello, world" program on your Android device.
6+
7+
If you encounter any problems following the instructions below, please file a
8+
bug using https://bugs.swift.org/.
9+
10+
## FAQ
11+
12+
Let's answer a few frequently asked questions right off the bat:
13+
14+
### Does this mean I can write Android applications in Swift?
15+
16+
No. Although the Swift compiler is capable of compiling Swift code that runs
17+
on an Android device, it takes a lot more than just the Swift stdlib to write
18+
an app. You'd need some sort of framework to build a user interface for your
19+
application, which the Swift stdlib does not provide.
20+
21+
Alternatively, one could theoretically call into Java interfaces from Swift,
22+
but unlike as with Objective-C, the Swift compiler does nothing to facilitate
23+
Swift-to-Java bridging.
24+
25+
## Prerequisites
26+
27+
To follow along with this guide, you'll need:
28+
29+
1. A Linux environment capable of building Swift from source. The stdlib is
30+
currently only buildable for Android from a Linux environment. Before
31+
attempting to build for Android, please make sure you are able to build
32+
for Linux by following the instructions in the Swift project README.
33+
2. An Android NDK of version 21 or greater, available to download here:
34+
http://developer.android.com/ndk/downloads/index.html.
35+
3. An Android device with remote debugging enabled. We require remote
36+
debugging in order to deploy built stdlib products to the device. You may
37+
turn on remote debugging by following the official instructions:
38+
https://developer.chrome.com/devtools/docs/remote-debugging.
39+
40+
## "Hello, world" on Android
41+
42+
### 1. Building the Swift Android stdlib dependencies
43+
44+
You may have noticed that, in order to build the Swift stdlib for Linux, you
45+
needed to `apt-get install libicu-dev icu-devtools`. Similarly, building
46+
the Swift stdlib for Android requires the libiconv and libicu libraries.
47+
However, you'll need versions of these libraries that work on Android devices.
48+
49+
To build libiconv and libicu for Android:
50+
51+
1. Ensure you have `curl`, `autoconf`, `automake`, `libtool`, and
52+
`git` installed.
53+
2. Clone the [SwiftAndroid/libiconv-libicu-android](https://github.com/SwiftAndroid/libiconv-libicu-android)
54+
project. From the command-line, run the following command:
55+
`[email protected]:SwiftAndroid/libiconv-libicu-android.git`.
56+
3. From the command-line, run `which ndk-build`. Confirm that the path to
57+
the `ndk-build` executable in the Android NDK you downloaded is displayed.
58+
If not, you may need to add the Android NDK directory to your `PATH`.
59+
4. Enter the `libiconv-libicu-android` directory on the command line, then
60+
run `build.sh`.
61+
5. Confirm that the build script created `armeabi-v7a/icu/source/i18n` and
62+
`armeabi-v7a/icu/source/common` directories within your
63+
`libiconv-libicu-android` directory.
64+
65+
### 2. Building the Swift stdlib for Android
66+
67+
Enter your Swift directory, then run the build script, passing paths to the
68+
Android NDK and libicu/libiconv directories:
69+
70+
```
71+
$ utils/build-script \
72+
-R \ # Build in ReleaseAssert mode.
73+
--android \ # Build for Android.
74+
--android-ndk ~/android-ndk-r10e \ # Path to an Android NDK.
75+
--android-ndk-version 21 \ # The NDK version to use. Must be 21 or greater.
76+
--android-icu-uc ~/libicu-android/armeabi-v7a/libicuuc.so \
77+
--android-icu-uc-include ~/libicu-android/armeabi-v7a/icu/source/common \
78+
--android-icu-i18n ~/libicu-android/armeabi-v7a/libicui18n.so \
79+
--android-icu-i18n-include ~/libicu-android/armeabi-v7a/icu/source/i18n/
80+
```
81+
82+
### 3. Compiling `hello.swift` to run on an Android device
83+
84+
Create a simple Swift file named `hello.swift`:
85+
86+
```swift
87+
print("Hello, Android")
88+
```
89+
90+
Use the built Swift compiler from the previous step to compile a Swift source
91+
file, targeting Android:
92+
93+
```
94+
$ build/Ninja/ReleaseAssert/swift-linux-x86_64/swiftc \ # The Swift compiler built in the previous step.
95+
-target armv7-none-linux-androideabi \ # Targeting android-armv7.
96+
-sdk ~/android-ndk-r10e/platforms/android-21/arch-arm \ # Use the same NDK path and version as you used to build the stdlib in the previous step.
97+
-L ~/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a \ # Link the Android NDK's libc++ and libgcc.
98+
-L ~/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8 \
99+
hello.swift
100+
```
101+
102+
This should produce a `hello` executable in the directory you executed the
103+
command. If you attempt to run this executable using your Linux environment,
104+
you'll see the following error:
105+
106+
```
107+
cannot execute binary file: Exec format error
108+
```
109+
110+
This is exactly the error we want: the executable is built to run on an
111+
Android device--it does not run on Linux. Next, let's deploy it to an Android
112+
device in order to execute it.
113+
114+
### 4. Deploying the build products to the device
115+
116+
You can use the `adb push` command to copy build products from your Linux
117+
environment to your Android device. Verify your device is connected and is
118+
listed when you run the `adb devices` command, then run the following
119+
commands to copy the Swift Android stdlib:
120+
121+
```
122+
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftCore.so /data/local/tmp
123+
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftGlibc.so /data/local/tmp
124+
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftSwiftOnoneSupport.so /data/local/tmp
125+
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftRemoteMirror.so /data/local/tmp
126+
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftSwiftExperimental.so /data/local/tmp
127+
```
128+
129+
In addition, you'll also need to copy the Android NDK's libc++:
130+
131+
```
132+
$ adb push ~/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so /data/local/tmp
133+
```
134+
135+
Finally, you'll need to copy the `hello` executable you built in the
136+
previous step:
137+
```
138+
$ adb push hello /data/local/tmp
139+
```
140+
141+
### 4. Running "Hello, world" on your Android device
142+
143+
You can use the `adb shell` command to execute the `hello` executable on
144+
the Android device:
145+
146+
```
147+
$ adb shell LD_LIBRARY_PATH=/data/local/tmp hello
148+
```
149+
150+
You should see the following output:
151+
152+
```
153+
Hello, Android
154+
```
155+
156+
Congratulations! You've just run your first Swift program on Android.
157+

0 commit comments

Comments
 (0)