@@ -2096,6 +2096,40 @@ impl Build {
20962096 tool
20972097 } ;
20982098
2099+ // New "standalone" C/C++ cross-compiler executables from recent Android NDK
2100+ // are just shell scripts that call main clang binary (from Android NDK) with
2101+ // proper `--target` argument.
2102+ //
2103+ // For example, armv7a-linux-androideabi16-clang passes
2104+ // `--target=armv7a-linux-androideabi16` to clang.
2105+ //
2106+ // As the shell script calls the main clang binary, the command line limit length
2107+ // on Windows is restricted to around 8k characters instead of around 32k characters.
2108+ // To remove this limit, we call the main clang binary directly and contruct the
2109+ // `--target=` ourselves.
2110+ if host. contains ( "windows" ) && android_clang_compiler_uses_target_arg_internally ( & tool. path )
2111+ {
2112+ if let Some ( path) = tool. path . file_name ( ) {
2113+ let file_name = path. to_str ( ) . unwrap ( ) . to_owned ( ) ;
2114+ let ( target, clang) = file_name. split_at ( file_name. rfind ( "-" ) . unwrap ( ) ) ;
2115+
2116+ tool. path . set_file_name ( clang. trim_start_matches ( "-" ) ) ;
2117+ tool. path . set_extension ( "exe" ) ;
2118+ tool. args . push ( format ! ( "--target={}" , target) . into ( ) ) ;
2119+
2120+ // Additionally, shell scripts for target i686-linux-android versions 16 to 24
2121+ // pass the `mstackrealign` option so we do that here as well.
2122+ if target. contains ( "i686-linux-android" ) {
2123+ let ( _, version) = target. split_at ( target. rfind ( "d" ) . unwrap ( ) + 1 ) ;
2124+ if let Ok ( version) = version. parse :: < u32 > ( ) {
2125+ if version > 15 && version < 25 {
2126+ tool. args . push ( "-mstackrealign" . into ( ) ) ;
2127+ }
2128+ }
2129+ }
2130+ } ;
2131+ }
2132+
20992133 // If we found `cl.exe` in our environment, the tool we're returning is
21002134 // an MSVC-like tool, *and* no env vars were set then set env vars for
21012135 // the tool that we're returning.
0 commit comments