Skip to content

Commit 94ab4a7

Browse files
authored
Merge pull request #228 from rust-lang/fix-android
android: Probe whether `dl_iterate_phdr` is defined
2 parents 7d93adb + acf613e commit 94ab4a7

File tree

5 files changed

+181
-4
lines changed

5 files changed

+181
-4
lines changed

ci/android-sdk.sh

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env sh
2+
# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
3+
# file at the top-level directory of this distribution and at
4+
# http://rust-lang.org/COPYRIGHT.
5+
#
6+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9+
# option. This file may not be copied, modified, or distributed
10+
# except according to those terms.
11+
12+
set -ex
13+
14+
# Prep the SDK and emulator
15+
#
16+
# Note that the update process requires that we accept a bunch of licenses, and
17+
# we can't just pipe `yes` into it for some reason, so we take the same strategy
18+
# located in https://github.com/appunite/docker by just wrapping it in a script
19+
# which apparently magically accepts the licenses.
20+
21+
SDK=4333796
22+
mkdir sdk
23+
curl --retry 20 https://dl.google.com/android/repository/sdk-tools-linux-${SDK}.zip -O
24+
unzip -q -d sdk sdk-tools-linux-${SDK}.zip
25+
26+
case "$1" in
27+
arm | armv7)
28+
api=24
29+
image="system-images;android-${api};google_apis;armeabi-v7a"
30+
;;
31+
aarch64)
32+
api=24
33+
image="system-images;android-${api};google_apis;arm64-v8a"
34+
;;
35+
i686)
36+
api=28
37+
image="system-images;android-${api};default;x86"
38+
;;
39+
x86_64)
40+
api=28
41+
image="system-images;android-${api};default;x86_64"
42+
;;
43+
*)
44+
echo "invalid arch: $1"
45+
exit 1
46+
;;
47+
esac;
48+
49+
# Try to fix warning about missing file.
50+
# See https://askubuntu.com/a/1078784
51+
mkdir -p /root/.android/
52+
echo '### User Sources for Android SDK Manager' >> /root/.android/repositories.cfg
53+
echo '#Fri Nov 03 10:11:27 CET 2017 count=0' >> /root/.android/repositories.cfg
54+
55+
# Print all available packages
56+
# yes | ./sdk/tools/bin/sdkmanager --list --verbose
57+
58+
# --no_https avoids
59+
# javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
60+
#
61+
# | grep -v = || true removes the progress bar output from the sdkmanager
62+
# which produces an insane amount of output.
63+
yes | ./sdk/tools/bin/sdkmanager --licenses --no_https | grep -v = || true
64+
yes | ./sdk/tools/bin/sdkmanager --no_https \
65+
"emulator" \
66+
"platform-tools" \
67+
"platforms;android-${api}" \
68+
"${image}" | grep -v = || true
69+
70+
echo "no" |
71+
./sdk/tools/bin/avdmanager create avd \
72+
--name "${1}" \
73+
--package "${image}" | grep -v = || true
74+

ci/docker/arm-linux-androideabi/Dockerfile

+21-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1111

1212
COPY android-ndk.sh /
1313
RUN /android-ndk.sh arm
14-
ENV PATH=$PATH:/android-toolchain/bin
14+
WORKDIR /android
15+
COPY android-sdk.sh /android/sdk.sh
16+
RUN ./sdk.sh arm
17+
RUN mv /root/.android /tmp
18+
RUN chmod 777 -R /tmp/.android
19+
RUN chmod 755 /android/sdk/tools/* /android/sdk/emulator/qemu/linux-x86_64/*
20+
ENV PATH=$PATH:/android-toolchain/bin:/android/sdk/platform-tools
1521

1622
# TODO: run tests in an emulator eventually
1723
ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
18-
CARGO_TARGET_ARM_LINUX_ANDROIDEABI_RUNNER="true"
24+
CARGO_TARGET_ARM_LINUX_ANDROIDEABI_RUNNER=/tmp/runtest \
25+
HOME=/tmp
26+
27+
ADD runtest-android.rs /tmp/runtest.rs
28+
ENTRYPOINT [ \
29+
"bash", \
30+
"-c", \
31+
# set SHELL so android can detect a 64bits system, see
32+
# http://stackoverflow.com/a/41789144
33+
"SHELL=/bin/dash /android/sdk/emulator/emulator @arm -no-window & \
34+
/rust/bin/rustc /tmp/runtest.rs -o /tmp/runtest && \
35+
exec \"$@\"", \
36+
"--" \
37+
]

ci/runtest-android.rs

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use std::env;
2+
use std::process::Command;
3+
use std::path::{Path, PathBuf};
4+
5+
fn main() {
6+
let args = env::args_os()
7+
.skip(1)
8+
.filter(|arg| arg != "--quiet")
9+
.collect::<Vec<_>>();
10+
assert_eq!(args.len(), 1);
11+
let test = PathBuf::from(&args[0]);
12+
let dst = Path::new("/data/local/tmp").join(test.file_name().unwrap());
13+
14+
println!("waiting for device to come online...");
15+
let status = Command::new("adb")
16+
.arg("wait-for-device")
17+
.status()
18+
.expect("failed to run: adb wait-for-device");
19+
assert!(status.success());
20+
21+
println!("pushing executable...");
22+
let status = Command::new("adb")
23+
.arg("push")
24+
.arg(&test)
25+
.arg(&dst)
26+
.status()
27+
.expect("failed to run: adb pushr");
28+
assert!(status.success());
29+
30+
println!("executing tests...");
31+
let output = Command::new("adb")
32+
.arg("shell")
33+
.arg(&dst)
34+
.output()
35+
.expect("failed to run: adb shell");
36+
assert!(status.success());
37+
38+
println!("status: {}\nstdout ---\n{}\nstderr ---\n{}",
39+
output.status,
40+
String::from_utf8_lossy(&output.stdout),
41+
String::from_utf8_lossy(&output.stderr));
42+
43+
let stdout = String::from_utf8_lossy(&output.stdout);
44+
stdout.lines().find(|l|
45+
(l.starts_with("PASSED ") && l.contains(" tests")) ||
46+
l.starts_with("test result: ok")
47+
).unwrap_or_else(|| {
48+
panic!("failed to find successful test run");
49+
});
50+
}

crates/backtrace-sys/build.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ fn main() {
5656
build.define("BACKTRACE_SUPPORTS_DATA", "0");
5757

5858
File::create(out_dir.join("config.h")).unwrap();
59-
if !target.contains("apple-ios")
59+
if target.contains("android") {
60+
maybe_enable_dl_iterate_phdr_android(&mut build);
61+
} else if !target.contains("apple-ios")
6062
&& !target.contains("solaris")
6163
&& !target.contains("redox")
62-
&& !target.contains("android")
6364
&& !target.contains("haiku")
6465
&& !target.contains("vxworks")
6566
{
@@ -122,3 +123,32 @@ fn main() {
122123

123124
build.compile("backtrace");
124125
}
126+
127+
// The `dl_iterate_phdr` API was added in Android API 21+ (according to #227),
128+
// so if we can dynamically detect an appropriately configured C compiler for
129+
// that then let's enable the `dl_iterate_phdr` API, otherwise Android just
130+
// won't have any information.
131+
fn maybe_enable_dl_iterate_phdr_android(build: &mut cc::Build) {
132+
let expansion = cc::Build::new().file("src/android-api.c").expand();
133+
let expansion = match std::str::from_utf8(&expansion) {
134+
Ok(s) => s,
135+
Err(_) => return,
136+
};
137+
println!("expanded android version detection:\n{}", expansion);
138+
let marker = "APIVERSION";
139+
let i = match expansion.find(marker) {
140+
Some(i) => i,
141+
None => return,
142+
};
143+
let version = match expansion[i + marker.len() + 1..].split_whitespace().next() {
144+
Some(s) => s,
145+
None => return,
146+
};
147+
let version = match version.parse::<u32>() {
148+
Ok(n) => n,
149+
Err(_) => return,
150+
};
151+
if version >= 21 {
152+
build.define("HAVE_DL_ITERATE_PHDR", "1");
153+
}
154+
}
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Used from the build script to detect the value of the `__ANDROID_API__`
2+
// builtin #define
3+
4+
APIVERSION __ANDROID_API__

0 commit comments

Comments
 (0)