Skip to content

Commit 9e2790f

Browse files
Tejas Sanapehuss
Tejas Sanap
authored andcommitted
Ability to specify the output name for a bin target different from the crate name
1 parent b51439f commit 9e2790f

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)