]>
git.proxmox.com Git - rustc.git/blob - vendor/cc/tests/support/mod.rs
4 use std
::ffi
::{OsStr, OsString}
;
5 use std
::fs
::{self, File}
;
7 use std
::io
::prelude
::*;
8 use std
::path
::{Path, PathBuf}
;
11 use tempfile
::{Builder, TempDir}
;
19 pub struct Execution
{
24 pub fn new() -> Test
{
25 // This is ugly: `sccache` needs to introspect the compiler it is
26 // executing, as it adjusts its behavior depending on the
27 // language/compiler. This crate's test driver uses mock compilers that
28 // are obviously not supported by sccache, so the tests fail if
29 // RUSTC_WRAPPER is set. rust doesn't build test dependencies with
30 // the `test` feature enabled, so we can't conditionally disable the
31 // usage of `sccache` if running in a test environment, at least not
32 // without setting an environment variable here and testing for it
33 // there. Explicitly deasserting RUSTC_WRAPPER here seems to be the
34 // lesser of the two evils.
35 env
::remove_var("RUSTC_WRAPPER");
37 let mut gcc
= PathBuf
::from(env
::current_exe().unwrap());
39 if gcc
.ends_with("deps") {
42 let td
= Builder
::new().prefix("gcc-test").tempdir_in(&gcc
).unwrap();
43 gcc
.push(format
!("gcc-shim{}", env
::consts
::EXE_SUFFIX
));
51 pub fn gnu() -> Test
{
53 t
.shim("cc").shim("c++").shim("ar");
57 pub fn msvc() -> Test
{
58 let mut t
= Test
::new();
59 t
.shim("cl").shim("lib.exe");
64 pub fn shim(&self, name
: &str) -> &Test
{
65 let name
= if name
.ends_with(env
::consts
::EXE_SUFFIX
) {
68 format
!("{}{}", name
, env
::consts
::EXE_SUFFIX
)
70 link_or_copy(&self.gcc
, self.td
.path().join(name
)).unwrap();
74 pub fn gcc(&self) -> cc
::Build
{
75 let mut cfg
= cc
::Build
::new();
76 let target
= if self.msvc
{
77 "x86_64-pc-windows-msvc"
79 "x86_64-unknown-linux-gnu"
86 .out_dir(self.td
.path())
87 .__set_env("PATH", self.path())
88 .__set_env("GCCTEST_OUT_DIR", self.td
.path());
90 cfg
.compiler(self.td
.path().join("cl"));
91 cfg
.archiver(self.td
.path().join("lib.exe"));
96 fn path(&self) -> OsString
{
97 let mut path
= env
::split_paths(&env
::var_os("PATH").unwrap()).collect
::<Vec
<_
>>();
98 path
.insert(0, self.td
.path().to_owned());
99 env
::join_paths(path
).unwrap()
102 pub fn cmd(&self, i
: u32) -> Execution
{
103 let mut s
= String
::new();
104 File
::open(self.td
.path().join(format
!("out{}", i
)))
106 .read_to_string(&mut s
)
109 args
: s
.lines().map(|s
| s
.to_string()).collect(),
115 pub fn must_have
<P
: AsRef
<OsStr
>>(&self, p
: P
) -> &Execution
{
116 if !self.has(p
.as_ref()) {
117 panic
!("didn't find {:?} in {:?}", p
.as_ref(), self.args
);
123 pub fn must_not_have
<P
: AsRef
<OsStr
>>(&self, p
: P
) -> &Execution
{
124 if self.has(p
.as_ref()) {
125 panic
!("found {:?}", p
.as_ref());
131 pub fn has(&self, p
: &OsStr
) -> bool
{
132 self.args
.iter().any(|arg
| OsStr
::new(arg
) == p
)
135 pub fn must_have_in_order(&self, before
: &str, after
: &str) -> &Execution
{
136 let before_position
= self
139 .rposition(|x
| OsStr
::new(x
) == OsStr
::new(before
));
140 let after_position
= self
143 .rposition(|x
| OsStr
::new(x
) == OsStr
::new(after
));
144 match (before_position
, after_position
) {
145 (Some(b
), Some(a
)) if b
< a
=> {}
147 "{:?} (last position: {:?}) did not appear before {:?} (last position: {:?})",
155 /// Hard link an executable or copy it if that fails.
157 /// We first try to hard link an executable to save space. If that fails (as on Windows with
158 /// different mount points, issue #60), we copy.
159 #[cfg(not(target_os = "macos"))]
160 fn link_or_copy
<P
: AsRef
<Path
>, Q
: AsRef
<Path
>>(from
: P
, to
: Q
) -> io
::Result
<()> {
161 let from
= from
.as_ref();
162 let to
= to
.as_ref();
163 fs
::hard_link(from
, to
).or_else(|_
| fs
::copy(from
, to
).map(|_
| ()))
166 /// Copy an executable.
168 /// On macOS, hard linking the executable leads to strange failures (issue #419), so we just copy.
169 #[cfg(target_os = "macos")]
170 fn link_or_copy
<P
: AsRef
<Path
>, Q
: AsRef
<Path
>>(from
: P
, to
: Q
) -> io
::Result
<()> {
171 fs
::copy(from
, to
).map(|_
| ())