Skip to content

Commit 7839a41

Browse files
committed
Add build support for android aarch64 and armv7.
1 parent 78d0ba9 commit 7839a41

File tree

1 file changed

+109
-11
lines changed

1 file changed

+109
-11
lines changed

fftw-src/build.rs

Lines changed: 109 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anyhow::Result;
2-
use std::env::{var, set_var};
2+
use cc;
3+
use std::env::{set_var, var};
34
use std::fs::{canonicalize, File};
45
use std::io::{copy, Write};
56
use std::path::{Path, PathBuf};
@@ -95,10 +96,16 @@ fn run(command: &mut Command) -> String {
9596
match command.output() {
9697
Ok(output) => {
9798
if !output.status.success() {
98-
panic!("`{:?}` failed: {}", command, output.status);
99+
panic!(
100+
"`{:?}` failed: {}\nstdout:\n{}\nstderr:\n{}",
101+
command,
102+
output.status,
103+
unsafe { String::from_utf8_unchecked(output.stdout) },
104+
unsafe { String::from_utf8_unchecked(output.stderr) }
105+
);
99106
}
100-
return String::from_utf8(output.stdout).unwrap()
101-
},
107+
return String::from_utf8(output.stdout).unwrap();
108+
}
102109
Err(error) => {
103110
panic!("failed to execute `{:?}`: {}", command, error);
104111
}
@@ -121,18 +128,109 @@ fn main() {
121128
};
122129
match target_os.as_ref() {
123130
"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);
130144
println!("cargo:rustc-link-search={}", out_dir.join("lib").display());
131145
println!("cargo:rustc-link-lib=static=fftw3");
132146
println!("cargo:rustc-link-lib=static=fftw3f");
133147
}
134148
"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+
}
136234
"windows" => {
137235
download_archive_windows(&out_dir).unwrap();
138236
println!("cargo:rustc-link-search={}", out_dir.display());

0 commit comments

Comments
 (0)