1
1
use anyhow:: Result ;
2
- use std:: env:: { var, set_var} ;
2
+ use cc;
3
+ use std:: env:: { set_var, var} ;
3
4
use std:: fs:: { canonicalize, File } ;
4
5
use std:: io:: { copy, Write } ;
5
6
use std:: path:: { Path , PathBuf } ;
@@ -95,10 +96,16 @@ fn run(command: &mut Command) -> String {
95
96
match command. output ( ) {
96
97
Ok ( output) => {
97
98
if !output. status . success ( ) {
98
- panic ! ( "`{:?}` failed: {}" , command, output. status) ;
99
+ panic ! (
100
+ "`{:?}` failed: {}\n stdout:\n {}\n stderr:\n {}" ,
101
+ command,
102
+ output. status,
103
+ unsafe { String :: from_utf8_unchecked( output. stdout) } ,
104
+ unsafe { String :: from_utf8_unchecked( output. stderr) }
105
+ ) ;
99
106
}
100
- return String :: from_utf8 ( output. stdout ) . unwrap ( )
101
- } ,
107
+ return String :: from_utf8 ( output. stdout ) . unwrap ( ) ;
108
+ }
102
109
Err ( error) => {
103
110
panic ! ( "failed to execute `{:?}`: {}" , command, error) ;
104
111
}
@@ -121,18 +128,109 @@ fn main() {
121
128
} ;
122
129
match target_os. as_ref ( ) {
123
130
"ios" => {
124
- let cc = run ( Command :: new ( "xcrun" ) . args ( & [ "--sdk" , "iphoneos" , "-f" , "clang" ] ) ) ;
125
- set_var ( "CC" , cc. trim ( ) ) ;
126
- let sysroot = run ( Command :: new ( "xcrun" ) . args ( & [ "--sdk" , "iphoneos" , "--show-sdk-path" ] ) ) ;
127
- set_var ( "CFLAGS" , format ! ( "-O3 -pipe -isysroot {} -arch {} -miphoneos-version-min=9.0" , sysroot. trim( ) , arch) ) ;
128
- let flags = & [ & format ! ( "--with-sysroot={}" , sysroot. trim( ) ) , "--host=arm-apple-darwin" ] ;
129
- build_unix ( & out_dir, flags) ;
131
+ let tool = cc:: Build :: new ( )
132
+ . target ( & target)
133
+ . flag_if_supported ( & format ! ( "-march={}" , arch) )
134
+ . get_compiler ( ) ;
135
+ set_var ( "CC" , tool. cc_env ( ) ) ;
136
+ set_var ( "CFLAGS" , tool. cflags_env ( ) ) ;
137
+ let sysroot =
138
+ run ( Command :: new ( "xcrun" ) . args ( & [ "--sdk" , "iphoneos" , "--show-sdk-path" ] ) ) ;
139
+ let args = & [
140
+ & format ! ( "--with-sysroot={}" , sysroot. trim( ) ) ,
141
+ "--host=arm-apple-darwin" ,
142
+ ] ;
143
+ build_unix ( & out_dir, args) ;
130
144
println ! ( "cargo:rustc-link-search={}" , out_dir. join( "lib" ) . display( ) ) ;
131
145
println ! ( "cargo:rustc-link-lib=static=fftw3" ) ;
132
146
println ! ( "cargo:rustc-link-lib=static=fftw3f" ) ;
133
147
}
134
148
"android" => {
135
- } ,
149
+ let tool = cc:: Build :: new ( )
150
+ . target ( & target)
151
+ . flag_if_supported ( "-mfloat-abi=softfp" )
152
+ . flag_if_supported ( "-mfpu=neon" )
153
+ . get_compiler ( ) ;
154
+ let mut cc = Command :: new ( tool. cc_env ( ) )
155
+ . arg ( "--version" )
156
+ . status ( )
157
+ . ok ( )
158
+ . and_then ( |status| {
159
+ if status. success ( ) {
160
+ Some ( tool. cc_env ( ) )
161
+ } else {
162
+ None
163
+ }
164
+ } ) ;
165
+ let ndk_root: PathBuf = var ( "ANDROID_NDK_ROOT" )
166
+ . map_err ( |_| var ( "ANDROID_NDK_HOME" ) )
167
+ . expect ( "ndk not found, please set ANDROID_NDK_ROOT to where ndk installed." )
168
+ . into ( ) ;
169
+ let mut sysroot: String = "" . to_string ( ) ;
170
+ if cc. is_none ( ) {
171
+ let host = var ( "HOST" ) . unwrap ( ) ;
172
+ let triple = host. split ( "-" ) . collect :: < Vec < _ > > ( ) ;
173
+ let toolchain = ndk_root
174
+ . join ( "toolchains/llvm/prebuilt" )
175
+ . join ( & format ! ( "{}-{}" , triple[ 2 ] , triple[ 0 ] ) )
176
+ . join ( "bin" ) ;
177
+ if !toolchain. exists ( ) {
178
+ panic ! ( format!(
179
+ "Unsupported platform {}, ndk toolchain dose not exists, {}!" ,
180
+ host,
181
+ toolchain. display( )
182
+ ) ) ;
183
+ } ;
184
+ match target. as_str ( ) {
185
+ "aarch64-linux-android" => {
186
+ set_var ( "AR" , toolchain. join ( "aarch64-linux-android-ar" ) ) ;
187
+ set_var ( "AS" , toolchain. join ( "aarch64-linux-android-as" ) ) ;
188
+ set_var ( "LD" , toolchain. join ( "aarch64-linux-android-ld" ) ) ;
189
+ set_var ( "STRIP" , toolchain. join ( "aarch64-linux-android-strip" ) ) ;
190
+ set_var ( "RANLIB" , toolchain. join ( "aarch64-linux-android-ranlib" ) ) ;
191
+ cc = Some (
192
+ toolchain
193
+ . join ( "aarch64-linux-android21-clang" )
194
+ . into_os_string ( ) ,
195
+ ) ;
196
+ sysroot = format ! (
197
+ "--with-sysroot={}/platforms/android-21/arch-arm64" ,
198
+ ndk_root. display( )
199
+ ) ;
200
+ }
201
+ "armv7-linux-androideabi" => {
202
+ set_var ( "AR" , toolchain. join ( "arm-linux-androideabi-ar" ) ) ;
203
+ set_var ( "AS" , toolchain. join ( "arm-linux-androideabi-as" ) ) ;
204
+ set_var ( "LD" , toolchain. join ( "arm-linux-androideabi-ld" ) ) ;
205
+ set_var ( "STRIP" , toolchain. join ( "arm-linux-androideabi-strip" ) ) ;
206
+ set_var ( "RANLIB" , toolchain. join ( "arm-linux-androideabi-ranlib" ) ) ;
207
+ cc = Some (
208
+ toolchain
209
+ . join ( "armv7a-linux-androideabi21-clang" )
210
+ . into_os_string ( ) ,
211
+ ) ;
212
+ sysroot = format ! (
213
+ "--with-sysroot={}/platforms/android-21/arch-arm" ,
214
+ ndk_root. display( )
215
+ ) ;
216
+ }
217
+ & _ => {
218
+ unimplemented ! ( ) ;
219
+ }
220
+ } ;
221
+ } ;
222
+ set_var ( "CFLAGS" , tool. cflags_env ( ) ) ;
223
+ set_var ( "CC" , cc. unwrap ( ) ) ;
224
+ let cross = format ! ( "--host={}" , target) ;
225
+ if target. starts_with ( "arm" ) {
226
+ build_unix ( & out_dir, & [ cross. as_str ( ) , sysroot. as_str ( ) ] ) ;
227
+ } else {
228
+ build_unix ( & out_dir, & [ cross. as_str ( ) , sysroot. as_str ( ) ] ) ;
229
+ }
230
+ println ! ( "cargo:rustc-link-search={}" , out_dir. join( "lib" ) . display( ) ) ;
231
+ println ! ( "cargo:rustc-link-lib=static=fftw3" ) ;
232
+ println ! ( "cargo:rustc-link-lib=static=fftw3f" ) ;
233
+ }
136
234
"windows" => {
137
235
download_archive_windows ( & out_dir) . unwrap ( ) ;
138
236
println ! ( "cargo:rustc-link-search={}" , out_dir. display( ) ) ;
0 commit comments