Skip to content

Commit 7debd81

Browse files
committed
Auto merge of #5393 - smithsps:master, r=matklad
Add target directory parameter --target-dir Implements: #5308 Adds a target directory parameter, that acts in the same manner as the environment variable `CARGO_TARGET_DIR`, to the following subcommands: - `bench` - `build` - `check` - `clean` - `doc` - `package` - `publish` - `run` - `rustc` - `rustdoc` - `test`
2 parents ac9d5da + 0b530c3 commit 7debd81

19 files changed

+175
-29
lines changed

src/bin/cli.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
7272
}
7373

7474
fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
75+
let (cmd, subcommand_args) = match args.subcommand() {
76+
(cmd, Some(args)) => (cmd, args),
77+
_ => {
78+
cli().print_help()?;
79+
return Ok(());
80+
}
81+
};
82+
83+
let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
84+
7585
config.configure(
7686
args.occurrences_of("verbose") as u32,
7787
if args.is_present("quiet") {
@@ -82,35 +92,28 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
8292
&args.value_of("color").map(|s| s.to_string()),
8393
args.is_present("frozen"),
8494
args.is_present("locked"),
95+
arg_target_dir,
8596
&args.values_of_lossy("unstable-features")
8697
.unwrap_or_default(),
8798
)?;
8899

89-
let (cmd, args) = match args.subcommand() {
90-
(cmd, Some(args)) => (cmd, args),
91-
_ => {
92-
cli().print_help()?;
93-
return Ok(());
94-
}
95-
};
96-
97100
if let Some(exec) = commands::builtin_exec(cmd) {
98-
return exec(config, args);
101+
return exec(config, subcommand_args);
99102
}
100103

101104
if let Some(mut alias) = super::aliased_command(config, cmd)? {
102105
alias.extend(
103-
args.values_of("")
104-
.unwrap_or_default()
105-
.map(|s| s.to_string()),
106+
subcommand_args.values_of("")
107+
.unwrap_or_default()
108+
.map(|s| s.to_string()),
106109
);
107-
let args = cli()
110+
let subcommand_args = cli()
108111
.setting(AppSettings::NoBinaryName)
109112
.get_matches_from_safe(alias)?;
110-
return execute_subcommand(config, args);
113+
return execute_subcommand(config, subcommand_args);
111114
}
112115
let mut ext_args: Vec<&str> = vec![cmd];
113-
ext_args.extend(args.values_of("").unwrap_or_default());
116+
ext_args.extend(subcommand_args.values_of("").unwrap_or_default());
114117
super::execute_external_subcommand(config, cmd, &ext_args)
115118
}
116119

src/bin/command_prelude.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ pub trait AppExt: Sized {
109109
self._arg(opt("target", target).value_name("TRIPLE"))
110110
}
111111

112+
fn arg_target_dir(self) -> Self {
113+
self._arg(opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"))
114+
}
115+
112116
fn arg_manifest_path(self) -> Self {
113117
self._arg(opt("manifest-path", "Path to Cargo.toml").value_name("PATH"))
114118
}

src/bin/commands/bench.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub fn cli() -> App {
3737
.arg_jobs()
3838
.arg_features()
3939
.arg_target_triple("Build for the target triple")
40+
.arg_target_dir()
4041
.arg_manifest_path()
4142
.arg_message_format()
4243
.arg(opt(

src/bin/commands/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn cli() -> App {
2727
.arg_release("Build artifacts in release mode, with optimizations")
2828
.arg_features()
2929
.arg_target_triple("Build for the target triple")
30+
.arg_target_dir()
3031
.arg(opt("out-dir", "Copy final artifacts to this directory").value_name("PATH"))
3132
.arg_manifest_path()
3233
.arg_message_format()

src/bin/commands/check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn cli() -> App {
2727
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
2828
.arg_features()
2929
.arg_target_triple("Check for the target triple")
30+
.arg_target_dir()
3031
.arg_manifest_path()
3132
.arg_message_format()
3233
.after_help(

src/bin/commands/clean.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub fn cli() -> App {
88
.arg_package_spec_simple("Package to clean artifacts for")
99
.arg_manifest_path()
1010
.arg_target_triple("Target triple to clean output for (default all)")
11+
.arg_target_dir()
1112
.arg_release("Whether or not to clean release artifacts")
1213
.after_help(
1314
"\

src/bin/commands/doc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn cli() -> App {
2424
.arg_release("Build artifacts in release mode, with optimizations")
2525
.arg_features()
2626
.arg_target_triple("Build for the target triple")
27+
.arg_target_dir()
2728
.arg_manifest_path()
2829
.arg_message_format()
2930
.after_help(

src/bin/commands/package.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn cli() -> App {
2424
"Allow dirty working directories to be packaged",
2525
))
2626
.arg_target_triple("Build for the target triple")
27+
.arg_target_dir()
2728
.arg_manifest_path()
2829
.arg_jobs()
2930
}

src/bin/commands/publish.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub fn cli() -> App {
1616
"Allow dirty working directories to be packaged",
1717
))
1818
.arg_target_triple("Build for the target triple")
19+
.arg_target_dir()
1920
.arg_manifest_path()
2021
.arg_jobs()
2122
.arg(opt("dry-run", "Perform all checks without uploading"))

src/bin/commands/run.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub fn cli() -> App {
1818
.arg_release("Build artifacts in release mode, with optimizations")
1919
.arg_features()
2020
.arg_target_triple("Build for the target triple")
21+
.arg_target_dir()
2122
.arg_manifest_path()
2223
.arg_message_format()
2324
.after_help(

src/bin/commands/rustc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub fn cli() -> App {
2525
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
2626
.arg_features()
2727
.arg_target_triple("Target triple which compiles will be for")
28+
.arg_target_dir()
2829
.arg_manifest_path()
2930
.arg_message_format()
3031
.after_help(

src/bin/commands/rustdoc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn cli() -> App {
2727
)
2828
.arg_release("Build artifacts in release mode, with optimizations")
2929
.arg_features()
30+
.arg_target_dir()
3031
.arg_manifest_path()
3132
.arg_message_format()
3233
.after_help(

src/bin/commands/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub fn cli() -> App {
4141
.arg_release("Build artifacts in release mode, with optimizations")
4242
.arg_features()
4343
.arg_target_triple("Build for the target triple")
44+
.arg_target_dir()
4445
.arg_manifest_path()
4546
.arg_message_format()
4647
.after_help(

src/cargo/core/workspace.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'cfg> Workspace<'cfg> {
131131
/// root and all member packages. It will then validate the workspace
132132
/// before returning it, so `Ok` is only returned for valid workspaces.
133133
pub fn new(manifest_path: &Path, config: &'cfg Config) -> CargoResult<Workspace<'cfg>> {
134-
let target_dir = config.target_dir()?;
134+
let target_dir = config.target_dir();
135135

136136
let mut ws = Workspace {
137137
config,
@@ -191,7 +191,7 @@ impl<'cfg> Workspace<'cfg> {
191191
ws.target_dir = if let Some(dir) = target_dir {
192192
Some(dir)
193193
} else {
194-
ws.config.target_dir()?
194+
ws.config.target_dir()
195195
};
196196
ws.members.push(ws.current_manifest.clone());
197197
ws.default_members.push(ws.current_manifest.clone());

src/cargo/ops/cargo_install.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ fn install_one(
213213
let mut needs_cleanup = false;
214214
let overidden_target_dir = if source_id.is_path() {
215215
None
216-
} else if let Some(dir) = config.target_dir()? {
216+
} else if let Some(dir) = config.target_dir() {
217217
Some(dir)
218218
} else if let Ok(td) = TempFileBuilder::new().prefix("cargo-install").tempdir() {
219219
let p = td.path().to_owned();

src/cargo/util/config.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ pub struct Config {
7070
cache_rustc_info: bool,
7171
/// Creation time of this config, used to output the total build time
7272
creation_time: Instant,
73+
/// Target Directory via resolved Cli parameter
74+
target_dir: Option<Filesystem>,
7375
}
7476

7577
impl Config {
@@ -113,6 +115,7 @@ impl Config {
113115
crates_io_source_id: LazyCell::new(),
114116
cache_rustc_info,
115117
creation_time: Instant::now(),
118+
target_dir: None,
116119
}
117120
}
118121

@@ -239,15 +242,8 @@ impl Config {
239242
&self.cwd
240243
}
241244

242-
pub fn target_dir(&self) -> CargoResult<Option<Filesystem>> {
243-
if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
244-
Ok(Some(Filesystem::new(self.cwd.join(dir))))
245-
} else if let Some(val) = self.get_path("build.target-dir")? {
246-
let val = self.cwd.join(val.val);
247-
Ok(Some(Filesystem::new(val)))
248-
} else {
249-
Ok(None)
250-
}
245+
pub fn target_dir(&self) -> Option<Filesystem> {
246+
self.target_dir.clone()
251247
}
252248

253249
fn get(&self, key: &str) -> CargoResult<Option<ConfigValue>> {
@@ -461,6 +457,7 @@ impl Config {
461457
color: &Option<String>,
462458
frozen: bool,
463459
locked: bool,
460+
target_dir: &Option<PathBuf>,
464461
unstable_flags: &[String],
465462
) -> CargoResult<()> {
466463
let extra_verbose = verbose >= 2;
@@ -494,11 +491,23 @@ impl Config {
494491
| (None, None, None) => Verbosity::Normal,
495492
};
496493

494+
let target_dir = if let Some(dir) = target_dir.as_ref() {
495+
Some(Filesystem::new(self.cwd.join(dir)))
496+
} else if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
497+
Some(Filesystem::new(self.cwd.join(dir)))
498+
} else if let Ok(Some(val)) = self.get_path("build.target-dir") {
499+
let val = self.cwd.join(val.val);
500+
Some(Filesystem::new(val))
501+
} else {
502+
None
503+
};
504+
497505
self.shell().set_verbosity(verbosity);
498506
self.shell().set_color_choice(color.map(|s| &s[..]))?;
499507
self.extra_verbose = extra_verbose;
500508
self.frozen = frozen;
501509
self.locked = locked;
510+
self.target_dir = target_dir;
502511
self.cli_flags.parse(unstable_flags)?;
503512

504513
Ok(())

tests/testsuite/bad_config.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ fn invalid_global_config() {
284284
p.cargo("build").arg("-v"),
285285
execs().with_status(101).with_stderr(
286286
"\
287-
[ERROR] Couldn't load Cargo configuration
287+
error: failed to parse manifest at `[..]`
288+
289+
Caused by:
290+
Couldn't load Cargo configuration
288291
289292
Caused by:
290293
could not parse TOML configuration in `[..]`

tests/testsuite/build.rs

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3603,7 +3603,7 @@ fn dotdir_root() {
36033603
}
36043604

36053605
#[test]
3606-
fn custom_target_dir() {
3606+
fn custom_target_dir_env() {
36073607
let p = project("foo")
36083608
.file(
36093609
"Cargo.toml",
@@ -3670,6 +3670,121 @@ fn custom_target_dir() {
36703670
);
36713671
}
36723672

3673+
#[test]
3674+
fn custom_target_dir_line_parameter() {
3675+
let p = project("foo")
3676+
.file(
3677+
"Cargo.toml",
3678+
r#"
3679+
[package]
3680+
name = "foo"
3681+
version = "0.0.1"
3682+
authors = []
3683+
"#,
3684+
)
3685+
.file("src/main.rs", "fn main() {}")
3686+
.build();
3687+
3688+
let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
3689+
3690+
assert_that(
3691+
p.cargo("build --target-dir foo/target"),
3692+
execs().with_status(0),
3693+
);
3694+
assert_that(
3695+
&p.root().join("foo/target/debug").join(&exe_name),
3696+
existing_file(),
3697+
);
3698+
assert_that(
3699+
&p.root().join("target/debug").join(&exe_name),
3700+
is_not(existing_file()),
3701+
);
3702+
3703+
assert_that(p.cargo("build"), execs().with_status(0));
3704+
assert_that(
3705+
&p.root().join("foo/target/debug").join(&exe_name),
3706+
existing_file(),
3707+
);
3708+
assert_that(
3709+
&p.root().join("target/debug").join(&exe_name),
3710+
existing_file(),
3711+
);
3712+
3713+
fs::create_dir(p.root().join(".cargo")).unwrap();
3714+
File::create(p.root().join(".cargo/config"))
3715+
.unwrap()
3716+
.write_all(
3717+
br#"
3718+
[build]
3719+
target-dir = "foo/target"
3720+
"#,
3721+
)
3722+
.unwrap();
3723+
assert_that(
3724+
p.cargo("build --target-dir bar/target"),
3725+
execs().with_status(0),
3726+
);
3727+
assert_that(
3728+
&p.root().join("bar/target/debug").join(&exe_name),
3729+
existing_file(),
3730+
);
3731+
assert_that(
3732+
&p.root().join("foo/target/debug").join(&exe_name),
3733+
existing_file(),
3734+
);
3735+
assert_that(
3736+
&p.root().join("target/debug").join(&exe_name),
3737+
existing_file(),
3738+
);
3739+
3740+
assert_that(
3741+
p.cargo("build --target-dir foobar/target")
3742+
.env("CARGO_TARGET_DIR", "bar/target"),
3743+
execs().with_status(0),
3744+
);
3745+
assert_that(
3746+
&p.root().join("foobar/target/debug").join(&exe_name),
3747+
existing_file(),
3748+
);
3749+
assert_that(
3750+
&p.root().join("bar/target/debug").join(&exe_name),
3751+
existing_file(),
3752+
);
3753+
assert_that(
3754+
&p.root().join("foo/target/debug").join(&exe_name),
3755+
existing_file(),
3756+
);
3757+
assert_that(
3758+
&p.root().join("target/debug").join(&exe_name),
3759+
existing_file(),
3760+
);
3761+
}
3762+
3763+
#[test]
3764+
fn rustc_no_trans() {
3765+
if !is_nightly() {
3766+
return;
3767+
}
3768+
3769+
let p = project("foo")
3770+
.file(
3771+
"Cargo.toml",
3772+
r#"
3773+
[package]
3774+
name = "foo"
3775+
version = "0.0.1"
3776+
authors = []
3777+
"#,
3778+
)
3779+
.file("src/main.rs", "fn main() {}")
3780+
.build();
3781+
3782+
assert_that(
3783+
p.cargo("rustc").arg("-v").arg("--").arg("-Zno-trans"),
3784+
execs().with_status(0),
3785+
);
3786+
}
3787+
36733788
#[test]
36743789
fn build_multiple_packages() {
36753790
let p = project("foo")

0 commit comments

Comments
 (0)