Skip to content

Commit a4a11ac

Browse files
committed
Auto merge of rust-lang#138704 - Kobzol:ci-llvm-checks, r=onur-ozkan
Simplify CI LLVM checks in bootstrap Extracted out of rust-lang#138591. Apart from simplifying the checks, it will make it easier to run E2E tests of bootstrap on a mostly empty directory without checking out LLVM on CI :) The commits should be mostly self-explanatory. r? `@onur-ozkan`
2 parents 4ac032f + f5c59a4 commit a4a11ac

File tree

8 files changed

+53
-62
lines changed

8 files changed

+53
-62
lines changed

src/bootstrap/src/core/build_steps/gcc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ fn detect_gcc_sha(config: &crate::Config, is_git: bool) -> String {
273273
get_closest_merge_commit(
274274
Some(&config.src),
275275
&config.git_config(),
276-
&[config.src.join("src/gcc"), config.src.join("src/bootstrap/download-ci-gcc-stamp")],
276+
&["src/gcc", "src/bootstrap/download-ci-gcc-stamp"],
277277
)
278278
.unwrap()
279279
} else if let Some(info) = crate::utils::channel::read_commit_info_file(&config.src) {

src/bootstrap/src/core/build_steps/llvm.rs

+13-48
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use std::path::{Path, PathBuf};
1414
use std::sync::OnceLock;
1515
use std::{env, fs};
1616

17-
use build_helper::ci::CiEnv;
1817
use build_helper::git::get_closest_merge_commit;
1918
#[cfg(feature = "tracing")]
2019
use tracing::instrument;
@@ -174,20 +173,19 @@ pub fn prebuilt_llvm_config(
174173
LlvmBuildStatus::ShouldBuild(Meta { stamp, res, out_dir, root: root.into() })
175174
}
176175

176+
/// Paths whose changes invalidate LLVM downloads.
177+
pub const LLVM_INVALIDATION_PATHS: &[&str] = &[
178+
"src/llvm-project",
179+
"src/bootstrap/download-ci-llvm-stamp",
180+
// the LLVM shared object file is named `LLVM-<LLVM-version>-rust-{version}-nightly`
181+
"src/version",
182+
];
183+
177184
/// This retrieves the LLVM sha we *want* to use, according to git history.
178185
pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
179186
let llvm_sha = if is_git {
180-
get_closest_merge_commit(
181-
Some(&config.src),
182-
&config.git_config(),
183-
&[
184-
config.src.join("src/llvm-project"),
185-
config.src.join("src/bootstrap/download-ci-llvm-stamp"),
186-
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
187-
config.src.join("src/version"),
188-
],
189-
)
190-
.unwrap()
187+
get_closest_merge_commit(Some(&config.src), &config.git_config(), LLVM_INVALIDATION_PATHS)
188+
.unwrap()
191189
} else if let Some(info) = crate::utils::channel::read_commit_info_file(&config.src) {
192190
info.sha.trim().to_owned()
193191
} else {
@@ -207,10 +205,9 @@ pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
207205

208206
/// Returns whether the CI-found LLVM is currently usable.
209207
///
210-
/// This checks both the build triple platform to confirm we're usable at all,
211-
/// and then verifies if the current HEAD matches the detected LLVM SHA head,
212-
/// in which case LLVM is indicated as not available.
213-
pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
208+
/// This checks the build triple platform to confirm we're usable at all, and if LLVM
209+
/// with/without assertions is available.
210+
pub(crate) fn is_ci_llvm_available_for_target(config: &Config, asserts: bool) -> bool {
214211
// This is currently all tier 1 targets and tier 2 targets with host tools
215212
// (since others may not have CI artifacts)
216213
// https://doc.rust-lang.org/rustc/platform-support.html#tier-1
@@ -255,41 +252,9 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
255252
return false;
256253
}
257254

258-
if is_ci_llvm_modified(config) {
259-
eprintln!("Detected LLVM as non-available: running in CI and modified LLVM in this change");
260-
return false;
261-
}
262-
263255
true
264256
}
265257

266-
/// Returns true if we're running in CI with modified LLVM (and thus can't download it)
267-
pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool {
268-
// If not running in a CI environment, return false.
269-
if !config.is_running_on_ci {
270-
return false;
271-
}
272-
273-
// In rust-lang/rust managed CI, assert the existence of the LLVM submodule.
274-
if CiEnv::is_rust_lang_managed_ci_job() {
275-
assert!(
276-
config.in_tree_llvm_info.is_managed_git_subrepository(),
277-
"LLVM submodule must be fetched in rust-lang/rust managed CI builders."
278-
);
279-
}
280-
// If LLVM submodule isn't present, skip the change check as it won't work.
281-
else if !config.in_tree_llvm_info.is_managed_git_subrepository() {
282-
return false;
283-
}
284-
285-
let llvm_sha = detect_llvm_sha(config, true);
286-
let head_sha = crate::output(
287-
helpers::git(Some(&config.src)).arg("rev-parse").arg("HEAD").as_command_mut(),
288-
);
289-
let head_sha = head_sha.trim();
290-
llvm_sha == head_sha
291-
}
292-
293258
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
294259
pub struct Llvm {
295260
pub target: TargetSelection,

src/bootstrap/src/core/builder/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ fn test_prebuilt_llvm_config_path_resolution() {
10741074
let config = configure(
10751075
r#"
10761076
[llvm]
1077-
download-ci-llvm = true
1077+
download-ci-llvm = "if-unchanged"
10781078
"#,
10791079
);
10801080

src/bootstrap/src/core/config/config.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use tracing::{instrument, span};
2323

2424
use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
2525
use crate::core::build_steps::llvm;
26+
use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
2627
pub use crate::core::config::flags::Subcommand;
2728
use crate::core::config::flags::{Color, Flags, Warnings};
2829
use crate::core::download::is_download_ci_available;
@@ -3096,7 +3097,14 @@ impl Config {
30963097
download_ci_llvm: Option<StringOrBool>,
30973098
asserts: bool,
30983099
) -> bool {
3099-
let download_ci_llvm = download_ci_llvm.unwrap_or(StringOrBool::Bool(true));
3100+
// We don't ever want to use `true` on CI, as we should not
3101+
// download upstream artifacts if there are any local modifications.
3102+
let default = if self.is_running_on_ci {
3103+
StringOrBool::String("if-unchanged".to_string())
3104+
} else {
3105+
StringOrBool::Bool(true)
3106+
};
3107+
let download_ci_llvm = download_ci_llvm.unwrap_or(default);
31003108

31013109
let if_unchanged = || {
31023110
if self.rust_info.is_from_tarball() {
@@ -3109,13 +3117,13 @@ impl Config {
31093117
#[cfg(not(test))]
31103118
self.update_submodule("src/llvm-project");
31113119

3112-
// Check for untracked changes in `src/llvm-project`.
3120+
// Check for untracked changes in `src/llvm-project` and other important places.
31133121
let has_changes = self
3114-
.last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
3122+
.last_modified_commit(LLVM_INVALIDATION_PATHS, "download-ci-llvm", true)
31153123
.is_none();
31163124

31173125
// Return false if there are untracked changes, otherwise check if CI LLVM is available.
3118-
if has_changes { false } else { llvm::is_ci_llvm_available(self, asserts) }
3126+
if has_changes { false } else { llvm::is_ci_llvm_available_for_target(self, asserts) }
31193127
};
31203128

31213129
match download_ci_llvm {
@@ -3126,8 +3134,15 @@ impl Config {
31263134
);
31273135
}
31283136

3137+
if b && self.is_running_on_ci {
3138+
// On CI, we must always rebuild LLVM if there were any modifications to it
3139+
panic!(
3140+
"`llvm.download-ci-llvm` cannot be set to `true` on CI. Use `if-unchanged` instead."
3141+
);
3142+
}
3143+
31293144
// If download-ci-llvm=true we also want to check that CI llvm is available
3130-
b && llvm::is_ci_llvm_available(self, asserts)
3145+
b && llvm::is_ci_llvm_available_for_target(self, asserts)
31313146
}
31323147
StringOrBool::String(s) if s == "if-unchanged" => if_unchanged(),
31333148
StringOrBool::String(other) => {

src/bootstrap/src/core/config/tests.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::flags::Flags;
1212
use super::{ChangeIdWrapper, Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS};
1313
use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
1414
use crate::core::build_steps::llvm;
15+
use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
1516
use crate::core::config::{LldMode, Target, TargetSelection, TomlConfig};
1617

1718
pub(crate) fn parse(config: &str) -> Config {
@@ -24,13 +25,21 @@ pub(crate) fn parse(config: &str) -> Config {
2425
#[test]
2526
fn download_ci_llvm() {
2627
let config = parse("");
27-
let is_available = llvm::is_ci_llvm_available(&config, config.llvm_assertions);
28+
let is_available = llvm::is_ci_llvm_available_for_target(&config, config.llvm_assertions);
2829
if is_available {
2930
assert!(config.llvm_from_ci);
3031
}
3132

32-
let config = parse("llvm.download-ci-llvm = true");
33-
let is_available = llvm::is_ci_llvm_available(&config, config.llvm_assertions);
33+
let config = Config::parse_inner(
34+
Flags::parse(&[
35+
"check".to_string(),
36+
"--config=/does/not/exist".to_string(),
37+
"--ci".to_string(),
38+
"false".to_string(),
39+
]),
40+
|&_| toml::from_str("llvm.download-ci-llvm = true"),
41+
);
42+
let is_available = llvm::is_ci_llvm_available_for_target(&config, config.llvm_assertions);
3443
if is_available {
3544
assert!(config.llvm_from_ci);
3645
}
@@ -41,7 +50,7 @@ fn download_ci_llvm() {
4150
let if_unchanged_config = parse("llvm.download-ci-llvm = \"if-unchanged\"");
4251
if if_unchanged_config.llvm_from_ci {
4352
let has_changes = if_unchanged_config
44-
.last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
53+
.last_modified_commit(LLVM_INVALIDATION_PATHS, "download-ci-llvm", true)
4554
.is_none();
4655

4756
assert!(

src/bootstrap/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//!
1616
//! More documentation can be found in each respective module below, and you can
1717
//! also check out the `src/bootstrap/README.md` file for more information.
18+
#![cfg_attr(test, allow(unused))]
1819

1920
use std::cell::{Cell, RefCell};
2021
use std::collections::{BTreeSet, HashMap, HashSet};

src/build_helper/src/git.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::path::{Path, PathBuf};
1+
use std::path::Path;
22
use std::process::{Command, Stdio};
33

44
use crate::ci::CiEnv;
@@ -121,7 +121,7 @@ fn git_upstream_merge_base(
121121
pub fn get_closest_merge_commit(
122122
git_dir: Option<&Path>,
123123
config: &GitConfig<'_>,
124-
target_paths: &[PathBuf],
124+
target_paths: &[&str],
125125
) -> Result<String, String> {
126126
let mut git = Command::new("git");
127127

src/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ config_dir="../src/bootstrap/defaults"
88
# Loop through each configuration file in the directory
99
for config_file in "$config_dir"/*.toml;
1010
do
11-
python3 ../x.py check --config $config_file --dry-run
11+
# Disable CI mode, because it is not compatible with all profiles
12+
python3 ../x.py check --config $config_file --dry-run --ci=false
1213
done

0 commit comments

Comments
 (0)