Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cargo: fix inconsistent dashes in lib.name #12640

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
cargo: allow dashes in lib.name
Change the cargo TOML parser to allow dashes in `lib.name`.

Cargo currently refuses explicit library names if they contain a dash.
However, if no library name is specified, the package-name will be used,
which itself can contain dashes. This leads to packages with `lib.name`
containing dashes, if their package-name contains dashes.

Drop this requirement and allow explicit `lib.name` configurations to
contain dashes.

The current ecosystem clearly allows `lib.name` to contain dashes,
given that `cargo metadata` already reports such names for any package
with a dash. It looks like an oversight that any explicit configuration
is not allowed to include dashes.

All consumers of `lib.name` already use `Target.crate_name()` rather
than `Target.name()` if a sanitized name is required. Therefore, they
already replace dashes with underscores.

Last but not least, the current documentation is simply wrong in stating
that `lib.name` defaults to the package-name with dashes replaced by
underscores. Cargo never replaces dashes for `lib.name`, and `cargo
metadata` and friends already happily show `lib.name` with dashes. Cargo
merely replaces dashes with underscores to retrieve the crate-name of a
target, which is then used as stem for library artifacts.
  • Loading branch information
dvdhrm committed Sep 7, 2023
commit 27dda17466784aa0f309153cc1d2e1b9e485184c
16 changes: 4 additions & 12 deletions src/cargo/util/toml/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,10 @@ fn clean_lib(
) -> CargoResult<Option<Target>> {
let inferred = inferred_lib(package_root);
let lib = match toml_lib {
Some(lib) => {
if let Some(ref name) = lib.name {
// XXX: other code paths dodge this validation
if name.contains('-') {
anyhow::bail!("library target names cannot contain hyphens: {}", name)
}
}
Some(TomlTarget {
name: lib.name.clone().or_else(|| Some(package_name.to_owned())),
..lib.clone()
})
}
Some(lib) => Some(TomlTarget {
name: lib.name.clone().or_else(|| Some(package_name.to_owned())),
..lib.clone()
}),
None => inferred.as_ref().map(|lib| TomlTarget {
name: Some(package_name.to_string()),
path: Some(PathValue(lib.clone())),
Expand Down
13 changes: 7 additions & 6 deletions src/doc/src/reference/cargo-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,15 @@ required-features = [] # Features required to build this target (N/A for lib).

### The `name` field

The `name` field specifies the name of the target, which corresponds to the
filename of the artifact that will be generated. For a library, this is the
crate name that dependencies will use to reference it.
The `name` field specifies the name of the target. For a binary it corresponds
to the filename of the artifact that will be generated. For a library, with any
dashes replaced with underscores, it corresponds to the stem used in the
produced library artifact, as well as the name that dependencies will use to
reference the library crate.

For the `[lib]` and the default binary (`src/main.rs`), this defaults to the
name of the package, with any dashes replaced with underscores. For other
[auto discovered](#target-auto-discovery) targets, it defaults to the
directory or file name.
name of the package. For other [auto discovered](#target-auto-discovery)
targets, it defaults to the directory or file name.

This is required for all targets except `[lib]`.

Expand Down
32 changes: 0 additions & 32 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3496,38 +3496,6 @@ fn dashes_to_underscores() {
assert!(p.bin("foo-bar").is_file());
}

#[cargo_test]
fn dashes_in_crate_name_bad() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []

[lib]
name = "foo-bar"
"#,
)
.file("src/lib.rs", "")
.file("src/main.rs", "extern crate foo_bar; fn main() {}")
.build();

p.cargo("build -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`

Caused by:
library target names cannot contain hyphens: foo-bar
",
)
.run();
}

#[cargo_test]
fn rustc_env_var() {
let p = project().file("src/lib.rs", "").build();
Expand Down
Loading