Skip to content

Commit 7d44e35

Browse files
committed
Initial commit.
0 parents  commit 7d44e35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1299
-0
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.git
2+
LICENSE
3+
*.md
4+
docker-*.sh

Dockerfile

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
FROM debian:bullseye-slim
2+
3+
RUN apt-get update \
4+
&& apt-get install -y \
5+
wget \
6+
unzip \
7+
build-essential \
8+
openjdk-11-jdk-headless \
9+
libgl1-mesa-dri \
10+
libgl1-mesa-glx \
11+
libpulse0 \
12+
libasound2 \
13+
libxcomposite1 \
14+
libxcursor1 \
15+
libxdamage1 \
16+
libxi6 \
17+
libxtst6 \
18+
--no-install-recommends \
19+
&& rm -rf /var/lib/apt/lists/*
20+
21+
RUN useradd --uid 1000 --create-home --shell /bin/bash dev
22+
# For some reason the host adds the USB device to the 46(plugdev) group. Being
23+
# member of this group is enough to have rw access to the USB device and run
24+
# adb.
25+
RUN groupadd --gid 106 --system kvm \
26+
&& usermod --groups 46,106 dev
27+
28+
USER dev
29+
WORKDIR "/home/dev"
30+
31+
# Install Gradle manually. The Debian package is too outdated.
32+
ENV GRADLE_ROOT=/home/dev/opt/gradle
33+
34+
RUN mkdir -p ${GRADLE_ROOT}
35+
RUN wget https://services.gradle.org/distributions/gradle-7.5.1-bin.zip -O gradle-7.5.1-bin.zip \
36+
&& sha256sum gradle-7.5.1-bin.zip \
37+
&& echo "f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 gradle-7.5.1-bin.zip" | sha256sum -c - \
38+
&& unzip gradle-7.5.1-bin.zip -d ${GRADLE_ROOT} \
39+
&& rm gradle-7.5.1-bin.zip
40+
41+
ENV PATH=${PATH}:${GRADLE_ROOT}/gradle-7.5.1/bin
42+
43+
# Set the ${ANDROID_HOME} variable, so that the tools can find our installation.
44+
# See https://developer.android.com/studio/command-line/variables#envar.
45+
ENV ANDROID_HOME=/home/dev/opt/android-sdk
46+
47+
RUN mkdir -p ${ANDROID_HOME}
48+
RUN wget https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip \
49+
-O ${HOME}/commandlinetools-linux-8512546_latest.zip \
50+
&& sha256sum commandlinetools-linux-8512546_latest.zip \
51+
&& echo "2ccbda4302db862a28ada25aa7425d99dce9462046003c1714b059b5c47970d8 commandlinetools-linux-8512546_latest.zip" | sha256sum -c - \
52+
&& unzip commandlinetools-linux-8512546_latest.zip -d ${ANDROID_HOME}/cmdline-tools \
53+
&& rm commandlinetools-linux-8512546_latest.zip
54+
55+
ENV PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/cmdline-tools/bin:${ANDROID_HOME}/platform-tools
56+
57+
# Given the following configuration in `build.gradle`:
58+
# classpath 'com.android.tools.build:gradle:7.3.0'
59+
# the build tools version to use is 30.0.3.
60+
# See https://mvnrepository.com/artifact/com.android.tools.build/gradle/7.3.0.
61+
RUN yes | sdkmanager --licenses \
62+
&& sdkmanager --list \
63+
&& sdkmanager --verbose \
64+
"build-tools;30.0.3" \
65+
"ndk;25.1.8937393" \
66+
"platforms;android-33" \
67+
"system-images;android-29;default;x86_64" \
68+
&& rm -R ${HOME}/.android/
69+
RUN sdkmanager --list_installed
70+
71+
RUN cd ${HOME}/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/ \
72+
&& ln -s aarch64-linux-android30-clang aarch64-linux-android-clang \
73+
&& ln -s armv7a-linux-androideabi30-clang arm-linux-androideabi-clang \
74+
&& ln -s i686-linux-android30-clang i686-linux-android-clang \
75+
&& ln -s x86_64-linux-android30-clang x86_64-linux-android-clang
76+
77+
# Replace the Android emulator by a custom one (version 31.3.11 from the
78+
# archive at https://developer.android.com/studio/emulator_archive). Indeed,
79+
# from version 31.3.12 on, the disk size is too big and doesn't fit in a
80+
# reasonably-sized tmpfs.
81+
#
82+
# See https://developer.android.com/studio/releases/emulator#31-3-12.
83+
RUN rm -R ${ANDROID_HOME}/emulator \
84+
&& wget https://redirector.gvt1.com/edgedl/android/repository/emulator-linux_x64-9058569.zip \
85+
-O ${HOME}/emulator-linux_x64-9058569.zip \
86+
&& sha256sum emulator-linux_x64-9058569.zip \
87+
&& echo "5b06dae2b8c79b0a39456c3b4d31cf1895571bbf9763cc8ba84c8fdae15673e8 emulator-linux_x64-9058569.zip" | sha256sum -c - \
88+
&& yes | unzip emulator-linux_x64-9058569.zip -d ${ANDROID_HOME} \
89+
&& rm emulator-linux_x64-9058569.zip
90+
91+
USER root
92+
COPY emulator-package.xml /home/dev/opt/android-sdk/emulator/package.xml
93+
USER dev
94+
95+
# Create an Android virtual device.
96+
RUN avdmanager create avd \
97+
-n test_avd \
98+
-d pixel \
99+
-k "system-images;android-29;default;x86_64" \
100+
&& mv ${HOME}/.android ${HOME}/android
101+
102+
# Install Rust toolchain.
103+
ENV NDK_HOME=${ANDROID_HOME}/ndk/25.1.8937393
104+
105+
RUN wget https://sh.rustup.rs -O rustup.sh \
106+
&& sha256sum rustup.sh \
107+
&& echo "173f4881e2de99ba9ad1acb59e65be01b2a44979d83b6ec648d0d22f8654cbce rustup.sh" | sha256sum -c - \
108+
&& sh rustup.sh -y \
109+
&& rm rustup.sh \
110+
&& rm .profile \
111+
&& ${HOME}/.cargo/bin/rustup target add \
112+
aarch64-linux-android \
113+
armv7-linux-androideabi \
114+
i686-linux-android \
115+
x86_64-linux-android \
116+
&& ${HOME}/.cargo/bin/rustup toolchain install nightly \
117+
&& ${HOME}/.cargo/bin/rustup target add --toolchain nightly \
118+
aarch64-linux-android \
119+
armv7-linux-androideabi \
120+
i686-linux-android \
121+
x86_64-linux-android
122+
123+
ENV PATH=${PATH}:/home/dev/.cargo/bin
124+
125+
USER root
126+
127+
COPY \
128+
strip-rust.sh \
129+
script-rust-default.sh \
130+
script-rust-default-nostrip.sh \
131+
script-rust-nightly.sh \
132+
script-rust-nightly-nostrip.sh \
133+
script-gradle.sh \
134+
script-java.sh \
135+
script-java-incorrect-arm64.sh \
136+
script-java-incorrect-x86_64.sh \
137+
emulator.sh \
138+
launch-app-debug.sh \
139+
launch-app-release.sh \
140+
/home/dev/
141+
RUN chmod 555 \
142+
/home/dev/strip-rust.sh \
143+
/home/dev/script-rust-default.sh \
144+
/home/dev/script-rust-default-nostrip.sh \
145+
/home/dev/script-rust-nightly.sh \
146+
/home/dev/script-rust-nightly-nostrip.sh \
147+
/home/dev/script-gradle.sh \
148+
/home/dev/script-java.sh \
149+
/home/dev/script-java-incorrect-arm64.sh \
150+
/home/dev/script-java-incorrect-x86_64.sh \
151+
/home/dev/emulator.sh \
152+
/home/dev/launch-app-debug.sh \
153+
/home/dev/launch-app-release.sh
154+
155+
COPY --chown=1000:1000 cargo-config.toml /home/dev/.cargo/config
156+
157+
COPY --chown=1000:1000 src /home/dev/src
158+
159+
USER dev
160+
161+
ENTRYPOINT [ "/bin/bash" ]
162+

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Guillaume Endignoux
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Android Rust example application
2+
3+
This repository is a demonstration of an Android app integrating a native Rust library.
4+
5+
You can find more information in the following blog post: [Compiling Rust libraries for Android apps: a deep dive](https://gendignoux.com/blog/2022/10/24/rust-library-android.html).
6+
7+
## Usage
8+
9+
To build a Docker container containing all the build tools and the demo application, run:
10+
11+
```bash
12+
$ sudo ./docker-build.sh
13+
```
14+
15+
You can then launch this Docker container to build the application.
16+
This comes in various configurations:
17+
18+
- `docker-run-basic.sh`: minimal setup to compile the application within the container.
19+
- `docker-run-emulator.sh`: besides compiling the application, this setup allows to spawn an Android emulator within the container to test this application.
20+
- `docker-run-usb.sh`: besides compiling the application, this setup gives the container access to the USB devices, so that you can install the application on a real device via ADB.
21+
- `docker-run-all.sh`: setup with everything available in the container.
22+
23+
```bash
24+
$ sudo ./docker-run-basic.sh
25+
$ ./script-rust.sh && ./script-java.sh
26+
```
27+
28+
You can build various flavors of the Rust library.
29+
30+
- `script-rust-nightly.sh`: basic script using the nightly Rust toolchain, with stripping of debug symbols enabled.
31+
- `script-rust-nightly-nostrip.sh`: same, but without stripping debug symbols.
32+
- `script-rust-default.sh` and `script-rust-default-nostrip.sh`: using the default Rust toolchain (stable).
33+
34+
Then, multiple ways are provided to build the Java part of the Android app.
35+
36+
- `script-java.sh`: normal build of the Android app.
37+
- `script-java-incorrect-arm64.sh`: Android app built with the ARM-64 library in the wrong folder.
38+
- `script-java-incorrect-x86_64.sh`: Android app built with the x86_64 library in the wrong folder.
39+
40+
You can then spawn an Android emulator with `emulator.sh`, and use the `launch-app-debug.sh` or `launch-app-release.sh` scripts to install+launch the application via ADB to either the emulator or a real device connected via USB.

cargo-config.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[target.aarch64-linux-android]
2+
linker = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang"
3+
4+
[target.armv7-linux-androideabi]
5+
linker = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi30-clang"
6+
7+
[target.i686-linux-android]
8+
linker = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android30-clang"
9+
10+
[target.x86_64-linux-android]
11+
linker = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android30-clang"

docker-build.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
docker build -t android-rust-simd .

docker-run-all.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/sh
2+
docker run \
3+
--rm \
4+
-it \
5+
--cap-drop=all \
6+
--security-opt no-new-privileges \
7+
--read-only \
8+
-u dev \
9+
--memory=3072m \
10+
--memory-swap=3072m \
11+
--memory-swappiness=0 \
12+
--env USER=dev \
13+
--env "DISPLAY=unix${DISPLAY}" \
14+
--env XAUTHORITY=/Xauthority \
15+
--tmpfs /tmp:size=16m \
16+
--tmpfs /home/dev/build:exec,size=512m \
17+
--tmpfs /home/dev/.gradle:exec,size=512m \
18+
--tmpfs /home/dev/.android:size=3072m \
19+
--tmpfs /home/dev/.cargo/registry:size=16m \
20+
--volume /tmp/.X11-unix:/tmp/.X11-unix \
21+
--volume ${HOME}/.Xauthority:/Xauthority:ro \
22+
--device /dev/bus/usb \
23+
--device /dev/dri \
24+
--device /dev/kvm \
25+
android-rust-simd

docker-run-basic.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
docker run \
3+
--rm \
4+
-it \
5+
--cap-drop=all \
6+
--security-opt no-new-privileges \
7+
--read-only \
8+
-u dev \
9+
--memory=3072m \
10+
--memory-swap=3072m \
11+
--memory-swappiness=0 \
12+
--env USER=dev \
13+
--tmpfs /tmp:size=16m \
14+
--tmpfs /home/dev/build:exec,size=512m \
15+
--tmpfs /home/dev/.gradle:exec,size=512m \
16+
--tmpfs /home/dev/.android:size=1m \
17+
--tmpfs /home/dev/.cargo/registry:size=16m \
18+
android-rust-simd

docker-run-emulator.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/sh
2+
docker run \
3+
--rm \
4+
-it \
5+
--cap-drop=all \
6+
--security-opt no-new-privileges \
7+
--read-only \
8+
-u dev \
9+
--memory=3072m \
10+
--memory-swap=3072m \
11+
--memory-swappiness=0 \
12+
--env USER=dev \
13+
--env "DISPLAY=unix${DISPLAY}" \
14+
--env XAUTHORITY=/Xauthority \
15+
--tmpfs /tmp:size=16m \
16+
--tmpfs /home/dev/build:exec,size=512m \
17+
--tmpfs /home/dev/.gradle:exec,size=512m \
18+
--tmpfs /home/dev/.android:size=3072m \
19+
--tmpfs /home/dev/.cargo/registry:size=16m \
20+
--volume /tmp/.X11-unix:/tmp/.X11-unix \
21+
--volume ${HOME}/.Xauthority:/Xauthority:ro \
22+
--device /dev/dri \
23+
--device /dev/kvm \
24+
android-rust-simd

docker-run-usb.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
docker run \
3+
--rm \
4+
-it \
5+
--cap-drop=all \
6+
--security-opt no-new-privileges \
7+
--read-only \
8+
-u dev \
9+
--memory=3072m \
10+
--memory-swap=3072m \
11+
--memory-swappiness=0 \
12+
--env USER=dev \
13+
--tmpfs /tmp:size=16m \
14+
--tmpfs /home/dev/build:exec,size=512m \
15+
--tmpfs /home/dev/.gradle:exec,size=512m \
16+
--tmpfs /home/dev/.android:size=1m \
17+
--tmpfs /home/dev/.cargo/registry:size=16m \
18+
--device /dev/bus/usb \
19+
android-rust-simd

0 commit comments

Comments
 (0)