Skip to content

Commit 6de78d5

Browse files
committed
Add Multiple Build Script (error on stable, error about not implemented on nightly)
1 parent e122cdd commit 6de78d5

File tree

6 files changed

+93
-44
lines changed

6 files changed

+93
-44
lines changed

crates/cargo-util-schemas/manifest.schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,13 @@
549549
{
550550
"description": "Path of Build Script if there's just one script.",
551551
"type": "string"
552+
},
553+
{
554+
"description": "Vector of paths if multiple build script are to be used.",
555+
"type": "array",
556+
"items": {
557+
"type": "string"
558+
}
552559
}
553560
]
554561
},

crates/cargo-util-schemas/src/manifest/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ impl TomlPackage {
260260
TomlPackageBuild::Auto(false) => Ok(None),
261261
TomlPackageBuild::Auto(true) => Err(UnresolvedError),
262262
TomlPackageBuild::SingleScript(value) => Ok(Some(value)),
263+
TomlPackageBuild::MultipleScript(_scripts) => {
264+
unimplemented!("Multiple Build Scripts feature is not implemented yet!")
265+
}
263266
}
264267
}
265268

@@ -1710,6 +1713,9 @@ pub enum TomlPackageBuild {
17101713

17111714
/// Path of Build Script if there's just one script.
17121715
SingleScript(String),
1716+
1717+
/// Vector of paths if multiple build script are to be used.
1718+
MultipleScript(Vec<String>),
17131719
}
17141720

17151721
impl<'de> Deserialize<'de> for TomlPackageBuild {
@@ -1720,6 +1726,7 @@ impl<'de> Deserialize<'de> for TomlPackageBuild {
17201726
UntaggedEnumVisitor::new()
17211727
.bool(|b| Ok(TomlPackageBuild::Auto(b)))
17221728
.string(|s| Ok(TomlPackageBuild::SingleScript(s.to_owned())))
1729+
.seq(|value| value.deserialize().map(TomlPackageBuild::MultipleScript))
17231730
.deserialize(deserializer)
17241731
}
17251732
}

src/cargo/ops/vendor.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -515,24 +515,34 @@ fn prepare_toml_for_vendor(
515515
.as_mut()
516516
.expect("venedored manifests must have packages");
517517
// Validates if build script file exists. If not, warn and ignore.
518-
if let Some(TomlPackageBuild::SingleScript(path)) = &package.build {
519-
let path = paths::normalize_path(Path::new(path));
520-
let included = packaged_files.contains(&path);
521-
let build = if included {
522-
let path = path
523-
.into_os_string()
524-
.into_string()
525-
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
526-
let path = crate::util::toml::normalize_path_string_sep(path);
527-
TomlPackageBuild::SingleScript(path)
528-
} else {
529-
gctx.shell().warn(format!(
530-
"ignoring `package.build` as `{}` is not included in the published package",
531-
path.display()
532-
))?;
533-
TomlPackageBuild::Auto(false)
534-
};
535-
package.build = Some(build);
518+
match &package.build {
519+
Some(TomlPackageBuild::SingleScript(path)) => {
520+
let path = paths::normalize_path(Path::new(path));
521+
let included = packaged_files.contains(&path);
522+
let build = if included {
523+
let path = path
524+
.into_os_string()
525+
.into_string()
526+
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
527+
let path = crate::util::toml::normalize_path_string_sep(path);
528+
TomlPackageBuild::SingleScript(path)
529+
} else {
530+
gctx.shell().warn(format!(
531+
"ignoring `package.build` as `{}` is not included in the published package",
532+
path.display()
533+
))?;
534+
TomlPackageBuild::Auto(false)
535+
};
536+
package.build = Some(build);
537+
}
538+
Some(TomlPackageBuild::MultipleScript(_scripts)) => {
539+
if gctx.cli_unstable().multiple_build_scripts {
540+
unimplemented!("Multiple build script is not implemented yet!");
541+
} else {
542+
bail!("`build = […]` requires `-Z multiple-build-scripts`");
543+
}
544+
}
545+
_ => {}
536546
}
537547

538548
let lib = if let Some(target) = &me.lib {

src/cargo/util/toml/mod.rs

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,16 @@ fn normalize_package_toml<'a>(
669669
.map(|value| field_inherit_with(value, "authors", || inherit()?.authors()))
670670
.transpose()?
671671
.map(manifest::InheritableField::Value);
672+
// Check if multiple build scripts are allowed or not
673+
let multiple_build_scripts = gctx.cli_unstable().multiple_build_scripts;
672674
let build = if is_embedded {
673675
Some(TomlPackageBuild::Auto(false))
674676
} else {
675-
targets::normalize_build(original_package.build.as_ref(), package_root)
677+
targets::normalize_build(
678+
original_package.build.as_ref(),
679+
multiple_build_scripts,
680+
package_root,
681+
)?
676682
};
677683
let metabuild = original_package.metabuild.clone();
678684
let default_target = original_package.default_target.clone();
@@ -2886,24 +2892,35 @@ fn prepare_toml_for_publish(
28862892
let mut package = me.package().unwrap().clone();
28872893
package.workspace = None;
28882894
// Validates if build script file exists. If not, warn and ignore.
2889-
if let Some(TomlPackageBuild::SingleScript(path)) = &package.build {
2890-
let path = Path::new(path).to_path_buf();
2891-
let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);
2892-
let build = if included {
2893-
let path = path
2894-
.into_os_string()
2895-
.into_string()
2896-
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
2897-
let path = normalize_path_string_sep(path);
2898-
TomlPackageBuild::SingleScript(path)
2899-
} else {
2900-
ws.gctx().shell().warn(format!(
2901-
"ignoring `package.build` as `{}` is not included in the published package",
2902-
path.display()
2903-
))?;
2904-
TomlPackageBuild::Auto(false)
2905-
};
2906-
package.build = Some(build);
2895+
match &package.build {
2896+
Some(TomlPackageBuild::SingleScript(path)) => {
2897+
let path = Path::new(path).to_path_buf();
2898+
let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);
2899+
let build = if included {
2900+
let path = path
2901+
.into_os_string()
2902+
.into_string()
2903+
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
2904+
let path = normalize_path_string_sep(path);
2905+
TomlPackageBuild::SingleScript(path)
2906+
} else {
2907+
ws.gctx().shell().warn(format!(
2908+
"ignoring `package.build` as `{}` is not included in the published package",
2909+
path.display()
2910+
))?;
2911+
TomlPackageBuild::Auto(false)
2912+
};
2913+
package.build = Some(build);
2914+
}
2915+
Some(TomlPackageBuild::MultipleScript(_scripts)) => {
2916+
if ws.gctx().cli_unstable().multiple_build_scripts {
2917+
unimplemented!("Multiple build script is not implemented yet!");
2918+
} else {
2919+
bail!("`build = […]` requires `-Z multiple-build-scripts`");
2920+
}
2921+
}
2922+
2923+
_ => {}
29072924
}
29082925
let current_resolver = package
29092926
.resolver

src/cargo/util/toml/targets.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,31 +1078,39 @@ Cargo doesn't know which to use because multiple target files found at `{}` and
10781078
#[tracing::instrument(skip_all)]
10791079
pub fn normalize_build(
10801080
build: Option<&TomlPackageBuild>,
1081+
multiple_build_scripts: bool,
10811082
package_root: &Path,
1082-
) -> Option<TomlPackageBuild> {
1083+
) -> CargoResult<Option<TomlPackageBuild>> {
10831084
const BUILD_RS: &str = "build.rs";
10841085
match build {
10851086
None => {
10861087
// If there is a `build.rs` file next to the `Cargo.toml`, assume it is
10871088
// a build script.
10881089
let build_rs = package_root.join(BUILD_RS);
10891090
if build_rs.is_file() {
1090-
Some(TomlPackageBuild::SingleScript(BUILD_RS.to_owned()))
1091+
Ok(Some(TomlPackageBuild::SingleScript(BUILD_RS.to_owned())))
10911092
} else {
1092-
Some(TomlPackageBuild::Auto(false))
1093+
Ok(Some(TomlPackageBuild::Auto(false)))
10931094
}
10941095
}
10951096
// Explicitly no build script.
1096-
Some(TomlPackageBuild::Auto(false)) => build.cloned(),
1097+
Some(TomlPackageBuild::Auto(false)) => Ok(build.cloned()),
10971098
Some(TomlPackageBuild::SingleScript(build_file)) => {
10981099
let build_file = paths::normalize_path(Path::new(build_file));
10991100
let build = build_file.into_os_string().into_string().expect(
11001101
"`build_file` started as a String and `normalize_path` shouldn't have changed that",
11011102
);
1102-
Some(TomlPackageBuild::SingleScript(build))
1103+
Ok(Some(TomlPackageBuild::SingleScript(build)))
11031104
}
11041105
Some(TomlPackageBuild::Auto(true)) => {
1105-
Some(TomlPackageBuild::SingleScript(BUILD_RS.to_owned()))
1106+
Ok(Some(TomlPackageBuild::SingleScript(BUILD_RS.to_owned())))
1107+
}
1108+
Some(TomlPackageBuild::MultipleScript(_scripts)) => {
1109+
if multiple_build_scripts {
1110+
unimplemented!("Multiple Build Scripts feature is not implemented yet!");
1111+
} else {
1112+
anyhow::bail!("`build = […]` requires `-Z multiple-build-scripts`");
1113+
}
11061114
}
11071115
}
11081116
}

tests/testsuite/bad_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2733,7 +2733,7 @@ fn bad_opt_level() {
27332733
p.cargo("check")
27342734
.with_status(101)
27352735
.with_stderr_data(str![[r#"
2736-
[ERROR] invalid type: integer `3`, expected a boolean or string
2736+
[ERROR] invalid type: integer `3`, expected a boolean, string or array
27372737
--> Cargo.toml:7:25
27382738
|
27392739
7 | build = 3

0 commit comments

Comments
 (0)