Skip to content

Commit

Permalink
Auto merge of #4440 - nisargthakkar:publish_target, r=alexcrichton
Browse files Browse the repository at this point in the history
Adding target support to cargo package and cargo publish

Fixing Issue #4012

Same as #4077 but couldn't reopen the PR due to force push after rebasing from master
  • Loading branch information
bors committed Aug 29, 2017
2 parents 814c389 + 0a4e04c commit b524682
Show file tree
Hide file tree
Showing 10 changed files with 360 additions and 243 deletions.
3 changes: 3 additions & 0 deletions src/bin/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct Options {
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_no_verify: bool,
flag_no_metadata: bool,
Expand All @@ -32,6 +33,7 @@ Options:
--no-verify Don't verify the contents by building them
--no-metadata Ignore warnings about a lack of human-usable metadata
--allow-dirty Allow dirty working directories to be packaged
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to compile
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
Expand All @@ -57,6 +59,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
list: options.flag_list,
check_metadata: !options.flag_no_metadata,
allow_dirty: options.flag_allow_dirty,
target: options.flag_target.as_ref().map(|t| &t[..]),
jobs: options.flag_jobs,
})?;
Ok(())
Expand Down
4 changes: 4 additions & 0 deletions src/bin/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct Options {
flag_index: Option<String>,
flag_host: Option<String>, // TODO: Deprecated, remove
flag_token: Option<String>,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
Expand Down Expand Up @@ -35,6 +36,7 @@ Options:
--token TOKEN Token to use when uploading
--no-verify Don't verify package tarball before publish
--allow-dirty Allow publishing with a dirty source directory
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest of the package to publish
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--dry-run Perform all checks without uploading
Expand Down Expand Up @@ -64,6 +66,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
flag_allow_dirty: allow_dirty,
flag_jobs: jobs,
flag_dry_run: dry_run,
flag_target: target,
..
} = options;

Expand Down Expand Up @@ -94,6 +97,7 @@ about this warning.";
else { config.shell().warn(&msg)?; host }, // TODO: Deprecated, remove
verify: !no_verify,
allow_dirty: allow_dirty,
target: target.as_ref().map(|t| &t[..]),
jobs: jobs,
dry_run: dry_run,
})?;
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct PackageOpts<'cfg> {
pub allow_dirty: bool,
pub verify: bool,
pub jobs: Option<u32>,
pub target: Option<&'cfg str>,
}

pub fn package(ws: &Workspace,
Expand Down Expand Up @@ -298,7 +299,7 @@ fn run_verify(ws: &Workspace, tar: &File, opts: &PackageOpts) -> CargoResult<()>
ops::compile_ws(&ws, None, &ops::CompileOptions {
config: config,
jobs: opts.jobs,
target: None,
target: opts.target,
features: &[],
no_default_features: false,
all_features: false,
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct PublishOpts<'cfg> {
pub verify: bool,
pub allow_dirty: bool,
pub jobs: Option<u32>,
pub target: Option<&'cfg str>,
pub dry_run: bool,
}

Expand Down Expand Up @@ -61,6 +62,7 @@ pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> {
list: false,
check_metadata: true,
allow_dirty: opts.allow_dirty,
target: opts.target,
jobs: opts.jobs,
})?.unwrap();

Expand Down
130 changes: 130 additions & 0 deletions tests/cargotest/support/cross_compile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use std::env;
use std::process::Command;
use std::sync::{Once, ONCE_INIT};
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};

use support::{project, main_file, basic_bin_manifest};

pub fn disabled() -> bool {
// First, disable if ./configure requested so
match env::var("CFG_DISABLE_CROSS_TESTS") {
Ok(ref s) if *s == "1" => return true,
_ => {}
}

// Right now the windows bots cannot cross compile due to the mingw setup,
// so we disable ourselves on all but macos/linux setups where the rustc
// install script ensures we have both architectures
if !(cfg!(target_os = "macos") ||
cfg!(target_os = "linux") ||
cfg!(target_env = "msvc")) {
return true;
}

// It's not particularly common to have a cross-compilation setup, so
// try to detect that before we fail a bunch of tests through no fault
// of the user.
static CAN_RUN_CROSS_TESTS: AtomicBool = ATOMIC_BOOL_INIT;
static CHECK: Once = ONCE_INIT;

let cross_target = alternate();

CHECK.call_once(|| {
let p = project("cross_test")
.file("Cargo.toml", &basic_bin_manifest("cross_test"))
.file("src/cross_test.rs", &main_file(r#""testing!""#, &[]));

let result = p.cargo_process("build")
.arg("--target").arg(&cross_target)
.exec_with_output();

if result.is_ok() {
CAN_RUN_CROSS_TESTS.store(true, Ordering::SeqCst);
}
});

if CAN_RUN_CROSS_TESTS.load(Ordering::SeqCst) {
// We were able to compile a simple project, so the user has the
// necessary std:: bits installed. Therefore, tests should not
// be disabled.
return false;
}

// We can't compile a simple cross project. We want to warn the user
// by failing a single test and having the remainder of the cross tests
// pass. We don't use std::sync::Once here because panicing inside its
// call_once method would poison the Once instance, which is not what
// we want.
static HAVE_WARNED: AtomicBool = ATOMIC_BOOL_INIT;

if HAVE_WARNED.swap(true, Ordering::SeqCst) {
// We are some other test and somebody else is handling the warning.
// Just disable the current test.
return true;
}

// We are responsible for warning the user, which we do by panicing.
let rustup_available = Command::new("rustup").output().is_ok();

let linux_help = if cfg!(target_os = "linux") {
"
You may need to install runtime libraries for your Linux distribution as well.".to_string()
} else {
"".to_string()
};

let rustup_help = if rustup_available {
format!("
Alternatively, you can install the necessary libraries for cross-compilation with
rustup target add {}{}", cross_target, linux_help)
} else {
"".to_string()
};

panic!("Cannot cross compile to {}.
This failure can be safely ignored. If you would prefer to not see this
failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\".{}
", cross_target, rustup_help);
}

pub fn alternate() -> String {
let platform = match env::consts::OS {
"linux" => "unknown-linux-gnu",
"macos" => "apple-darwin",
"windows" => "pc-windows-msvc",
_ => unreachable!(),
};
let arch = match env::consts::ARCH {
"x86" => "x86_64",
"x86_64" => "i686",
_ => unreachable!(),
};
format!("{}-{}", arch, platform)
}

pub fn alternate_arch() -> &'static str {
match env::consts::ARCH {
"x86" => "x86_64",
"x86_64" => "x86",
_ => unreachable!(),
}
}

pub fn host() -> String {
let platform = match env::consts::OS {
"linux" => "unknown-linux-gnu",
"macos" => "apple-darwin",
"windows" => "pc-windows-msvc",
_ => unreachable!(),
};
let arch = match env::consts::ARCH {
"x86" => "i686",
"x86_64" => "x86_64",
_ => unreachable!(),
};
format!("{}-{}", arch, platform)
}
2 changes: 2 additions & 0 deletions tests/cargotest/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ macro_rules! t {
pub mod paths;
pub mod git;
pub mod registry;
pub mod cross_compile;
pub mod publish;

/*
*
Expand Down
30 changes: 30 additions & 0 deletions tests/cargotest/support/publish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::path::PathBuf;
use std::io::prelude::*;
use std::fs::{self, File};

use support::paths;
use support::git::repo;

use url::Url;

pub fn setup() {
let config = paths::root().join(".cargo/config");
t!(fs::create_dir_all(config.parent().unwrap()));
t!(t!(File::create(&config)).write_all(br#"
[registry]
token = "api-token"
"#));
t!(fs::create_dir_all(&upload_path().join("api/v1/crates")));

repo(&registry_path())
.file("config.json", &format!(r#"{{
"dl": "{0}",
"api": "{0}"
}}"#, upload()))
.build();
}

fn registry_path() -> PathBuf { paths::root().join("registry") }
pub fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
pub fn upload_path() -> PathBuf { paths::root().join("upload") }
fn upload() -> Url { Url::from_file_path(&*upload_path()).ok().unwrap() }
Loading

0 comments on commit b524682

Please sign in to comment.