-
Notifications
You must be signed in to change notification settings - Fork 459
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4e622d8
commit df91e66
Showing
1 changed file
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use std::os; | ||
use std::io::Command; | ||
use std::io::process::InheritFd; | ||
|
||
/// Compile a library from the given set of input C files. | ||
/// | ||
/// This will simply compile all files into object files and then assemble them | ||
/// into the output. This will read the standard environment variables to detect | ||
/// cross compilations and such. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]); | ||
/// ``` | ||
pub fn compile_library(output: &str, files: &[&str]) { | ||
assert!(output.starts_with("lib")); | ||
assert!(output.ends_with(".a")); | ||
|
||
let target = os::getenv("TARGET").unwrap(); | ||
let opt_level = os::getenv("OPT_LEVEL").unwrap(); | ||
|
||
let mut cmd = Command::new(gcc()); | ||
cmd.arg(format!("-O{}", opt_level)); | ||
cmd.arg("-c"); | ||
cmd.arg("-ffunction-sections").arg("-fdata-sections"); | ||
cmd.args(cflags().as_slice()); | ||
|
||
if target.as_slice().contains("i686") { | ||
cmd.arg("-m32"); | ||
} else if target.as_slice().contains("x86_64") { | ||
cmd.arg("-m64"); | ||
} | ||
|
||
let src = Path::new(os::getenv("CARGO_MANIFEST_DIR").unwrap()); | ||
let dst = Path::new(os::getenv("OUT_DIR").unwrap()); | ||
let mut objects = Vec::new(); | ||
for file in files.iter() { | ||
let obj = dst.join(*file).with_extension("o"); | ||
run(cmd.clone().arg(src.join(*file)).arg("-o").arg(&obj)); | ||
objects.push(obj); | ||
} | ||
|
||
|
||
run(Command::new(ar()).arg("crus") | ||
.arg(dst.join(output)) | ||
.args(objects.as_slice())); | ||
println!("cargo:rustc-flags=-L {} -l {}", | ||
dst.display(), output.slice(3, output.len() - 2)); | ||
} | ||
|
||
fn run(cmd: &mut Command) { | ||
println!("running: {}", cmd); | ||
assert!(cmd.stdout(InheritFd(1)) | ||
.stderr(InheritFd(2)) | ||
.status() | ||
.unwrap() | ||
.success()); | ||
|
||
} | ||
|
||
fn gcc() -> String { | ||
os::getenv("CC").unwrap_or(if cfg!(windows) { | ||
"gcc".to_string() | ||
} else { | ||
"cc".to_string() | ||
}) | ||
} | ||
|
||
fn ar() -> String { | ||
os::getenv("AR").unwrap_or("ar".to_string()) | ||
} | ||
|
||
fn cflags() -> Vec<String> { | ||
os::getenv("CFLAGS").unwrap_or(String::new()) | ||
.as_slice().words().map(|s| s.to_string()) | ||
.collect() | ||
} |