}
fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
+ let (cmd, subcommand_args) = match args.subcommand() {
+ (cmd, Some(args)) => (cmd, args),
+ _ => {
+ cli().print_help()?;
+ return Ok(());
+ }
+ };
+
+ let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
+
config.configure(
args.occurrences_of("verbose") as u32,
if args.is_present("quiet") {
&args.value_of("color").map(|s| s.to_string()),
args.is_present("frozen"),
args.is_present("locked"),
+ arg_target_dir,
&args.values_of_lossy("unstable-features")
.unwrap_or_default(),
)?;
- let (cmd, args) = match args.subcommand() {
- (cmd, Some(args)) => (cmd, args),
- _ => {
- cli().print_help()?;
- return Ok(());
- }
- };
-
if let Some(exec) = commands::builtin_exec(cmd) {
- return exec(config, args);
+ return exec(config, subcommand_args);
}
if let Some(mut alias) = super::aliased_command(config, cmd)? {
alias.extend(
- args.values_of("")
- .unwrap_or_default()
- .map(|s| s.to_string()),
+ subcommand_args.values_of("")
+ .unwrap_or_default()
+ .map(|s| s.to_string()),
);
- let args = cli()
+ let subcommand_args = cli()
.setting(AppSettings::NoBinaryName)
.get_matches_from_safe(alias)?;
- return execute_subcommand(config, args);
+ return execute_subcommand(config, subcommand_args);
}
let mut ext_args: Vec<&str> = vec![cmd];
- ext_args.extend(args.values_of("").unwrap_or_default());
+ ext_args.extend(subcommand_args.values_of("").unwrap_or_default());
super::execute_external_subcommand(config, cmd, &ext_args)
}
self._arg(opt("target", target).value_name("TRIPLE"))
}
+ fn arg_target_dir(self) -> Self {
+ self._arg(opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"))
+ }
+
fn arg_manifest_path(self) -> Self {
self._arg(opt("manifest-path", "Path to Cargo.toml").value_name("PATH"))
}
.arg_jobs()
.arg_features()
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.arg(opt(
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg(opt("out-dir", "Copy final artifacts to this directory").value_name("PATH"))
.arg_manifest_path()
.arg_message_format()
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
.arg_features()
.arg_target_triple("Check for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.after_help(
.arg_package_spec_simple("Package to clean artifacts for")
.arg_manifest_path()
.arg_target_triple("Target triple to clean output for (default all)")
+ .arg_target_dir()
.arg_release("Whether or not to clean release artifacts")
.after_help(
"\
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.after_help(
"Allow dirty working directories to be packaged",
))
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_jobs()
}
"Allow dirty working directories to be packaged",
))
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_jobs()
.arg(opt("dry-run", "Perform all checks without uploading"))
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.after_help(
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
.arg_features()
.arg_target_triple("Target triple which compiles will be for")
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.after_help(
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.after_help(
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
+ .arg_target_dir()
.arg_manifest_path()
.arg_message_format()
.after_help(
cache_rustc_info: bool,
/// Creation time of this config, used to output the total build time
creation_time: Instant,
+ /// Target Directory via resolved Cli parameter
+ cli_target_dir: Option<Filesystem>,
}
impl Config {
crates_io_source_id: LazyCell::new(),
cache_rustc_info,
creation_time: Instant::now(),
+ cli_target_dir: None,
}
}
}
pub fn target_dir(&self) -> CargoResult<Option<Filesystem>> {
- if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
+ if let Some(ref dir) = self.cli_target_dir {
+ Ok(Some(dir.clone()))
+ } else if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
Ok(Some(Filesystem::new(self.cwd.join(dir))))
} else if let Some(val) = self.get_path("build.target-dir")? {
let val = self.cwd.join(val.val);
color: &Option<String>,
frozen: bool,
locked: bool,
+ target_dir: &Option<PathBuf>,
unstable_flags: &[String],
) -> CargoResult<()> {
let extra_verbose = verbose >= 2;
| (None, None, None) => Verbosity::Normal,
};
+ let cli_target_dir = match target_dir.as_ref() {
+ Some(dir) => Some(Filesystem::new(dir.clone())),
+ None => None,
+ };
+
self.shell().set_verbosity(verbosity);
self.shell().set_color_choice(color.map(|s| &s[..]))?;
self.extra_verbose = extra_verbose;
self.frozen = frozen;
self.locked = locked;
+ self.cli_target_dir = cli_target_dir;
self.cli_flags.parse(unstable_flags)?;
Ok(())
}
#[test]
-fn custom_target_dir() {
+fn custom_target_dir_env() {
let p = project("foo")
.file(
"Cargo.toml",
);
}
+#[test]
+fn custom_target_dir_line_parameter() {
+ let p = project("foo")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
+
+ assert_that(
+ p.cargo("build").arg("--target-dir").arg("foo/target"),
+ execs().with_status(0),
+ );
+ assert_that(
+ &p.root().join("foo/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("target/debug").join(&exe_name),
+ is_not(existing_file()),
+ );
+
+ assert_that(p.cargo("build"), execs().with_status(0));
+ assert_that(
+ &p.root().join("foo/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("target/debug").join(&exe_name),
+ existing_file(),
+ );
+
+ fs::create_dir(p.root().join(".cargo")).unwrap();
+ File::create(p.root().join(".cargo/config"))
+ .unwrap()
+ .write_all(
+ br#"
+ [build]
+ target-dir = "foo/target"
+ "#,
+ )
+ .unwrap();
+ assert_that(
+ p.cargo("build").arg("--target-dir").arg("bar/target"),
+ execs().with_status(0),
+ );
+ assert_that(
+ &p.root().join("bar/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("foo/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("target/debug").join(&exe_name),
+ existing_file(),
+ );
+
+ assert_that(
+ p.cargo("build")
+ .arg("--target-dir")
+ .arg("foobar/target")
+ .env("CARGO_TARGET_DIR", "bar/target"),
+ execs().with_status(0),
+ );
+ assert_that(
+ &p.root().join("foobar/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("bar/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("foo/target/debug").join(&exe_name),
+ existing_file(),
+ );
+ assert_that(
+ &p.root().join("target/debug").join(&exe_name),
+ existing_file(),
+ );
+}
+
+#[test]
+fn rustc_no_trans() {
+ if !is_nightly() {
+ return;
+ }
+
+ let p = project("foo")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ assert_that(
+ p.cargo("rustc").arg("-v").arg("--").arg("-Zno-trans"),
+ execs().with_status(0),
+ );
+}
+
#[test]
fn build_multiple_packages() {
let p = project("foo")
&None,
false,
false,
+ &None,
&["minimal-versions".to_string()],
)
.unwrap();