diff options
| author | Jakub Beránek <berykubik@gmail.com> | 2025-06-12 15:41:02 +0200 |
|---|---|---|
| committer | Jakub Beránek <berykubik@gmail.com> | 2025-06-12 15:48:50 +0200 |
| commit | a71b463d2b3ae896db91b6e5ba116c77f1ce7d48 (patch) | |
| tree | 948bec1dd9ace7b5ed597e145f3c6d4fbccb0c25 | |
| parent | dbe15e3e94ac206d212a5f3370edb6f9ac2c4463 (diff) | |
| download | rust-a71b463d2b3ae896db91b6e5ba116c77f1ce7d48.tar.gz rust-a71b463d2b3ae896db91b6e5ba116c77f1ce7d48.zip | |
Move submodule path cache from `parse_gitmodules` to `Builder`
It would not be correct if multiple values of `target_dir` were ever passed to the function in the same process.
| -rw-r--r-- | src/bootstrap/src/core/builder/mod.rs | 21 | ||||
| -rw-r--r-- | src/bootstrap/src/lib.rs | 8 | ||||
| -rw-r--r-- | src/bootstrap/src/utils/helpers.rs | 2 | ||||
| -rw-r--r-- | src/build_helper/src/util.rs | 26 |
4 files changed, 30 insertions, 27 deletions
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 887db683f78..7433f0b0f3b 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -5,7 +5,7 @@ use std::fmt::{self, Debug, Write}; use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; -use std::sync::LazyLock; +use std::sync::{LazyLock, OnceLock}; use std::time::{Duration, Instant}; use std::{env, fs}; @@ -60,6 +60,9 @@ pub struct Builder<'a> { /// to do. For example: with `./x check foo bar` we get `paths=["foo", /// "bar"]`. pub paths: Vec<PathBuf>, + + /// Cached list of submodules from self.build.src. + submodule_paths_cache: OnceLock<Vec<String>>, } impl Deref for Builder<'_> { @@ -687,7 +690,7 @@ impl<'a> ShouldRun<'a> { /// /// [`path`]: ShouldRun::path pub fn paths(mut self, paths: &[&str]) -> Self { - let submodules_paths = build_helper::util::parse_gitmodules(&self.builder.src); + let submodules_paths = self.builder.submodule_paths(); self.paths.insert(PathSet::Set( paths @@ -1180,6 +1183,7 @@ impl<'a> Builder<'a> { stack: RefCell::new(Vec::new()), time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), paths, + submodule_paths_cache: Default::default(), } } @@ -1510,6 +1514,19 @@ impl<'a> Builder<'a> { None } + /// Updates all submodules, and exits with an error if submodule + /// management is disabled and the submodule does not exist. + pub fn require_and_update_all_submodules(&self) { + for submodule in self.submodule_paths() { + self.require_submodule(submodule, None); + } + } + + /// Get all submodules from the src directory. + pub fn submodule_paths(&self) -> &[String] { + self.submodule_paths_cache.get_or_init(|| build_helper::util::parse_gitmodules(&self.src)) + } + /// Ensure that a given step is built, returning its output. This will /// cache the step, so it is safe (and good!) to call this as often as /// needed to ensure that all dependencies are built. diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 215586b32f0..fd874604bbe 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -591,14 +591,6 @@ impl Build { } } - /// Updates all submodules, and exits with an error if submodule - /// management is disabled and the submodule does not exist. - pub fn require_and_update_all_submodules(&self) { - for submodule in build_helper::util::parse_gitmodules(&self.src) { - self.require_submodule(submodule, None); - } - } - /// If any submodule has been initialized already, sync it unconditionally. /// This avoids contributors checking in a submodule change by accident. fn update_existing_submodules(&self) { diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index f2c3e8c0df4..4f361af4bf7 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -98,7 +98,7 @@ pub fn is_dylib(path: &Path) -> bool { /// Return the path to the containing submodule if available. pub fn submodule_path_of(builder: &Builder<'_>, path: &str) -> Option<String> { - let submodule_paths = build_helper::util::parse_gitmodules(&builder.src); + let submodule_paths = builder.submodule_paths(); submodule_paths.iter().find_map(|submodule_path| { if path.starts_with(submodule_path) { Some(submodule_path.to_string()) } else { None } }) diff --git a/src/build_helper/src/util.rs b/src/build_helper/src/util.rs index 72c05c4c48a..80dd6813d13 100644 --- a/src/build_helper/src/util.rs +++ b/src/build_helper/src/util.rs @@ -2,7 +2,6 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::Path; use std::process::Command; -use std::sync::OnceLock; /// Invokes `build_helper::util::detail_exit` with `cfg!(test)` /// @@ -51,25 +50,20 @@ pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> Result<(), ()> { } /// Returns the submodule paths from the `.gitmodules` file in the given directory. -pub fn parse_gitmodules(target_dir: &Path) -> &[String] { - static SUBMODULES_PATHS: OnceLock<Vec<String>> = OnceLock::new(); +pub fn parse_gitmodules(target_dir: &Path) -> Vec<String> { let gitmodules = target_dir.join(".gitmodules"); assert!(gitmodules.exists(), "'{}' file is missing.", gitmodules.display()); - let init_submodules_paths = || { - let file = File::open(gitmodules).unwrap(); + let file = File::open(gitmodules).unwrap(); - let mut submodules_paths = vec![]; - for line in BufReader::new(file).lines().map_while(Result::ok) { - let line = line.trim(); - if line.starts_with("path") { - let actual_path = line.split(' ').last().expect("Couldn't get value of path"); - submodules_paths.push(actual_path.to_owned()); - } + let mut submodules_paths = vec![]; + for line in BufReader::new(file).lines().map_while(Result::ok) { + let line = line.trim(); + if line.starts_with("path") { + let actual_path = line.split(' ').last().expect("Couldn't get value of path"); + submodules_paths.push(actual_path.to_owned()); } + } - submodules_paths - }; - - SUBMODULES_PATHS.get_or_init(|| init_submodules_paths()) + submodules_paths } |
