1
1
use std:: env;
2
+ use std:: path:: Path ;
2
3
3
4
fn main ( ) {
4
5
println ! ( "cargo:rerun-if-changed=build.rs" ) ;
@@ -20,7 +21,6 @@ fn main() {
20
21
21
22
println ! ( "cargo:rustc-check-cfg=cfg(restricted_std)" ) ;
22
23
if target_os == "linux"
23
- || target_os == "android"
24
24
|| target_os == "netbsd"
25
25
|| target_os == "dragonfly"
26
26
|| target_os == "openbsd"
@@ -58,6 +58,9 @@ fn main() {
58
58
|| env:: var ( "RUSTC_BOOTSTRAP_SYNTHETIC_TARGET" ) . is_ok ( )
59
59
{
60
60
// These platforms don't have any special requirements.
61
+ } else if target_os == "android" {
62
+ // If ANDROID_API >= 21, enable `dl_iterate_phdr` feature.
63
+ build_android ( ) ;
61
64
} else {
62
65
// This is for Cargo's build-std support, to mark std as unstable for
63
66
// typically no_std platforms.
@@ -183,3 +186,45 @@ fn main() {
183
186
println ! ( "cargo:rustc-cfg=reliable_f128_math" ) ;
184
187
}
185
188
}
189
+
190
+ fn build_android ( ) {
191
+ // Used to detect the value of the `__ANDROID_API__`
192
+ // builtin #define
193
+ const MARKER : & str = "BACKTRACE_RS_ANDROID_APIVERSION" ;
194
+ const ANDROID_API_C : & str = "
195
+ BACKTRACE_RS_ANDROID_APIVERSION __ANDROID_API__
196
+ " ;
197
+
198
+ // Create `android-api.c` on demand.
199
+ let out_dir = env:: var_os ( "OUT_DIR" ) . unwrap ( ) ;
200
+ let android_api_c = Path :: new ( & out_dir) . join ( "android-api.c" ) ;
201
+ std:: fs:: write ( & android_api_c, ANDROID_API_C ) . unwrap ( ) ;
202
+
203
+ let expansion = match cc:: Build :: new ( ) . file ( & android_api_c) . try_expand ( ) {
204
+ Ok ( result) => result,
205
+ Err ( e) => {
206
+ eprintln ! ( "warning: android version detection failed while running C compiler: {e}" ) ;
207
+ return ;
208
+ }
209
+ } ;
210
+ let expansion = match std:: str:: from_utf8 ( & expansion) {
211
+ Ok ( s) => s,
212
+ Err ( _) => return ,
213
+ } ;
214
+ eprintln ! ( "expanded android version detection:\n {expansion}" ) ;
215
+ let i = match expansion. find ( MARKER ) {
216
+ Some ( i) => i,
217
+ None => return ,
218
+ } ;
219
+ let version = match expansion[ i + MARKER . len ( ) + 1 ..] . split_whitespace ( ) . next ( ) {
220
+ Some ( s) => s,
221
+ None => return ,
222
+ } ;
223
+ let version = match version. parse :: < u32 > ( ) {
224
+ Ok ( n) => n,
225
+ Err ( _) => return ,
226
+ } ;
227
+ if version >= 21 {
228
+ println ! ( "cargo:rustc-cfg=feature=\" dl_iterate_phdr\" " ) ;
229
+ }
230
+ }
0 commit comments