Skip to content

Commit 7216b13

Browse files
committed
Add a way to build the app with a stage 1 Rust compiler.
1 parent e2ff788 commit 7216b13

32 files changed

+936
-13
lines changed

.github/workflows/docker-build.yml

+32-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ jobs:
55
runs-on: ubuntu-latest
66
steps:
77
- uses: actions/checkout@v2
8+
- name: Get some system information
9+
run: |
10+
id;
11+
df;
12+
free;
13+
nproc
814
- name: Docker build
915
run: ./docker-build.sh
10-
- name: Build Android application
16+
- name: Build Android application (nightly Rust)
1117
run: |
1218
docker run \
1319
--rm \
@@ -24,5 +30,30 @@ jobs:
2430
--tmpfs /home/dev/.gradle:exec,size=512m \
2531
--tmpfs /home/dev/.android:size=1m \
2632
--tmpfs /home/dev/.cargo/registry:size=16m \
33+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
2734
--entrypoint /home/dev/build-application.sh \
2835
android-rust-simd
36+
- name: Build Android application (stage 1 Rust)
37+
run: |
38+
mkdir -p rustc-build;
39+
chmod 777 rustc-build;
40+
PWD=`pwd`;
41+
docker run \
42+
--rm \
43+
--cap-drop=all \
44+
--security-opt no-new-privileges \
45+
--read-only \
46+
-u dev \
47+
--memory=5g \
48+
--memory-swap=5g \
49+
--memory-swappiness=0 \
50+
--env USER=dev \
51+
--tmpfs /tmp:size=256m \
52+
--tmpfs /home/dev/build:exec,size=512m \
53+
--tmpfs /home/dev/.gradle:exec,size=512m \
54+
--tmpfs /home/dev/.android:size=1m \
55+
--tmpfs /home/dev/.cargo/registry:size=512m \
56+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
57+
--volume ${PWD}/rustc-build:/home/dev/rustc-build \
58+
--entrypoint /home/dev/build-application-stage1.sh \
59+
android-rust-simd

.github/workflows/format.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ jobs:
1010
- uses: dtolnay/rust-toolchain@nightly
1111
with:
1212
components: rustfmt
13-
- name: Check Rust formatting
13+
- name: Check Rust formatting (android-simd)
1414
run: cargo fmt --verbose --manifest-path src/android-simd/Cargo.toml -- --check
15+
- name: Check Rust formatting (flamedisk)
16+
run: cargo fmt --verbose --manifest-path tools/flamedisk/Cargo.toml -- --check

Dockerfile

+33-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ RUN apt-get update \
55
wget \
66
unzip \
77
build-essential \
8+
python3 \
9+
curl \
10+
cmake \
11+
git \
812
openjdk-11-jdk-headless \
913
libgl1-mesa-dri \
1014
libgl1-mesa-glx \
@@ -32,7 +36,7 @@ WORKDIR "/home/dev"
3236
ENV GRADLE_ROOT=/home/dev/opt/gradle
3337

3438
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 \
39+
RUN wget -nv https://services.gradle.org/distributions/gradle-7.5.1-bin.zip -O gradle-7.5.1-bin.zip \
3640
&& sha256sum gradle-7.5.1-bin.zip \
3741
&& echo "f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 gradle-7.5.1-bin.zip" | sha256sum -c - \
3842
&& unzip gradle-7.5.1-bin.zip -d ${GRADLE_ROOT} \
@@ -45,7 +49,7 @@ ENV PATH=${PATH}:${GRADLE_ROOT}/gradle-7.5.1/bin
4549
ENV ANDROID_HOME=/home/dev/opt/android-sdk
4650

4751
RUN mkdir -p ${ANDROID_HOME}
48-
RUN wget https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip \
52+
RUN wget -nv https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip \
4953
-O ${HOME}/commandlinetools-linux-8512546_latest.zip \
5054
&& sha256sum commandlinetools-linux-8512546_latest.zip \
5155
&& echo "2ccbda4302db862a28ada25aa7425d99dce9462046003c1714b059b5c47970d8 commandlinetools-linux-8512546_latest.zip" | sha256sum -c - \
@@ -81,7 +85,7 @@ RUN cd ${HOME}/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x
8185
#
8286
# See https://developer.android.com/studio/releases/emulator#31-3-12.
8387
RUN rm -R ${ANDROID_HOME}/emulator \
84-
&& wget https://redirector.gvt1.com/edgedl/android/repository/emulator-linux_x64-9058569.zip \
88+
&& wget -nv https://redirector.gvt1.com/edgedl/android/repository/emulator-linux_x64-9058569.zip \
8589
-O ${HOME}/emulator-linux_x64-9058569.zip \
8690
&& sha256sum emulator-linux_x64-9058569.zip \
8791
&& echo "5b06dae2b8c79b0a39456c3b4d31cf1895571bbf9763cc8ba84c8fdae15673e8 emulator-linux_x64-9058569.zip" | sha256sum -c - \
@@ -102,7 +106,7 @@ RUN avdmanager create avd \
102106
# Install Rust toolchain.
103107
ENV NDK_HOME=${ANDROID_HOME}/ndk/25.1.8937393
104108

105-
RUN wget https://sh.rustup.rs -O rustup.sh \
109+
RUN wget -nv https://sh.rustup.rs -O rustup.sh \
106110
&& sha256sum rustup.sh \
107111
&& echo "173f4881e2de99ba9ad1acb59e65be01b2a44979d83b6ec648d0d22f8654cbce rustup.sh" | sha256sum -c - \
108112
&& sh rustup.sh -y \
@@ -118,45 +122,68 @@ RUN wget https://sh.rustup.rs -O rustup.sh \
118122
aarch64-linux-android \
119123
armv7-linux-androideabi \
120124
i686-linux-android \
121-
x86_64-linux-android
125+
x86_64-linux-android \
126+
&& mkdir -p ${HOME}/rustup \
127+
&& mv ${HOME}/.rustup/toolchains ${HOME}/rustup/toolchains
122128

123129
ENV PATH=${PATH}:/home/dev/.cargo/bin
124130

125131
USER root
126132

127133
COPY \
128134
scripts/build-application.sh \
135+
scripts/build-application-stage1.sh \
136+
scripts/setup.sh \
137+
scripts/clone-rustlang-head.sh \
138+
scripts/clone-rustlang-1.67.0-1286ee23e.sh \
139+
scripts/stage0.sh \
140+
scripts/stage1.sh \
129141
scripts/strip-rust.sh \
130142
scripts/script-rust-default.sh \
131143
scripts/script-rust-default-nostrip.sh \
132144
scripts/script-rust-nightly.sh \
133145
scripts/script-rust-nightly-nostrip.sh \
146+
scripts/script-rust-stage1.sh \
147+
scripts/script-rust-stage1-nostrip.sh \
134148
scripts/script-gradle.sh \
135149
scripts/script-java.sh \
136150
scripts/script-java-incorrect-arm64.sh \
137151
scripts/script-java-incorrect-x86_64.sh \
138152
scripts/emulator.sh \
139153
scripts/launch-app-debug.sh \
140154
scripts/launch-app-release.sh \
155+
scripts/flamedisk.sh \
141156
/home/dev/
142157
RUN chmod 555 \
143158
/home/dev/build-application.sh \
159+
/home/dev/build-application-stage1.sh \
160+
/home/dev/setup.sh \
161+
/home/dev/clone-rustlang-head.sh \
162+
/home/dev/clone-rustlang-1.67.0-1286ee23e.sh \
163+
/home/dev/stage0.sh \
164+
/home/dev/stage1.sh \
144165
/home/dev/strip-rust.sh \
145166
/home/dev/script-rust-default.sh \
146167
/home/dev/script-rust-default-nostrip.sh \
147168
/home/dev/script-rust-nightly.sh \
148169
/home/dev/script-rust-nightly-nostrip.sh \
170+
/home/dev/script-rust-stage1.sh \
171+
/home/dev/script-rust-stage1-nostrip.sh \
149172
/home/dev/script-gradle.sh \
150173
/home/dev/script-java.sh \
151174
/home/dev/script-java-incorrect-arm64.sh \
152175
/home/dev/script-java-incorrect-x86_64.sh \
153176
/home/dev/emulator.sh \
154177
/home/dev/launch-app-debug.sh \
155-
/home/dev/launch-app-release.sh
178+
/home/dev/launch-app-release.sh \
179+
/home/dev/flamedisk.sh
156180

157181
COPY --chown=1000:1000 cargo-config.toml /home/dev/.cargo/config
182+
COPY --chown=1000:1000 rustbuild-config.toml /home/dev/
183+
COPY --chown=1000:1000 stdarch.patch /home/dev/
158184

159185
COPY --chown=1000:1000 src /home/dev/src
186+
COPY --chown=1000:1000 tools /home/dev/tools
160187

161188
USER dev
162189

README.md

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
# Android Rust example application
1+
# Android Rust example application with SIMD instructions
22

33
This repository is a demonstration of an Android app integrating a native Rust library.
4+
Additionally, this Rust library demonstrates detecting support for SIMD instructions.
45

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+
You can find more information in the following blog posts:
7+
8+
- [Compiling Rust libraries for Android apps: a deep dive](https://gendignoux.com/blog/2022/10/24/rust-library-android.html),
9+
- [Detecting SIMD support on ARM with Android (and patching the Rust compiler for it)](https://gendignoux.com/blog/2022/11/09/rust-simd-detect-arm-android.md).
610

711
## Usage
812

@@ -29,6 +33,7 @@ You can build various flavors of the Rust library.
2933

3034
- `script-rust-nightly.sh`: basic script using the nightly Rust toolchain, with stripping of debug symbols enabled.
3135
- `script-rust-nightly-nostrip.sh`: same, but without stripping debug symbols.
36+
- `script-rust-stage1.sh` and `script-rust-stage1-nostrip.sh`: using a locally built `stage1` Rust compiler (see below).
3237
- `script-rust-default.sh` and `script-rust-default-nostrip.sh`: using the default Rust toolchain (stable).
3338

3439
Then, multiple ways are provided to build the Java part of the Android app.
@@ -38,3 +43,25 @@ Then, multiple ways are provided to build the Java part of the Android app.
3843
- `script-java-incorrect-x86_64.sh`: Android app built with the x86_64 library in the wrong folder.
3944

4045
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.
46+
47+
## Building and using a patched Rust compiler
48+
49+
This repository also shows how to patch and build the Rust compiler.
50+
You can launch the Docker container in various scenarios:
51+
52+
- `docker-run-rustc-1cpu.sh`: with 1 CPU, 2 GB of RAM,
53+
- `docker-run-rustc-2cpu.sh`: with 2 CPUs, 2 GB of RAM,
54+
- `docker-run-rustc-4cpu.sh`: with 4 CPUs, 3 GB of RAM,
55+
- `docker-run-rustc-8cpu.sh`: with 8 CPUs, 5 GB of RAM,
56+
- `docker-run-all-rustc.sh`: to compile `rustc` + build the app.
57+
58+
Once launched, you can clone and compile `rustc` for Android with:
59+
60+
- `scripts/clone-rustlang-head.sh`: clone the latest commit on the Rust repository,
61+
- `scripts/stage0.sh`: build a stage 0 compiler,
62+
- `scripts/stage1.sh`: build a stage 1 compiler.
63+
64+
You'll also find the following tool to generate a flame graph of the disk space used by a build of `rustc`:
65+
66+
- `tools/flamedisk`: small Rust tool to generate an input suitable for `flamegraph.pl`,
67+
- `scripts/flamedisk.sh`: driver script to generate the flame graph.

docker-run-all-rustc.sh

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/sh
2+
3+
mkdir -p rustc-build
4+
chown 1000:1000 rustc-build
5+
PWD=`pwd`
6+
7+
docker run \
8+
--rm \
9+
-it \
10+
--cap-drop=all \
11+
--security-opt no-new-privileges \
12+
--read-only \
13+
-u dev \
14+
--cpus 8 \
15+
--memory=5g \
16+
--memory-swap=5g \
17+
--memory-swappiness=0 \
18+
--env USER=dev \
19+
--env "DISPLAY=unix${DISPLAY}" \
20+
--tmpfs /tmp:size=256m \
21+
--tmpfs /home/dev/build:exec,size=512m \
22+
--tmpfs /home/dev/.gradle:exec,size=512m \
23+
--tmpfs /home/dev/.android:size=3g \
24+
--tmpfs /home/dev/.cargo/registry:size=512m \
25+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
26+
--volume /tmp/.X11-unix:/tmp/.X11-unix \
27+
--volume ${PWD}/rustc-build:/home/dev/rustc-build \
28+
--device /dev/bus/usb \
29+
--device /dev/dri \
30+
--device /dev/kvm \
31+
android-rust-simd

docker-run-all.sh

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ docker run \
1616
--tmpfs /home/dev/.gradle:exec,size=512m \
1717
--tmpfs /home/dev/.android:size=3g \
1818
--tmpfs /home/dev/.cargo/registry:size=16m \
19+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
1920
--volume /tmp/.X11-unix:/tmp/.X11-unix \
2021
--device /dev/bus/usb \
2122
--device /dev/dri \

docker-run-basic.sh

+1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ docker run \
1515
--tmpfs /home/dev/.gradle:exec,size=512m \
1616
--tmpfs /home/dev/.android:size=1m \
1717
--tmpfs /home/dev/.cargo/registry:size=16m \
18+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
1819
android-rust-simd

docker-run-emulator.sh

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ docker run \
1616
--tmpfs /home/dev/.gradle:exec,size=512m \
1717
--tmpfs /home/dev/.android:size=3g \
1818
--tmpfs /home/dev/.cargo/registry:size=16m \
19+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
1920
--volume /tmp/.X11-unix:/tmp/.X11-unix \
2021
--device /dev/dri \
2122
--device /dev/kvm \

docker-run-rustc-1cpu.sh

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
mkdir -p rustc-build
4+
chown 1000:1000 rustc-build
5+
PWD=`pwd`
6+
7+
docker run \
8+
--rm \
9+
-it \
10+
--cap-drop=all \
11+
--security-opt no-new-privileges \
12+
--read-only \
13+
-u dev \
14+
--cpus 1 \
15+
--memory=2g \
16+
--memory-swap=2g \
17+
--memory-swappiness=0 \
18+
--env USER=dev \
19+
--tmpfs /tmp:size=256m \
20+
--tmpfs /home/dev/.cargo/registry:size=512m \
21+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
22+
--volume $PWD/rustc-build:/home/dev/rustc-build \
23+
android-rust-simd

docker-run-rustc-2cpus.sh

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
mkdir -p rustc-build
4+
chown 1000:1000 rustc-build
5+
PWD=`pwd`
6+
7+
docker run \
8+
--rm \
9+
-it \
10+
--cap-drop=all \
11+
--security-opt no-new-privileges \
12+
--read-only \
13+
-u dev \
14+
--cpus 2 \
15+
--memory=2g \
16+
--memory-swap=2g \
17+
--memory-swappiness=0 \
18+
--env USER=dev \
19+
--tmpfs /tmp:size=256m \
20+
--tmpfs /home/dev/.cargo/registry:size=512m \
21+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
22+
--volume ${PWD}/rustc-build:/home/dev/rustc-build \
23+
android-rust-simd

docker-run-rustc-4cpus.sh

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
mkdir -p rustc-build
4+
chown 1000:1000 rustc-build
5+
PWD=`pwd`
6+
7+
docker run \
8+
--rm \
9+
-it \
10+
--cap-drop=all \
11+
--security-opt no-new-privileges \
12+
--read-only \
13+
-u dev \
14+
--cpus 4 \
15+
--memory=3g \
16+
--memory-swap=3g \
17+
--memory-swappiness=0 \
18+
--env USER=dev \
19+
--tmpfs /tmp:size=256m \
20+
--tmpfs /home/dev/.cargo/registry:size=512m \
21+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
22+
--volume ${PWD}/rustc-build:/home/dev/rustc-build \
23+
android-rust-simd

docker-run-rustc-8cpus.sh

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
mkdir -p rustc-build
4+
chown 1000:1000 rustc-build
5+
PWD=`pwd`
6+
7+
docker run \
8+
--rm \
9+
-it \
10+
--cap-drop=all \
11+
--security-opt no-new-privileges \
12+
--read-only \
13+
-u dev \
14+
--cpus 8 \
15+
--memory=5g \
16+
--memory-swap=5g \
17+
--memory-swappiness=0 \
18+
--env USER=dev \
19+
--tmpfs /tmp:size=256m \
20+
--tmpfs /home/dev/.cargo/registry:size=512m \
21+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
22+
--volume ${PWD}/rustc-build:/home/dev/rustc-build \
23+
android-rust-simd

docker-run-usb.sh

+1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ docker run \
1515
--tmpfs /home/dev/.gradle:exec,size=512m \
1616
--tmpfs /home/dev/.android:size=1m \
1717
--tmpfs /home/dev/.cargo/registry:size=16m \
18+
--tmpfs /home/dev/.rustup/toolchains:exec,size=1m \
1819
--device /dev/bus/usb \
1920
android-rust-simd

rustbuild-config.toml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Includes one of the default files in src/bootstrap/defaults
2+
profile = "library"
3+
changelog-seen = 2
4+
5+
[target.aarch64-linux-android]
6+
android-ndk = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64"
7+
8+
[target.armv7-linux-androideabi]
9+
android-ndk = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64"
10+
11+
[target.i686-linux-android]
12+
android-ndk = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64"
13+
14+
[target.x86_64-linux-android]
15+
android-ndk = "/home/dev/opt/android-sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64"

0 commit comments

Comments
 (0)