@@ -1370,6 +1370,12 @@ impl Build {
1370
1370
cmd. push_opt_unless_duplicate ( format ! ( "-O{}" , opt_level) . into ( ) ) ;
1371
1371
}
1372
1372
1373
+ if cmd. family == ToolFamily :: Clang && target. contains ( "android" ) {
1374
+ for arg in defines_for_android_compiler ( & cmd. path ) . into_iter ( ) {
1375
+ cmd. push_cc_arg ( arg. into ( ) ) ;
1376
+ }
1377
+ }
1378
+
1373
1379
if !target. contains ( "-ios" ) {
1374
1380
cmd. push_cc_arg ( "-ffunction-sections" . into ( ) ) ;
1375
1381
cmd. push_cc_arg ( "-fdata-sections" . into ( ) ) ;
@@ -1974,29 +1980,7 @@ impl Build {
1974
1980
format ! ( "{}.exe" , gnu)
1975
1981
}
1976
1982
} else if target. contains ( "android" ) {
1977
- let target = target
1978
- . replace ( "armv7neon" , "arm" )
1979
- . replace ( "armv7" , "arm" )
1980
- . replace ( "thumbv7neon" , "arm" )
1981
- . replace ( "thumbv7" , "arm" ) ;
1982
- let gnu_compiler = format ! ( "{}-{}" , target, gnu) ;
1983
- let clang_compiler = format ! ( "{}-{}" , target, clang) ;
1984
- // On Windows, the Android clang compiler is provided as a `.cmd` file instead
1985
- // of a `.exe` file. `std::process::Command` won't run `.cmd` files unless the
1986
- // `.cmd` is explicitly appended to the command name, so we do that here.
1987
- let clang_compiler_cmd = format ! ( "{}-{}.cmd" , target, clang) ;
1988
-
1989
- // Check if gnu compiler is present
1990
- // if not, use clang
1991
- if Command :: new ( & gnu_compiler) . output ( ) . is_ok ( ) {
1992
- gnu_compiler
1993
- } else if host. contains ( "windows" )
1994
- && Command :: new ( & clang_compiler_cmd) . output ( ) . is_ok ( )
1995
- {
1996
- clang_compiler_cmd
1997
- } else {
1998
- clang_compiler
1999
- }
1983
+ autodetect_android_compiler ( & target, & host, gnu, clang)
2000
1984
} else if target. contains ( "cloudabi" ) {
2001
1985
format ! ( "{}-{}" , target, traditional)
2002
1986
} else if target == "wasm32-wasi"
@@ -2722,3 +2706,77 @@ fn command_add_output_file(
2722
2706
cmd. arg ( "-o" ) . arg ( & dst) ;
2723
2707
}
2724
2708
}
2709
+
2710
+ static NEW_STANDALONE_ANDROID_COMPILERS : [ & str ; 4 ] = [
2711
+ "aarch64-linux-android21-clang" ,
2712
+ "armv7a-linux-androideabi16-clang" ,
2713
+ "i686-linux-android16-clang" ,
2714
+ "x86_64-linux-android21-clang" ,
2715
+ ] ;
2716
+
2717
+ fn defines_for_android_compiler ( clang_path : & Path ) -> Vec < & ' static str > {
2718
+ match NEW_STANDALONE_ANDROID_COMPILERS . iter ( ) . find ( |x| {
2719
+ let x: & OsStr = x. as_ref ( ) ;
2720
+ x == clang_path. as_os_str ( )
2721
+ } ) {
2722
+ Some ( new_clang) => {
2723
+ let mut ret = Vec :: with_capacity ( 2 ) ;
2724
+ ret. push ( "-DANDROID" ) ;
2725
+ if new_clang. contains ( "android21" ) {
2726
+ ret. push ( "-D__ANDROID_API__=21" ) ;
2727
+ } else if new_clang. contains ( "android16" ) || new_clang. contains ( "androideabi16" ) {
2728
+ ret. push ( "-D__ANDROID_API__=16" ) ;
2729
+ }
2730
+
2731
+ ret
2732
+ }
2733
+ None => Vec :: new ( ) ,
2734
+ }
2735
+ }
2736
+
2737
+ fn autodetect_android_compiler ( target : & str , host : & str , gnu : & str , clang : & str ) -> String {
2738
+ let new_clang_key = match target {
2739
+ "aarch64-linux-android" => Some ( "aarch64" ) ,
2740
+ "armv7-linux-androideabi" => Some ( "armv7a" ) ,
2741
+ "i686-linux-android" => Some ( "i686" ) ,
2742
+ "x86_64-linux-android" => Some ( "x86_64" ) ,
2743
+ _ => None ,
2744
+ } ;
2745
+
2746
+ let new_clang = new_clang_key
2747
+ . map ( |key| {
2748
+ NEW_STANDALONE_ANDROID_COMPILERS
2749
+ . iter ( )
2750
+ . find ( |x| x. starts_with ( key) )
2751
+ } )
2752
+ . unwrap_or ( None ) ;
2753
+
2754
+ if let Some ( new_clang) = new_clang {
2755
+ if Command :: new ( new_clang) . output ( ) . is_ok ( ) {
2756
+ return ( * new_clang) . into ( ) ;
2757
+ }
2758
+ }
2759
+
2760
+ let target = target
2761
+ . replace ( "armv7neon" , "arm" )
2762
+ . replace ( "armv7" , "arm" )
2763
+ . replace ( "thumbv7neon" , "arm" )
2764
+ . replace ( "thumbv7" , "arm" ) ;
2765
+ let gnu_compiler = format ! ( "{}-{}" , target, gnu) ;
2766
+ let clang_compiler = format ! ( "{}-{}" , target, clang) ;
2767
+
2768
+ // On Windows, the Android clang compiler is provided as a `.cmd` file instead
2769
+ // of a `.exe` file. `std::process::Command` won't run `.cmd` files unless the
2770
+ // `.cmd` is explicitly appended to the command name, so we do that here.
2771
+ let clang_compiler_cmd = format ! ( "{}-{}.cmd" , target, clang) ;
2772
+
2773
+ // Check if gnu compiler is present
2774
+ // if not, use clang
2775
+ if Command :: new ( & gnu_compiler) . output ( ) . is_ok ( ) {
2776
+ gnu_compiler
2777
+ } else if host. contains ( "windows" ) && Command :: new ( & clang_compiler_cmd) . output ( ) . is_ok ( ) {
2778
+ clang_compiler_cmd
2779
+ } else {
2780
+ clang_compiler
2781
+ }
2782
+ }
0 commit comments