Skip to content

Commit 9174a46

Browse files
committed
Merge pull request #2184 from modocache/android-documentation
[docs][Android] Add a "Getting Started" guide
2 parents 1b6ad50 + 9618fe3 commit 9174a46

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)