Skip to content

Commit ba804bb

Browse files
author
Nisarg Thakkar
committed
Adding tests for --target with cargo publish and cargo package
1 parent 1c59387 commit ba804bb

File tree

7 files changed

+353
-243
lines changed

7 files changed

+353
-243
lines changed

src/bin/publish.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
6666
flag_allow_dirty: allow_dirty,
6767
flag_jobs: jobs,
6868
flag_dry_run: dry_run,
69+
flag_target: target,
6970
..
7071
} = options;
7172

@@ -96,7 +97,7 @@ about this warning.";
9697
else { config.shell().warn(&msg)?; host }, // TODO: Deprecated, remove
9798
verify: !no_verify,
9899
allow_dirty: allow_dirty,
99-
target: options.flag_target.as_ref().map(|t| &t[..]),
100+
target: target.as_ref().map(|t| &t[..]),
100101
jobs: jobs,
101102
dry_run: dry_run,
102103
})?;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use std::env;
2+
use std::process::Command;
3+
use std::sync::{Once, ONCE_INIT};
4+
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
5+
6+
use support::{project, main_file, basic_bin_manifest};
7+
8+
pub fn disabled() -> bool {
9+
// First, disable if ./configure requested so
10+
match env::var("CFG_DISABLE_CROSS_TESTS") {
11+
Ok(ref s) if *s == "1" => return true,
12+
_ => {}
13+
}
14+
15+
// Right now the windows bots cannot cross compile due to the mingw setup,
16+
// so we disable ourselves on all but macos/linux setups where the rustc
17+
// install script ensures we have both architectures
18+
if !(cfg!(target_os = "macos") ||
19+
cfg!(target_os = "linux") ||
20+
cfg!(target_env = "msvc")) {
21+
return true;
22+
}
23+
24+
// It's not particularly common to have a cross-compilation setup, so
25+
// try to detect that before we fail a bunch of tests through no fault
26+
// of the user.
27+
static CAN_RUN_CROSS_TESTS: AtomicBool = ATOMIC_BOOL_INIT;
28+
static CHECK: Once = ONCE_INIT;
29+
30+
let cross_target = alternate();
31+
32+
CHECK.call_once(|| {
33+
let p = project("cross_test")
34+
.file("Cargo.toml", &basic_bin_manifest("cross_test"))
35+
.file("src/cross_test.rs", &main_file(r#""testing!""#, &[]));
36+
37+
let result = p.cargo_process("build")
38+
.arg("--target").arg(&cross_target)
39+
.exec_with_output();
40+
41+
if result.is_ok() {
42+
CAN_RUN_CROSS_TESTS.store(true, Ordering::SeqCst);
43+
}
44+
});
45+
46+
if CAN_RUN_CROSS_TESTS.load(Ordering::SeqCst) {
47+
// We were able to compile a simple project, so the user has the
48+
// necessary std:: bits installed. Therefore, tests should not
49+
// be disabled.
50+
return false;
51+
}
52+
53+
// We can't compile a simple cross project. We want to warn the user
54+
// by failing a single test and having the remainder of the cross tests
55+
// pass. We don't use std::sync::Once here because panicing inside its
56+
// call_once method would poison the Once instance, which is not what
57+
// we want.
58+
static HAVE_WARNED: AtomicBool = ATOMIC_BOOL_INIT;
59+
60+
if HAVE_WARNED.swap(true, Ordering::SeqCst) {
61+
// We are some other test and somebody else is handling the warning.
62+
// Just disable the current test.
63+
return true;
64+
}
65+
66+
// We are responsible for warning the user, which we do by panicing.
67+
let rustup_available = Command::new("rustup").output().is_ok();
68+
69+
let linux_help = if cfg!(target_os = "linux") {
70+
"
71+
72+
You may need to install runtime libraries for your Linux distribution as well.".to_string()
73+
} else {
74+
"".to_string()
75+
};
76+
77+
let rustup_help = if rustup_available {
78+
format!("
79+
80+
Alternatively, you can install the necessary libraries for cross-compilation with
81+
82+
rustup target add {}{}", cross_target, linux_help)
83+
} else {
84+
"".to_string()
85+
};
86+
87+
panic!("Cannot cross compile to {}.
88+
89+
This failure can be safely ignored. If you would prefer to not see this
90+
failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\".{}
91+
", cross_target, rustup_help);
92+
}
93+
94+
pub fn alternate() -> String {
95+
let platform = match env::consts::OS {
96+
"linux" => "unknown-linux-gnu",
97+
"macos" => "apple-darwin",
98+
"windows" => "pc-windows-msvc",
99+
_ => unreachable!(),
100+
};
101+
let arch = match env::consts::ARCH {
102+
"x86" => "x86_64",
103+
"x86_64" => "i686",
104+
_ => unreachable!(),
105+
};
106+
format!("{}-{}", arch, platform)
107+
}
108+
109+
pub fn alternate_arch() -> &'static str {
110+
match env::consts::ARCH {
111+
"x86" => "x86_64",
112+
"x86_64" => "x86",
113+
_ => unreachable!(),
114+
}
115+
}
116+
117+
pub fn host() -> String {
118+
let platform = match env::consts::OS {
119+
"linux" => "unknown-linux-gnu",
120+
"macos" => "apple-darwin",
121+
"windows" => "pc-windows-msvc",
122+
_ => unreachable!(),
123+
};
124+
let arch = match env::consts::ARCH {
125+
"x86" => "i686",
126+
"x86_64" => "x86_64",
127+
_ => unreachable!(),
128+
};
129+
format!("{}-{}", arch, platform)
130+
}

tests/cargotest/support/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ macro_rules! t {
3030
pub mod paths;
3131
pub mod git;
3232
pub mod registry;
33+
pub mod cross_compile;
34+
pub mod publish;
3335

3436
/*
3537
*

tests/cargotest/support/publish.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
extern crate url;
2+
3+
use std::path::PathBuf;
4+
use std::io::prelude::*;
5+
use std::fs::{self, File};
6+
7+
use support::paths;
8+
use support::git::repo;
9+
10+
use url::Url;
11+
12+
pub fn setup() {
13+
let config = paths::root().join(".cargo/config");
14+
t!(fs::create_dir_all(config.parent().unwrap()));
15+
t!(t!(File::create(&config)).write_all(br#"
16+
[registry]
17+
token = "api-token"
18+
"#));
19+
t!(fs::create_dir_all(&upload_path().join("api/v1/crates")));
20+
21+
repo(&registry_path())
22+
.file("config.json", &format!(r#"{{
23+
"dl": "{0}",
24+
"api": "{0}"
25+
}}"#, upload()))
26+
.build();
27+
}
28+
29+
fn registry_path() -> PathBuf { paths::root().join("registry") }
30+
pub fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
31+
pub fn upload_path() -> PathBuf { paths::root().join("upload") }
32+
fn upload() -> Url { Url::from_file_path(&*upload_path()).ok().unwrap() }

0 commit comments

Comments
 (0)