aboutsummaryrefslogtreecommitdiff
path: root/gcc/tests
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tests')
-rw-r--r--gcc/tests/cc_env.rs49
-rw-r--r--gcc/tests/support/mod.rs112
-rw-r--r--gcc/tests/test.rs229
3 files changed, 390 insertions, 0 deletions
diff --git a/gcc/tests/cc_env.rs b/gcc/tests/cc_env.rs
new file mode 100644
index 0000000..559dbe8
--- /dev/null
+++ b/gcc/tests/cc_env.rs
@@ -0,0 +1,49 @@
+extern crate tempdir;
+extern crate gcc;
+
+use std::env;
+
+mod support;
+use support::Test;
+
+#[test]
+fn main() {
+ ccache();
+ distcc();
+ ccache_spaces();
+}
+
+fn ccache() {
+ let test = Test::gnu();
+ test.shim("ccache");
+
+ env::set_var("CC", "ccache lol-this-is-not-a-compiler foo");
+ test.gcc().file("foo.c").compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("lol-this-is-not-a-compiler foo")
+ .must_have("foo.c")
+ .must_not_have("ccache");
+}
+
+fn ccache_spaces() {
+ let test = Test::gnu();
+ test.shim("ccache");
+
+ env::set_var("CC", "ccache lol-this-is-not-a-compiler foo");
+ test.gcc().file("foo.c").compile("libfoo.a");
+ test.cmd(0).must_have("lol-this-is-not-a-compiler foo");
+}
+
+fn distcc() {
+ let test = Test::gnu();
+ test.shim("distcc");
+
+ env::set_var("CC", "distcc lol-this-is-not-a-compiler foo");
+ test.gcc().file("foo.c").compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("lol-this-is-not-a-compiler foo")
+ .must_have("foo.c")
+ .must_not_have("distcc");
+}
diff --git a/gcc/tests/support/mod.rs b/gcc/tests/support/mod.rs
new file mode 100644
index 0000000..135a663
--- /dev/null
+++ b/gcc/tests/support/mod.rs
@@ -0,0 +1,112 @@
+#![allow(dead_code)]
+
+use std::env;
+use std::ffi::OsStr;
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::path::PathBuf;
+
+use gcc;
+use tempdir::TempDir;
+
+pub struct Test {
+ pub td: TempDir,
+ pub gcc: PathBuf,
+ pub msvc: bool,
+}
+
+pub struct Execution {
+ args: Vec<String>,
+}
+
+impl Test {
+ pub fn new() -> Test {
+ let mut gcc = PathBuf::from(env::current_exe().unwrap());
+ gcc.pop();
+ if gcc.ends_with("deps") {
+ gcc.pop();
+ }
+ gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX));
+ Test {
+ td: TempDir::new("gcc-test").unwrap(),
+ gcc: gcc,
+ msvc: false,
+ }
+ }
+
+ pub fn gnu() -> Test {
+ let t = Test::new();
+ t.shim("cc").shim("ar");
+ t
+ }
+
+ pub fn msvc() -> Test {
+ let mut t = Test::new();
+ t.shim("cl").shim("lib.exe");
+ t.msvc = true;
+ t
+ }
+
+ pub fn shim(&self, name: &str) -> &Test {
+ let fname = format!("{}{}", name, env::consts::EXE_SUFFIX);
+ fs::hard_link(&self.gcc, self.td.path().join(&fname))
+ .or_else(|_| fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ()))
+ .unwrap();
+ self
+ }
+
+ pub fn gcc(&self) -> gcc::Config {
+ let mut cfg = gcc::Config::new();
+ let mut path = env::split_paths(&env::var_os("PATH").unwrap()).collect::<Vec<_>>();
+ path.insert(0, self.td.path().to_owned());
+ let target = if self.msvc {
+ "x86_64-pc-windows-msvc"
+ } else {
+ "x86_64-unknown-linux-gnu"
+ };
+
+ cfg.target(target)
+ .host(target)
+ .opt_level(2)
+ .debug(false)
+ .out_dir(self.td.path())
+ .__set_env("PATH", env::join_paths(path).unwrap())
+ .__set_env("GCCTEST_OUT_DIR", self.td.path());
+ if self.msvc {
+ cfg.compiler(self.td.path().join("cl"));
+ cfg.archiver(self.td.path().join("lib.exe"));
+ }
+ cfg
+ }
+
+ pub fn cmd(&self, i: u32) -> Execution {
+ let mut s = String::new();
+ File::open(self.td.path().join(format!("out{}", i)))
+ .unwrap()
+ .read_to_string(&mut s)
+ .unwrap();
+ Execution { args: s.lines().map(|s| s.to_string()).collect() }
+ }
+}
+
+impl Execution {
+ pub fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
+ if !self.has(p.as_ref()) {
+ panic!("didn't find {:?} in {:?}", p.as_ref(), self.args);
+ } else {
+ self
+ }
+ }
+
+ pub fn must_not_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
+ if self.has(p.as_ref()) {
+ panic!("found {:?}", p.as_ref());
+ } else {
+ self
+ }
+ }
+
+ pub fn has(&self, p: &OsStr) -> bool {
+ self.args.iter().any(|arg| OsStr::new(arg) == p)
+ }
+}
diff --git a/gcc/tests/test.rs b/gcc/tests/test.rs
new file mode 100644
index 0000000..1c51e09
--- /dev/null
+++ b/gcc/tests/test.rs
@@ -0,0 +1,229 @@
+extern crate gcc;
+extern crate tempdir;
+
+use support::Test;
+
+mod support;
+
+#[test]
+fn gnu_smoke() {
+ let test = Test::gnu();
+ test.gcc()
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("-O2")
+ .must_have("foo.c")
+ .must_not_have("-g")
+ .must_have("-c")
+ .must_have("-ffunction-sections")
+ .must_have("-fdata-sections");
+ test.cmd(1).must_have(test.td.path().join("foo.o"));
+}
+
+#[test]
+fn gnu_opt_level_1() {
+ let test = Test::gnu();
+ test.gcc()
+ .opt_level(1)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("-O1")
+ .must_not_have("-O2");
+}
+
+#[test]
+fn gnu_opt_level_s() {
+ let test = Test::gnu();
+ test.gcc()
+ .opt_level_str("s")
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("-Os")
+ .must_not_have("-O1")
+ .must_not_have("-O2")
+ .must_not_have("-O3")
+ .must_not_have("-Oz");
+}
+
+#[test]
+fn gnu_debug() {
+ let test = Test::gnu();
+ test.gcc()
+ .debug(true)
+ .file("foo.c")
+ .compile("libfoo.a");
+ test.cmd(0).must_have("-g");
+}
+
+#[test]
+fn gnu_x86_64() {
+ for vendor in &["unknown-linux-gnu", "apple-darwin"] {
+ let target = format!("x86_64-{}", vendor);
+ let test = Test::gnu();
+ test.gcc()
+ .target(&target)
+ .host(&target)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("-fPIC")
+ .must_have("-m64");
+ }
+}
+
+#[test]
+fn gnu_x86_64_no_pic() {
+ for vendor in &["unknown-linux-gnu", "apple-darwin"] {
+ let target = format!("x86_64-{}", vendor);
+ let test = Test::gnu();
+ test.gcc()
+ .pic(false)
+ .target(&target)
+ .host(&target)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_not_have("-fPIC");
+ }
+}
+
+#[test]
+fn gnu_i686() {
+ for vendor in &["unknown-linux-gnu", "apple-darwin"] {
+ let target = format!("i686-{}", vendor);
+ let test = Test::gnu();
+ test.gcc()
+ .target(&target)
+ .host(&target)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("-m32");
+ }
+}
+
+#[test]
+fn gnu_i686_pic() {
+ for vendor in &["unknown-linux-gnu", "apple-darwin"] {
+ let target = format!("i686-{}", vendor);
+ let test = Test::gnu();
+ test.gcc()
+ .pic(true)
+ .target(&target)
+ .host(&target)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_have("-fPIC");
+ }
+}
+
+#[test]
+fn gnu_set_stdlib() {
+ let test = Test::gnu();
+ test.gcc()
+ .cpp_set_stdlib(Some("foo"))
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_not_have("-stdlib=foo");
+}
+
+#[test]
+fn gnu_include() {
+ let test = Test::gnu();
+ test.gcc()
+ .include("foo/bar")
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_have("-I").must_have("foo/bar");
+}
+
+#[test]
+fn gnu_define() {
+ let test = Test::gnu();
+ test.gcc()
+ .define("FOO", Some("bar"))
+ .define("BAR", None)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
+}
+
+#[test]
+fn gnu_compile_assembly() {
+ let test = Test::gnu();
+ test.gcc()
+ .file("foo.S")
+ .compile("libfoo.a");
+ test.cmd(0).must_have("foo.S");
+}
+
+#[test]
+fn msvc_smoke() {
+ let test = Test::msvc();
+ test.gcc()
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0)
+ .must_have("/O2")
+ .must_have("foo.c")
+ .must_not_have("/Z7")
+ .must_have("/c");
+ test.cmd(1).must_have(test.td.path().join("foo.o"));
+}
+
+#[test]
+fn msvc_opt_level_0() {
+ let test = Test::msvc();
+ test.gcc()
+ .opt_level(0)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_not_have("/O2");
+}
+
+#[test]
+fn msvc_debug() {
+ let test = Test::msvc();
+ test.gcc()
+ .debug(true)
+ .file("foo.c")
+ .compile("libfoo.a");
+ test.cmd(0).must_have("/Z7");
+}
+
+#[test]
+fn msvc_include() {
+ let test = Test::msvc();
+ test.gcc()
+ .include("foo/bar")
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_have("/I").must_have("foo/bar");
+}
+
+#[test]
+fn msvc_define() {
+ let test = Test::msvc();
+ test.gcc()
+ .define("FOO", Some("bar"))
+ .define("BAR", None)
+ .file("foo.c")
+ .compile("libfoo.a");
+
+ test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
+}