use std::collections::HashSet;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process;
use std::process::{Command, Stdio};
fn main() {
let (args, passthrough) = parse_arguments();
let gcc = env::var("CARGO_APK_GCC").unwrap();
let gcc_sysroot = env::var("CARGO_APK_GCC_SYSROOT").unwrap();
let native_app_glue = env::var("CARGO_APK_NATIVE_APP_GLUE").unwrap();
let glue_obj = env::var("CARGO_APK_GLUE_OBJ").unwrap();
let glue_lib = env::var("CARGO_APK_GLUE_LIB").unwrap();
let linker_output = env::var("CARGO_APK_LINKER_OUTPUT").unwrap();
let lib_paths_output = env::var("CARGO_APK_LIB_PATHS_OUTPUT").unwrap();
let libs_output = env::var("CARGO_APK_LIBS_OUTPUT").unwrap();
{
let mut lib_paths = File::create(Path::new(&lib_paths_output)).unwrap();
for lib_path in args.library_path.iter() {
writeln!(lib_paths, "{}", lib_path.to_string_lossy()).unwrap();
}
let mut libs = File::create(Path::new(&libs_output)).unwrap();
for lib in args.shared_libraries.iter() {
writeln!(libs, "{}", lib).unwrap();
}
}
if Command::new(Path::new(&gcc))
.args(&*passthrough)
.arg(native_app_glue)
.arg(glue_obj)
.arg(glue_lib)
.arg("-llog").arg("-landroid") .arg("--sysroot").arg(gcc_sysroot)
.arg("-o").arg(linker_output)
.arg("-shared")
.arg("-Wl,-E")
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status().unwrap().code().unwrap() != 0
{
println!("Error while executing gcc");
process::exit(1);
}
}
struct Args {
library_path: Vec<PathBuf>,
shared_libraries: HashSet<String>,
}
fn parse_arguments() -> (Args, Vec<String>) {
let mut result_library_path = Vec::new();
let mut result_shared_libraries = HashSet::new();
let mut result_passthrough = Vec::new();
let args = env::args();
let mut args = args.skip(1);
loop {
let arg = match args.next() {
Some(arg) => arg,
None => {
let args = Args {
library_path: result_library_path,
shared_libraries: result_shared_libraries,
};
return (args, result_passthrough);
}
};
match &*arg {
"-o" => { args.next(); },
"-L" => {
let path = args.next().expect("-L must be followed by a path");
result_library_path.push(PathBuf::from(path.clone()));
result_passthrough.push(arg);
result_passthrough.push(path);
},
"-l" => {
let name = args.next().expect("-l must be followed by a library name");
result_shared_libraries.insert(vec!["lib", &name, ".so"].concat());
result_passthrough.push(arg);
result_passthrough.push(name);
}
_ => {
if arg.starts_with("-l") {
result_shared_libraries.insert(vec!["lib", &arg[2..], ".so"].concat());
}
result_passthrough.push(arg);
}
};
}
}