Skip to content

[WIP] feat: Multiple build scripts #15630

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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

namanlp
Copy link
Contributor

@namanlp namanlp commented Jun 4, 2025

Hi Everyone!

This is PR for first milestone of GSoC Project : Build Script Delegation

What does this PR try to resolve?

Currently, just a single build script is allowed for each package. This PR will allow users to create and use multiple build scripts, and is backward compatible with single script as well as boolean values.

Motivation : This will help users to maintain separate smaller and cleaner build scripts instead of one large build script. This is also necessary for build script delegation.

How to test and review this PR?

There is a feature gate multiple-build-scripts that can be passed with -Z in cargo.

It is not ready for review yet

@rustbot rustbot added the A-unstable Area: nightly unstable support label Jun 4, 2025
@epage
Copy link
Contributor

epage commented Jun 4, 2025

Feel free to rebase on master, rather than merge it.

@rustbot rustbot added A-manifest Area: Cargo.toml issues Command-vendor labels Jun 5, 2025
@namanlp namanlp closed this Jun 6, 2025
@namanlp namanlp force-pushed the multiple-build-scripts-1 branch from 60fe887 to f6bebc3 Compare June 6, 2025 21:16
@namanlp namanlp reopened this Jun 6, 2025
@namanlp namanlp force-pushed the multiple-build-scripts-1 branch 2 times, most recently from b7a6036 to 1d18b6b Compare June 8, 2025 22:09
@@ -1361,6 +1362,7 @@ impl CliUnstable {
"msrv-policy" => self.msrv_policy = parse_empty(k, v)?,
// can also be set in .cargo/config or with and ENV
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,
"multiple-build-scripts" => self.multiple_build_scripts = parse_empty(k, v)?,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit should also add a section for this to our unstable docs. There isn't much to say but we should add more to it as features get implemented.

Comment on lines +263 to 266
TomlPackageBuild::MultipleScript(_scripts) => {
unimplemented!("Multiple Build Scripts feature is not implemented yet!")
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a commit before this one, we should update normalized_build to return Result<Option<&Vec<String>>, UnresolvedError> to avoid this unimplemented!

Comment on lines +518 to +544
match &package.build {
Some(TomlPackageBuild::SingleScript(path)) => {
let path = paths::normalize_path(Path::new(path));
let included = packaged_files.contains(&path);
let build = if included {
let path = path
.into_os_string()
.into_string()
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
let path = crate::util::toml::normalize_path_string_sep(path);
TomlPackageBuild::SingleScript(path)
} else {
gctx.shell().warn(format!(
"ignoring `package.build` as `{}` is not included in the published package",
path.display()
))?;
TomlPackageBuild::Auto(false)
};
package.build = Some(build);
}
Some(TomlPackageBuild::MultipleScript(_scripts)) => {
if gctx.cli_unstable().multiple_build_scripts {
unimplemented!("Multiple build script is not implemented yet!");
} else {
bail!("`build = […]` requires `-Z multiple-build-scripts`");
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend unifying this code so there is a single code path for single or multiple scripts.

Maybe something like https://doc.rust-lang.org/std/option/enum.Option.html#method.as_slice could help

Comment on lines 673 to 677
let multiple_build_scripts = gctx.cli_unstable().multiple_build_scripts;
let build = if is_embedded {
Some(TomlPackageBuild::Auto(false))
} else {
targets::normalize_build(original_package.build.as_ref(), package_root)
targets::normalize_build(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"the hackiest hack is the best hack"
or
"when implementing short-lived or hacky code, be as surgical as possible"

I'd recommend we do the unstable check here, rather than updating normalize_builds API to take in a parameter related to this

@@ -840,6 +840,7 @@ unstable_cli_options!(
minimal_versions: bool = ("Resolve minimal dependency versions instead of maximum"),
msrv_policy: bool = ("Enable rust-version aware policy within cargo"),
mtime_on_use: bool = ("Configure Cargo to update the mtime of used files"),
multiple_build_scripts: bool = ("Enables the use of multiple build scripts"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I overlooked this before, this was implemented as a -Z when this needs to be a cargo_features.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, replaced it with cargo_features

Comment on lines 2894 to 2895
// Validates if build script file exists. If not, warn and ignore.
if let Some(TomlPackageBuild::SingleScript(path)) = &package.build {
let path = Path::new(path).to_path_buf();
let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);
let build = if included {
let path = path
.into_os_string()
.into_string()
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
let path = normalize_path_string_sep(path);
TomlPackageBuild::SingleScript(path)
} else {
ws.gctx().shell().warn(format!(
"ignoring `package.build` as `{}` is not included in the published package",
path.display()
))?;
TomlPackageBuild::Auto(false)
};
package.build = Some(build);
match &package.build {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto what I said with vendor

}
Some(TomlPackageBuild::MultipleScript(_scripts)) => {
if multiple_build_scripts {
unimplemented!("Multiple Build Scripts feature is not implemented yet!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go ahead and do this in this commit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I'd like to see runtime errors, rather than panics for when we cut users off from this feature.

@namanlp namanlp force-pushed the multiple-build-scripts-1 branch from 0321144 to 6de78d5 Compare June 10, 2025 22:39
@rustbot rustbot added the A-documenting-cargo-itself Area: Cargo's documentation label Jun 10, 2025
@namanlp namanlp force-pushed the multiple-build-scripts-1 branch from 6de78d5 to 158dd35 Compare June 10, 2025 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-documenting-cargo-itself Area: Cargo's documentation A-manifest Area: Cargo.toml issues A-unstable Area: nightly unstable support Command-vendor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants