Skip to content

Commit

Permalink
Auto merge of #9627 - whereistejas:many-bin-names, r=ehuss
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Aug 11, 2021
2 parents b51439f + 9e2790f commit 3d3ddd2
Show file tree
Hide file tree
Showing 11 changed files with 376 additions and 9 deletions.
15 changes: 11 additions & 4 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,18 @@ impl FileType {
/// The filename for this FileType that Cargo should use when "uplifting"
/// it to the destination directory.
pub fn uplift_filename(&self, target: &Target) -> String {
let name = if self.should_replace_hyphens {
target.crate_name()
} else {
target.name().to_string()
let name = match target.binary_filename() {
Some(name) => name,
None => {
// For binary crate type, `should_replace_hyphens` will always be false.
if self.should_replace_hyphens {
target.crate_name()
} else {
target.name().to_string()
}
}
};

format!("{}{}{}", self.prefix, name, self.suffix)
}

Expand Down
7 changes: 6 additions & 1 deletion src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,12 @@ impl<'cfg> Compilation<'cfg> {
/// that are only relevant in a context that has a unit
fn fill_rustc_tool_env(mut cmd: ProcessBuilder, unit: &Unit) -> ProcessBuilder {
if unit.target.is_bin() {
cmd.env("CARGO_BIN_NAME", unit.target.name());
let name = unit
.target
.binary_filename()
.unwrap_or(unit.target.name().to_string());

cmd.env("CARGO_BIN_NAME", name);
}
cmd.env("CARGO_CRATE_NAME", unit.target.crate_name());
cmd
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
let meta = &self.metas[unit];
let meta_opt = meta.use_extra_filename.then(|| meta.meta_hash.to_string());
let path = out_dir.join(file_type.output_filename(&unit.target, meta_opt.as_deref()));

// If, the `different_binary_name` feature is enabled, the name of the hardlink will
// be the name of the binary provided by the user in `Cargo.toml`.
let hardlink = self.uplift_to(unit, &file_type, &path);
let export_path = if unit.target.is_custom_build() {
None
Expand Down
5 changes: 4 additions & 1 deletion src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,10 @@ fn build_base_args(
let exe_path = cx
.files()
.bin_link_for_target(bin_target, unit.kind, cx.bcx)?;
let key = format!("CARGO_BIN_EXE_{}", bin_target.name());
let name = bin_target
.binary_filename()
.unwrap_or(bin_target.name().to_string());
let key = format!("CARGO_BIN_EXE_{}", name);
cmd.env(&key, exe_path);
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,9 @@ features! {

// Allow to specify which codegen backend should be used.
(unstable, codegen_backend, "", "reference/unstable.html#codegen-backend"),

// Allow specifying different binary name apart from the crate name
(unstable, different_binary_name, "", "reference/unstable.html#different-binary-name"),
}

pub struct Feature {
Expand Down
14 changes: 13 additions & 1 deletion src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ pub struct Target {
struct TargetInner {
kind: TargetKind,
name: String,
// Note that `bin_name` is used for the cargo-feature `different_binary_name`
bin_name: Option<String>,
// Note that the `src_path` here is excluded from the `Hash` implementation
// as it's absolute currently and is otherwise a little too brittle for
// causing rebuilds. Instead the hash for the path that we send to the
Expand Down Expand Up @@ -350,6 +352,7 @@ compact_debug! {
[debug_the_fields(
kind
name
bin_name
src_path
required_features
tested
Expand Down Expand Up @@ -627,6 +630,7 @@ impl Target {
inner: Arc::new(TargetInner {
kind: TargetKind::Bin,
name: String::new(),
bin_name: None,
src_path,
required_features: None,
doc: false,
Expand Down Expand Up @@ -662,6 +666,7 @@ impl Target {

pub fn bin_target(
name: &str,
bin_name: Option<String>,
src_path: PathBuf,
required_features: Option<Vec<String>>,
edition: Edition,
Expand All @@ -670,6 +675,7 @@ impl Target {
target
.set_kind(TargetKind::Bin)
.set_name(name)
.set_binary_name(bin_name)
.set_required_features(required_features)
.set_doc(true);
target
Expand Down Expand Up @@ -911,11 +917,17 @@ impl Target {
Arc::make_mut(&mut self.inner).name = name.to_string();
self
}
pub fn set_binary_name(&mut self, bin_name: Option<String>) -> &mut Target {
Arc::make_mut(&mut self.inner).bin_name = bin_name;
self
}
pub fn set_required_features(&mut self, required_features: Option<Vec<String>>) -> &mut Target {
Arc::make_mut(&mut self.inner).required_features = required_features;
self
}

pub fn binary_filename(&self) -> Option<String> {
self.inner.bin_name.clone()
}
pub fn description_named(&self) -> String {
match self.kind() {
TargetKind::Lib(..) => "lib".to_string(),
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,8 @@ struct TomlTarget {
crate_type2: Option<Vec<String>>,

path: Option<PathValue>,
// Note that `filename` is used for the cargo-feature `different_binary_name`
filename: Option<String>,
test: Option<bool>,
doctest: Option<bool>,
bench: Option<bool>,
Expand Down
17 changes: 15 additions & 2 deletions src/cargo/util/toml/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,14 @@ fn clean_bins(
"autobins",
);

// This loop performs basic checks on each of the TomlTarget in `bins`.
for bin in &bins {
// For each binary, check if the `filename` parameter is populated. If it is,
// check if the corresponding cargo feature has been activated.
if bin.filename.is_some() {
features.require(Feature::different_binary_name())?;
}

validate_target_name(bin, "binary", "bin", warnings)?;

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

let mut target =
Target::bin_target(&bin.name(), path, bin.required_features.clone(), edition);
let mut target = Target::bin_target(
&bin.name(),
bin.filename.clone(),
path,
bin.required_features.clone(),
edition,
);

configure(features, bin, &mut target)?;
result.push(target);
}
Expand Down
27 changes: 27 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Each new feature described below should explain how to use it.
* Output behavior
* [out-dir](#out-dir) — Adds a directory where artifacts are copied to.
* [terminal-width](#terminal-width) — Tells rustc the width of the terminal so that long diagnostic messages can be truncated to be more readable.
* [Different binary name](#different-binary-name) — Assign a name to the built binary that is seperate from the crate name.
* Compile behavior
* [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.
* [doctest-xcompile](#doctest-xcompile) — Supports running doctests with the `--target` flag.
Expand Down Expand Up @@ -1288,6 +1289,32 @@ The primary use case is to run `cargo rustc --print=cfg` to get config values
for the appropriate target and influenced by any other RUSTFLAGS.


### Different binary name

* Tracking Issue: [#9778](https://github.com/rust-lang/cargo/issues/9778)
* PR: [#9627](https://github.com/rust-lang/cargo/pull/9627)

The `different-binary-name` feature allows setting the filename of the binary without having to obey the
restrictions placed on crate names. For example, the crate name must use only `alphanumeric` characters
or `-` or `_`, and cannot be empty.

The `filename` parameter should **not** include the binary extension, `cargo` will figure out the appropriate
extension and use that for the binary on its own.

The `filename` parameter is only available in the `[[bin]]` section of the manifest.

```toml
cargo-features = ["different-binary-name"]

[project]
name = "foo"
version = "0.0.1"

[[bin]]
name = "foo"
filename = "007bar"
path = "src/main.rs"
```

## Stabilized and removed features

Expand Down
Loading

0 comments on commit 3d3ddd2

Please sign in to comment.