Skip to content

Commit 4d74451

Browse files
committed
Validate the uniqueness of build scripts
1 parent 93515ac commit 4d74451

File tree

2 files changed

+34
-27
lines changed

2 files changed

+34
-27
lines changed

src/cargo/util/toml/targets.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
//! It is a bit tricky because we need match explicit information from `Cargo.toml`
1111
//! with implicit info in directory layout.
1212
13-
use std::collections::HashSet;
13+
use std::collections::{HashMap, HashSet};
14+
use std::fmt::Write;
1415
use std::fs::{self, DirEntry};
1516
use std::path::{Path, PathBuf};
1617

@@ -104,6 +105,7 @@ pub(super) fn to_targets(
104105
if metabuild.is_some() {
105106
anyhow::bail!("cannot specify both `metabuild` and `build`");
106107
}
108+
validate_unique_build_scripts(custom_build)?;
107109
for script in custom_build {
108110
let script_path = Path::new(script);
109111
let name = format!(
@@ -901,6 +903,31 @@ fn validate_unique_names(targets: &[TomlTarget], target_kind: &str) -> CargoResu
901903
Ok(())
902904
}
903905

906+
/// Will check a list of build scripts, and make sure script file stems are unique within a vector.
907+
fn validate_unique_build_scripts(scripts: &[String]) -> CargoResult<()> {
908+
let mut seen = HashMap::new();
909+
for script in scripts {
910+
let stem = Path::new(script).file_stem().unwrap().to_str().unwrap();
911+
seen.entry(stem)
912+
.or_insert_with(Vec::new)
913+
.push(script.as_str());
914+
}
915+
let mut conflict_file_stem = false;
916+
let mut err_msg = String::from(
917+
"found build scripts with duplicate file stems, but all build scripts must have a unique file stem",
918+
);
919+
for (stem, paths) in seen {
920+
if paths.len() > 1 {
921+
conflict_file_stem = true;
922+
write!(&mut err_msg, "\n for stem `{stem}`: {}", paths.join(", "))?;
923+
}
924+
}
925+
if conflict_file_stem {
926+
anyhow::bail!(err_msg);
927+
}
928+
Ok(())
929+
}
930+
904931
fn configure(
905932
toml: &TomlTarget,
906933
target: &mut Target,

tests/testsuite/build_scripts_multiple.rs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -870,32 +870,12 @@ fn duplicate_build_script_stems() {
870870
.masquerade_as_nightly_cargo(&["multiple-build-scripts"])
871871
.with_status(101)
872872
.with_stderr_data(str![[r#"
873-
[WARNING] output filename collision.
874-
The build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)` has the same output filename as the build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)`.
875-
Colliding filename is: [ROOT]/foo/target/debug/build/foo-[HASH]/build_script_build1-[HASH]
876-
The targets should have unique names.
877-
Consider changing their names to be unique or compiling them separately.
878-
This may become a hard error in the future; see <https://github.com/rust-lang/cargo/issues/6313>.
879-
[WARNING] output filename collision.
880-
The build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)` has the same output filename as the build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)`.
881-
Colliding filename is: [ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build1
882-
The targets should have unique names.
883-
Consider changing their names to be unique or compiling them separately.
884-
This may become a hard error in the future; see <https://github.com/rust-lang/cargo/issues/6313>.
885-
[WARNING] output filename collision.
886-
The build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)` has the same output filename as the build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)`.
887-
Colliding filename is: [ROOT]/foo/target/debug/build/foo-[HASH]/build_script_build1-[HASH].dwp
888-
The targets should have unique names.
889-
Consider changing their names to be unique or compiling them separately.
890-
This may become a hard error in the future; see <https://github.com/rust-lang/cargo/issues/6313>.
891-
[WARNING] output filename collision.
892-
The build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)` has the same output filename as the build-script target `build-script-build1` in package `foo v0.1.0 ([ROOT]/foo)`.
893-
Colliding filename is: [ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build1.dwp
894-
The targets should have unique names.
895-
Consider changing their names to be unique or compiling them separately.
896-
This may become a hard error in the future; see <https://github.com/rust-lang/cargo/issues/6313>.
897-
[COMPILING] foo v0.1.0 ([ROOT]/foo)
898-
...
873+
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
874+
875+
Caused by:
876+
found build scripts with duplicate file stems, but all build scripts must have a unique file stem
877+
for stem `build1`: build1.rs, foo/build1.rs
878+
899879
"#]])
900880
.run();
901881
}

0 commit comments

Comments
 (0)