Skip to content

Commit 3d3ddd2

Browse files
committed
Auto merge of #9627 - whereistejas:many-bin-names, r=ehuss
Ability to specify the output name for a bin target different from the crate name Hi, I have opened this to close the following issue #1706 . I have decided to start by writing a test to outline what behavior is expected from `Cargo`. As of now, this test fails (for obvious reasons). I will now start writing the code needed to pass this test. This is my first time contributing to cargo. Please, feel free to let me know if there are any protocols/processes that need to be followed. I'm a newbie at this. Closes issue #1706
2 parents b51439f + 9e2790f commit 3d3ddd2

File tree

11 files changed

+376
-9
lines changed

11 files changed

+376
-9
lines changed

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,18 @@ impl FileType {
103103
/// The filename for this FileType that Cargo should use when "uplifting"
104104
/// it to the destination directory.
105105
pub fn uplift_filename(&self, target: &Target) -> String {
106-
let name = if self.should_replace_hyphens {
107-
target.crate_name()
108-
} else {
109-
target.name().to_string()
106+
let name = match target.binary_filename() {
107+
Some(name) => name,
108+
None => {
109+
// For binary crate type, `should_replace_hyphens` will always be false.
110+
if self.should_replace_hyphens {
111+
target.crate_name()
112+
} else {
113+
target.name().to_string()
114+
}
115+
}
110116
};
117+
111118
format!("{}{}{}", self.prefix, name, self.suffix)
112119
}
113120

src/cargo/core/compiler/compilation.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,12 @@ impl<'cfg> Compilation<'cfg> {
365365
/// that are only relevant in a context that has a unit
366366
fn fill_rustc_tool_env(mut cmd: ProcessBuilder, unit: &Unit) -> ProcessBuilder {
367367
if unit.target.is_bin() {
368-
cmd.env("CARGO_BIN_NAME", unit.target.name());
368+
let name = unit
369+
.target
370+
.binary_filename()
371+
.unwrap_or(unit.target.name().to_string());
372+
373+
cmd.env("CARGO_BIN_NAME", name);
369374
}
370375
cmd.env("CARGO_CRATE_NAME", unit.target.crate_name());
371376
cmd

src/cargo/core/compiler/context/compilation_files.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
467467
let meta = &self.metas[unit];
468468
let meta_opt = meta.use_extra_filename.then(|| meta.meta_hash.to_string());
469469
let path = out_dir.join(file_type.output_filename(&unit.target, meta_opt.as_deref()));
470+
471+
// If, the `different_binary_name` feature is enabled, the name of the hardlink will
472+
// be the name of the binary provided by the user in `Cargo.toml`.
470473
let hardlink = self.uplift_to(unit, &file_type, &path);
471474
let export_path = if unit.target.is_custom_build() {
472475
None

src/cargo/core/compiler/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,10 @@ fn build_base_args(
985985
let exe_path = cx
986986
.files()
987987
.bin_link_for_target(bin_target, unit.kind, cx.bcx)?;
988-
let key = format!("CARGO_BIN_EXE_{}", bin_target.name());
988+
let name = bin_target
989+
.binary_filename()
990+
.unwrap_or(bin_target.name().to_string());
991+
let key = format!("CARGO_BIN_EXE_{}", name);
989992
cmd.env(&key, exe_path);
990993
}
991994
}

src/cargo/core/features.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,9 @@ features! {
405405

406406
// Allow to specify which codegen backend should be used.
407407
(unstable, codegen_backend, "", "reference/unstable.html#codegen-backend"),
408+
409+
// Allow specifying different binary name apart from the crate name
410+
(unstable, different_binary_name, "", "reference/unstable.html#different-binary-name"),
408411
}
409412

410413
pub struct Feature {

src/cargo/core/manifest.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ pub struct Target {
194194
struct TargetInner {
195195
kind: TargetKind,
196196
name: String,
197+
// Note that `bin_name` is used for the cargo-feature `different_binary_name`
198+
bin_name: Option<String>,
197199
// Note that the `src_path` here is excluded from the `Hash` implementation
198200
// as it's absolute currently and is otherwise a little too brittle for
199201
// causing rebuilds. Instead the hash for the path that we send to the
@@ -350,6 +352,7 @@ compact_debug! {
350352
[debug_the_fields(
351353
kind
352354
name
355+
bin_name
353356
src_path
354357
required_features
355358
tested
@@ -627,6 +630,7 @@ impl Target {
627630
inner: Arc::new(TargetInner {
628631
kind: TargetKind::Bin,
629632
name: String::new(),
633+
bin_name: None,
630634
src_path,
631635
required_features: None,
632636
doc: false,
@@ -662,6 +666,7 @@ impl Target {
662666

663667
pub fn bin_target(
664668
name: &str,
669+
bin_name: Option<String>,
665670
src_path: PathBuf,
666671
required_features: Option<Vec<String>>,
667672
edition: Edition,
@@ -670,6 +675,7 @@ impl Target {
670675
target
671676
.set_kind(TargetKind::Bin)
672677
.set_name(name)
678+
.set_binary_name(bin_name)
673679
.set_required_features(required_features)
674680
.set_doc(true);
675681
target
@@ -911,11 +917,17 @@ impl Target {
911917
Arc::make_mut(&mut self.inner).name = name.to_string();
912918
self
913919
}
920+
pub fn set_binary_name(&mut self, bin_name: Option<String>) -> &mut Target {
921+
Arc::make_mut(&mut self.inner).bin_name = bin_name;
922+
self
923+
}
914924
pub fn set_required_features(&mut self, required_features: Option<Vec<String>>) -> &mut Target {
915925
Arc::make_mut(&mut self.inner).required_features = required_features;
916926
self
917927
}
918-
928+
pub fn binary_filename(&self) -> Option<String> {
929+
self.inner.bin_name.clone()
930+
}
919931
pub fn description_named(&self) -> String {
920932
match self.kind() {
921933
TargetKind::Lib(..) => "lib".to_string(),

src/cargo/util/toml/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,6 +1968,8 @@ struct TomlTarget {
19681968
crate_type2: Option<Vec<String>>,
19691969

19701970
path: Option<PathValue>,
1971+
// Note that `filename` is used for the cargo-feature `different_binary_name`
1972+
filename: Option<String>,
19711973
test: Option<bool>,
19721974
doctest: Option<bool>,
19731975
bench: Option<bool>,

src/cargo/util/toml/targets.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,14 @@ fn clean_bins(
266266
"autobins",
267267
);
268268

269+
// This loop performs basic checks on each of the TomlTarget in `bins`.
269270
for bin in &bins {
271+
// For each binary, check if the `filename` parameter is populated. If it is,
272+
// check if the corresponding cargo feature has been activated.
273+
if bin.filename.is_some() {
274+
features.require(Feature::different_binary_name())?;
275+
}
276+
270277
validate_target_name(bin, "binary", "bin", warnings)?;
271278

272279
let name = bin.name();
@@ -321,8 +328,14 @@ fn clean_bins(
321328
Err(e) => anyhow::bail!("{}", e),
322329
};
323330

324-
let mut target =
325-
Target::bin_target(&bin.name(), path, bin.required_features.clone(), edition);
331+
let mut target = Target::bin_target(
332+
&bin.name(),
333+
bin.filename.clone(),
334+
path,
335+
bin.required_features.clone(),
336+
edition,
337+
);
338+
326339
configure(features, bin, &mut target)?;
327340
result.push(target);
328341
}

src/doc/src/reference/unstable.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Each new feature described below should explain how to use it.
7474
* Output behavior
7575
* [out-dir](#out-dir) — Adds a directory where artifacts are copied to.
7676
* [terminal-width](#terminal-width) — Tells rustc the width of the terminal so that long diagnostic messages can be truncated to be more readable.
77+
* [Different binary name](#different-binary-name) — Assign a name to the built binary that is seperate from the crate name.
7778
* Compile behavior
7879
* [mtime-on-use](#mtime-on-use) — Updates the last-modified timestamp on every dependency every time it is used, to provide a mechanism to delete unused artifacts.
7980
* [doctest-xcompile](#doctest-xcompile) — Supports running doctests with the `--target` flag.
@@ -1288,6 +1289,32 @@ The primary use case is to run `cargo rustc --print=cfg` to get config values
12881289
for the appropriate target and influenced by any other RUSTFLAGS.
12891290

12901291

1292+
### Different binary name
1293+
1294+
* Tracking Issue: [#9778](https://github.com/rust-lang/cargo/issues/9778)
1295+
* PR: [#9627](https://github.com/rust-lang/cargo/pull/9627)
1296+
1297+
The `different-binary-name` feature allows setting the filename of the binary without having to obey the
1298+
restrictions placed on crate names. For example, the crate name must use only `alphanumeric` characters
1299+
or `-` or `_`, and cannot be empty.
1300+
1301+
The `filename` parameter should **not** include the binary extension, `cargo` will figure out the appropriate
1302+
extension and use that for the binary on its own.
1303+
1304+
The `filename` parameter is only available in the `[[bin]]` section of the manifest.
1305+
1306+
```toml
1307+
cargo-features = ["different-binary-name"]
1308+
1309+
[project]
1310+
name = "foo"
1311+
version = "0.0.1"
1312+
1313+
[[bin]]
1314+
name = "foo"
1315+
filename = "007bar"
1316+
path = "src/main.rs"
1317+
```
12911318

12921319
## Stabilized and removed features
12931320

0 commit comments

Comments
 (0)