mirror of https://github.com/rust-lang/rust.git
chore: remove `rustc-workspace-hack`
Co-authored-by: Scott Schafer <schaferjscott@gmail.com> Co-authored-by: Eric Huss <eric@huss.org>
This commit is contained in:
parent
1cfaa3431e
commit
befa5c98c9
|
@ -2773,7 +2773,6 @@ dependencies = [
|
||||||
name = "rls"
|
name = "rls"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-workspace-hack",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -2885,11 +2884,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-workspace-hack"
|
name = "rustc-workspace-hack"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
dependencies = [
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"libc",
|
checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb"
|
||||||
"regex",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_abi"
|
name = "rustc_abi"
|
||||||
|
|
|
@ -100,10 +100,6 @@ miniz_oxide.debug = 0
|
||||||
object.debug = 0
|
object.debug = 0
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
|
|
||||||
# here
|
|
||||||
rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
|
|
||||||
|
|
||||||
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on
|
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on
|
||||||
# here
|
# here
|
||||||
rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
|
rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
|
||||||
|
|
|
@ -238,8 +238,6 @@ pub struct Build {
|
||||||
ci_env: CiEnv,
|
ci_env: CiEnv,
|
||||||
delayed_failures: RefCell<Vec<String>>,
|
delayed_failures: RefCell<Vec<String>>,
|
||||||
prerelease_version: Cell<Option<u32>>,
|
prerelease_version: Cell<Option<u32>>,
|
||||||
tool_artifacts:
|
|
||||||
RefCell<HashMap<TargetSelection, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
|
|
||||||
|
|
||||||
#[cfg(feature = "build-metrics")]
|
#[cfg(feature = "build-metrics")]
|
||||||
metrics: metrics::BuildMetrics,
|
metrics: metrics::BuildMetrics,
|
||||||
|
@ -458,7 +456,6 @@ impl Build {
|
||||||
ci_env: CiEnv::current(),
|
ci_env: CiEnv::current(),
|
||||||
delayed_failures: RefCell::new(Vec::new()),
|
delayed_failures: RefCell::new(Vec::new()),
|
||||||
prerelease_version: Cell::new(None),
|
prerelease_version: Cell::new(None),
|
||||||
tool_artifacts: Default::default(),
|
|
||||||
|
|
||||||
#[cfg(feature = "build-metrics")]
|
#[cfg(feature = "build-metrics")]
|
||||||
metrics: metrics::BuildMetrics::init(),
|
metrics: metrics::BuildMetrics::init(),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -120,136 +119,10 @@ impl Step for ToolBuild {
|
||||||
&self.target,
|
&self.target,
|
||||||
);
|
);
|
||||||
builder.info(&msg);
|
builder.info(&msg);
|
||||||
let mut duplicates = Vec::new();
|
let is_expected = compile::stream_cargo(builder, cargo, vec![], &mut |_msg| {
|
||||||
let is_expected = compile::stream_cargo(builder, cargo, vec![], &mut |msg| {
|
return;
|
||||||
// Only care about big things like the RLS/Cargo for now
|
|
||||||
match tool {
|
|
||||||
"rls" | "clippy-driver" | "miri" | "rustfmt" => {}
|
|
||||||
|
|
||||||
_ => return,
|
|
||||||
}
|
|
||||||
let (id, features, filenames) = match msg {
|
|
||||||
compile::CargoMessage::CompilerArtifact {
|
|
||||||
package_id,
|
|
||||||
features,
|
|
||||||
filenames,
|
|
||||||
target: _,
|
|
||||||
} => (package_id, features, filenames),
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
let features = features.iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
for path in filenames {
|
|
||||||
let val = (tool, PathBuf::from(&*path), features.clone());
|
|
||||||
// we're only interested in deduplicating rlibs for now
|
|
||||||
if val.1.extension().and_then(|s| s.to_str()) != Some("rlib") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't worry about compiles that turn out to be host
|
|
||||||
// dependencies or build scripts. To skip these we look for
|
|
||||||
// anything that goes in `.../release/deps` but *doesn't* go in
|
|
||||||
// `$target/release/deps`. This ensure that outputs in
|
|
||||||
// `$target/release` are still considered candidates for
|
|
||||||
// deduplication.
|
|
||||||
if let Some(parent) = val.1.parent() {
|
|
||||||
if parent.ends_with("release/deps") {
|
|
||||||
let maybe_target = parent
|
|
||||||
.parent()
|
|
||||||
.and_then(|p| p.parent())
|
|
||||||
.and_then(|p| p.file_name())
|
|
||||||
.and_then(|p| p.to_str())
|
|
||||||
.unwrap();
|
|
||||||
if maybe_target != &*target.triple {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record that we've built an artifact for `id`, and if one was
|
|
||||||
// already listed then we need to see if we reused the same
|
|
||||||
// artifact or produced a duplicate.
|
|
||||||
let mut artifacts = builder.tool_artifacts.borrow_mut();
|
|
||||||
let prev_artifacts = artifacts.entry(target).or_default();
|
|
||||||
let prev = match prev_artifacts.get(&*id) {
|
|
||||||
Some(prev) => prev,
|
|
||||||
None => {
|
|
||||||
prev_artifacts.insert(id.to_string(), val);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if prev.1 == val.1 {
|
|
||||||
return; // same path, same artifact
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the paths are different and one of them *isn't* inside of
|
|
||||||
// `release/deps`, then it means it's probably in
|
|
||||||
// `$target/release`, or it's some final artifact like
|
|
||||||
// `libcargo.rlib`. In these situations Cargo probably just
|
|
||||||
// copied it up from `$target/release/deps/libcargo-xxxx.rlib`,
|
|
||||||
// so if the features are equal we can just skip it.
|
|
||||||
let prev_no_hash = prev.1.parent().unwrap().ends_with("release/deps");
|
|
||||||
let val_no_hash = val.1.parent().unwrap().ends_with("release/deps");
|
|
||||||
if prev.2 == val.2 || !prev_no_hash || !val_no_hash {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and otherwise this looks like we duplicated some sort of
|
|
||||||
// compilation, so record it to generate an error later.
|
|
||||||
duplicates.push((id.to_string(), val, prev.clone()));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if is_expected && !duplicates.is_empty() {
|
|
||||||
eprintln!(
|
|
||||||
"duplicate artifacts found when compiling a tool, this \
|
|
||||||
typically means that something was recompiled because \
|
|
||||||
a transitive dependency has different features activated \
|
|
||||||
than in a previous build:\n"
|
|
||||||
);
|
|
||||||
let (same, different): (Vec<_>, Vec<_>) =
|
|
||||||
duplicates.into_iter().partition(|(_, cur, prev)| cur.2 == prev.2);
|
|
||||||
if !same.is_empty() {
|
|
||||||
eprintln!(
|
|
||||||
"the following dependencies are duplicated although they \
|
|
||||||
have the same features enabled:"
|
|
||||||
);
|
|
||||||
for (id, cur, prev) in same {
|
|
||||||
eprintln!(" {}", id);
|
|
||||||
// same features
|
|
||||||
eprintln!(" `{}` ({:?})\n `{}` ({:?})", cur.0, cur.1, prev.0, prev.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !different.is_empty() {
|
|
||||||
eprintln!("the following dependencies have different features:");
|
|
||||||
for (id, cur, prev) in different {
|
|
||||||
eprintln!(" {}", id);
|
|
||||||
let cur_features: HashSet<_> = cur.2.into_iter().collect();
|
|
||||||
let prev_features: HashSet<_> = prev.2.into_iter().collect();
|
|
||||||
eprintln!(
|
|
||||||
" `{}` additionally enabled features {:?} at {:?}",
|
|
||||||
cur.0,
|
|
||||||
&cur_features - &prev_features,
|
|
||||||
cur.1
|
|
||||||
);
|
|
||||||
eprintln!(
|
|
||||||
" `{}` additionally enabled features {:?} at {:?}",
|
|
||||||
prev.0,
|
|
||||||
&prev_features - &cur_features,
|
|
||||||
prev.1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eprintln!();
|
|
||||||
eprintln!(
|
|
||||||
"to fix this you will probably want to edit the local \
|
|
||||||
src/tools/rustc-workspace-hack/Cargo.toml crate, as \
|
|
||||||
that will update the dependency graph to ensure that \
|
|
||||||
these crates all share the same feature set"
|
|
||||||
);
|
|
||||||
panic!("tools should not compile multiple copies of the same crate");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.save_toolstate(
|
builder.save_toolstate(
|
||||||
tool,
|
tool,
|
||||||
if is_expected { ToolState::TestFail } else { ToolState::BuildFail },
|
if is_expected { ToolState::TestFail } else { ToolState::BuildFail },
|
||||||
|
|
|
@ -7,7 +7,3 @@ license = "Apache-2.0/MIT"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.143", features = ["derive"] }
|
serde = { version = "1.0.143", features = ["derive"] }
|
||||||
serde_json = "1.0.83"
|
serde_json = "1.0.83"
|
||||||
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
|
|
||||||
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
|
|
||||||
# for more information.
|
|
||||||
rustc-workspace-hack = "1.0.0"
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "rustc-workspace-hack"
|
|
||||||
version = "1.0.0"
|
|
||||||
license = 'MIT OR Apache-2.0'
|
|
||||||
description = """
|
|
||||||
Hack for the compiler's own build system
|
|
||||||
"""
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "lib.rs"
|
|
||||||
|
|
||||||
# For documentation about what this is and why in the world these dependencies
|
|
||||||
# are appearing, see `README.md`.
|
|
||||||
[dependencies]
|
|
||||||
libc = { version = "0.2", features = ["extra_traits"] }
|
|
||||||
serde_json = { version = "1.0.31", features = ["unbounded_depth"] }
|
|
||||||
# Ensure default features of regex, which are disabled in some scenarios.
|
|
||||||
regex = { version = "1.5.6" }
|
|
|
@ -1,25 +0,0 @@
|
||||||
# `rustc-workspace-hack`
|
|
||||||
|
|
||||||
This crate is a bit of a hack to make workspaces in rustc work a bit better.
|
|
||||||
The rationale for this existence is a bit subtle, but the general idea is that
|
|
||||||
we want commands like `./x.py build src/tools/{clippy,cargo}` to share as
|
|
||||||
many dependencies as possible.
|
|
||||||
|
|
||||||
Each invocation is a different invocation of Cargo, however. Each time Cargo
|
|
||||||
runs a build it will re-resolve the dependency graph, notably selecting
|
|
||||||
different features sometimes for each build.
|
|
||||||
|
|
||||||
For example, let's say there's a very deep dependency like `winapi` in each of
|
|
||||||
these builds. For Cargo, `winapi` has 33 features enabled. In Clippy, however,
|
|
||||||
`winapi` has 22 features enabled. This means that building Cargo and then the
|
|
||||||
Clippy will actually build winapi twice, which in turn will build duplicates
|
|
||||||
of everything that depends on `winapi`. This is bad!
|
|
||||||
|
|
||||||
The goal of this crate is to solve this problem and ensure that the resolved
|
|
||||||
dependency graph for all of these tools is the same in the various subsets of
|
|
||||||
each tool, notably enabling the same features of transitive dependencies.
|
|
||||||
|
|
||||||
All tools vendored here depend on the `rustc-workspace-hack` crate on crates.io.
|
|
||||||
When on crates.io this crate is an empty crate that is just a noop. We override
|
|
||||||
it, however, in this workspace to this crate here, which means we can control
|
|
||||||
crates in the dependency graph for each of these tools.
|
|
|
@ -1 +0,0 @@
|
||||||
// intentionally left blank
|
|
Loading…
Reference in New Issue