mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Accessing each build script's OUT_DIR
and in the correct order (#15776)
Hi Everyone! This PR is aimed to have some improvements over #15704 ### What does this PR try to resolve? Now, multiple build scripts are built correctly. But there are some underlying issues, that this PR is targeting. - Preserving the order of the build scripts: Earlier the build scripts were sorted by default, but now, the order will be preserved. ### How to test and review this PR? There is a feature gate `multiple-build-scripts` that can be passed via `cargo-features` in `Cargo.toml`. So, you have to add ```toml cargo-features = ["multiple-build-scripts"] ``` Preferably on the top of the `Cargo.toml` and use nightly toolchain to use the feature
This commit is contained in:
commit
e87ec1a12a
@ -30,7 +30,9 @@ use crate::core::dependency::{Artifact, ArtifactKind, ArtifactTarget, DepKind};
|
||||
use crate::core::profiles::{Profile, Profiles, UnitFor};
|
||||
use crate::core::resolver::Resolve;
|
||||
use crate::core::resolver::features::{FeaturesFor, ResolvedFeatures};
|
||||
use crate::core::{Dependency, Package, PackageId, PackageSet, Target, TargetKind, Workspace};
|
||||
use crate::core::{
|
||||
Dependency, Feature, Package, PackageId, PackageSet, Target, TargetKind, Workspace,
|
||||
};
|
||||
use crate::ops::resolve_all_features;
|
||||
use crate::util::GlobalContext;
|
||||
use crate::util::interning::InternedString;
|
||||
@ -142,8 +144,27 @@ pub fn build_unit_dependencies<'a, 'gctx>(
|
||||
// which affect the determinism of the build itself. As a result be sure
|
||||
// that dependency lists are always sorted to ensure we've always got a
|
||||
// deterministic output.
|
||||
for list in state.unit_dependencies.values_mut() {
|
||||
list.sort();
|
||||
for (unit, list) in &mut state.unit_dependencies {
|
||||
let is_multiple_build_scripts_enabled = unit
|
||||
.pkg
|
||||
.manifest()
|
||||
.unstable_features()
|
||||
.require(Feature::multiple_build_scripts())
|
||||
.is_ok();
|
||||
|
||||
if is_multiple_build_scripts_enabled {
|
||||
list.sort_by_key(|unit_dep| {
|
||||
if unit_dep.unit.target.is_custom_build() {
|
||||
// We do not sort build scripts to preserve the user-defined order.
|
||||
// In terms of determinism, we are assuming nothing interferes with order from when the user set it in `Cargo.toml` to here
|
||||
(0, None)
|
||||
} else {
|
||||
(1, Some(unit_dep.clone()))
|
||||
}
|
||||
});
|
||||
} else {
|
||||
list.sort();
|
||||
}
|
||||
}
|
||||
trace!("ALL UNIT DEPENDENCIES {:#?}", state.unit_dependencies);
|
||||
|
||||
|
@ -608,6 +608,85 @@ Hello, from Build Script 2!
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn build_script_with_conflicts_reverse_sorted() {
|
||||
// In this, multiple scripts create file with same name in their respective OUT_DIR.
|
||||
// It is different from above because `package.build` is not sorted in this.
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["multiple-build-scripts"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
build = ["build2.rs", "build1.rs"]
|
||||
"#,
|
||||
)
|
||||
// OUT_DIR is set to the lexicographically largest build script's OUT_DIR by default
|
||||
.file(
|
||||
"src/main.rs",
|
||||
r#"
|
||||
include!(concat!(env!("OUT_DIR"), "/foo.rs"));
|
||||
fn main() {
|
||||
println!("{}", message());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"build1.rs",
|
||||
r#"
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("foo.rs");
|
||||
fs::write(
|
||||
&dest_path,
|
||||
"pub fn message() -> &'static str {
|
||||
\"Hello, from Build Script 1!\"
|
||||
}
|
||||
"
|
||||
).unwrap();
|
||||
}"#,
|
||||
)
|
||||
.file(
|
||||
"build2.rs",
|
||||
r#"
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("foo.rs");
|
||||
fs::write(
|
||||
&dest_path,
|
||||
"pub fn message() -> &'static str {
|
||||
\"Hello, from Build Script 2!\"
|
||||
}
|
||||
"
|
||||
).unwrap();
|
||||
}"#,
|
||||
)
|
||||
.build();
|
||||
|
||||
p.cargo("run -v")
|
||||
.masquerade_as_nightly_cargo(&["multiple-build-scripts"])
|
||||
.with_status(0)
|
||||
.with_stdout_data(str![[r#"
|
||||
Hello, from Build Script 1!
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rerun_untracks_other_files() {
|
||||
let p = project()
|
||||
|
Loading…
x
Reference in New Issue
Block a user