Skip to content

Commit df91e66

Browse files
committed
Initial commit
1 parent 4e622d8 commit df91e66

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

src/lib.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::os;
2+
use std::io::Command;
3+
use std::io::process::InheritFd;
4+
5+
/// Compile a library from the given set of input C files.
6+
///
7+
/// This will simply compile all files into object files and then assemble them
8+
/// into the output. This will read the standard environment variables to detect
9+
/// cross compilations and such.
10+
///
11+
/// # Example
12+
///
13+
/// ```
14+
/// gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]);
15+
/// ```
16+
pub fn compile_library(output: &str, files: &[&str]) {
17+
assert!(output.starts_with("lib"));
18+
assert!(output.ends_with(".a"));
19+
20+
let target = os::getenv("TARGET").unwrap();
21+
let opt_level = os::getenv("OPT_LEVEL").unwrap();
22+
23+
let mut cmd = Command::new(gcc());
24+
cmd.arg(format!("-O{}", opt_level));
25+
cmd.arg("-c");
26+
cmd.arg("-ffunction-sections").arg("-fdata-sections");
27+
cmd.args(cflags().as_slice());
28+
29+
if target.as_slice().contains("i686") {
30+
cmd.arg("-m32");
31+
} else if target.as_slice().contains("x86_64") {
32+
cmd.arg("-m64");
33+
}
34+
35+
let src = Path::new(os::getenv("CARGO_MANIFEST_DIR").unwrap());
36+
let dst = Path::new(os::getenv("OUT_DIR").unwrap());
37+
let mut objects = Vec::new();
38+
for file in files.iter() {
39+
let obj = dst.join(*file).with_extension("o");
40+
run(cmd.clone().arg(src.join(*file)).arg("-o").arg(&obj));
41+
objects.push(obj);
42+
}
43+
44+
45+
run(Command::new(ar()).arg("crus")
46+
.arg(dst.join(output))
47+
.args(objects.as_slice()));
48+
println!("cargo:rustc-flags=-L {} -l {}",
49+
dst.display(), output.slice(3, output.len() - 2));
50+
}
51+
52+
fn run(cmd: &mut Command) {
53+
println!("running: {}", cmd);
54+
assert!(cmd.stdout(InheritFd(1))
55+
.stderr(InheritFd(2))
56+
.status()
57+
.unwrap()
58+
.success());
59+
60+
}
61+
62+
fn gcc() -> String {
63+
os::getenv("CC").unwrap_or(if cfg!(windows) {
64+
"gcc".to_string()
65+
} else {
66+
"cc".to_string()
67+
})
68+
}
69+
70+
fn ar() -> String {
71+
os::getenv("AR").unwrap_or("ar".to_string())
72+
}
73+
74+
fn cflags() -> Vec<String> {
75+
os::getenv("CFLAGS").unwrap_or(String::new())
76+
.as_slice().words().map(|s| s.to_string())
77+
.collect()
78+
}

0 commit comments

Comments
 (0)