make download context lean and remove mutable types

This commit is contained in:
bit-aloo 2025-08-20 23:24:53 +05:30
parent 5ae81c984f
commit 433dc2be44
No known key found for this signature in database
2 changed files with 89 additions and 79 deletions

View file

@ -679,15 +679,11 @@ impl Config {
.unwrap_or_else(|| vec![host_target]);
let llvm_assertions = llvm_assertions_.unwrap_or(false);
let mut target_config = HashMap::new();
let mut download_rustc_commit = None;
let mut llvm_from_ci = false;
let mut channel = "dev".to_string();
let mut out = flags_build_dir
.or(build_build_dir.map(PathBuf::from))
.unwrap_or_else(|| PathBuf::from("build"));
let mut rust_info = GitInfo::Absent;
if cfg!(test) {
// Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly.
@ -730,16 +726,11 @@ impl Config {
);
}
let mut dwn_ctx = DownloadContext {
let dwn_ctx = DownloadContext {
path_modification_cache: path_modification_cache.clone(),
src: &src,
rust_info: rust_info.clone(),
submodules: &build_submodules,
download_rustc_commit: download_rustc_commit.clone(),
host_target,
llvm_from_ci,
target_config: target_config.clone(),
out: out.clone(),
patch_binaries_for_nix: build_patch_binaries_for_nix,
exec_ctx: &exec_ctx,
stage0_metadata: &stage0_metadata,
@ -749,7 +740,7 @@ impl Config {
};
let initial_rustc = build_rustc.unwrap_or_else(|| {
download_beta_toolchain(&dwn_ctx);
download_beta_toolchain(&dwn_ctx, &out);
out.join(host_target).join("stage0").join("bin").join(exe("rustc", host_target))
});
@ -763,7 +754,7 @@ impl Config {
));
let initial_cargo = build_cargo.unwrap_or_else(|| {
download_beta_toolchain(&dwn_ctx);
download_beta_toolchain(&dwn_ctx, &out);
initial_sysroot.join("bin").join(exe("cargo", host_target))
});
@ -771,7 +762,6 @@ impl Config {
if exec_ctx.dry_run() {
out = out.join("tmp-dry-run");
fs::create_dir_all(&out).expect("Failed to create dry-run directory");
dwn_ctx.out = out.clone();
}
let file_content = t!(fs::read_to_string(src.join("src/ci/channel")));
@ -791,8 +781,7 @@ impl Config {
let omit_git_hash = rust_omit_git_hash.unwrap_or(channel == "dev");
rust_info = git_info(&exec_ctx, omit_git_hash, &src);
dwn_ctx.rust_info = rust_info.clone();
let rust_info = git_info(&exec_ctx, omit_git_hash, &src);
if !is_user_configured_rust_channel && rust_info.is_from_tarball() {
channel = ci_channel.into();
@ -823,9 +812,8 @@ impl Config {
);
}
download_rustc_commit =
download_ci_rustc_commit(&dwn_ctx, rust_download_rustc, llvm_assertions);
dwn_ctx.download_rustc_commit = download_rustc_commit.clone();
let mut download_rustc_commit =
download_ci_rustc_commit(&dwn_ctx, &rust_info, rust_download_rustc, llvm_assertions);
if debug_assertions_requested && download_rustc_commit.is_some() {
eprintln!(
@ -834,7 +822,6 @@ impl Config {
);
// We need to put this later down_ci_rustc_commit.
download_rustc_commit = None;
dwn_ctx.download_rustc_commit = None;
}
// We need to override `rust.channel` if it's manually specified when using the CI rustc.
@ -847,9 +834,10 @@ impl Config {
"WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel."
);
channel = read_file_by_commit(&dwn_ctx, Path::new("src/ci/channel"), commit)
.trim()
.to_owned();
channel =
read_file_by_commit(&dwn_ctx, &rust_info, Path::new("src/ci/channel"), commit)
.trim()
.to_owned();
}
if let Some(t) = toml.target {
@ -911,11 +899,15 @@ impl Config {
target_config.insert(TargetSelection::from_user(&triple), target);
}
dwn_ctx.target_config = target_config.clone();
}
llvm_from_ci = parse_download_ci_llvm(&dwn_ctx, llvm_download_ci_llvm, llvm_assertions);
dwn_ctx.llvm_from_ci = llvm_from_ci;
let llvm_from_ci = parse_download_ci_llvm(
&dwn_ctx,
&rust_info,
&download_rustc_commit,
llvm_download_ci_llvm,
llvm_assertions,
);
// We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will
// build our internal lld and use it as the default linker, by setting the `rust.lld` config
@ -976,18 +968,16 @@ impl Config {
if llvm_from_ci {
let triple = &host_target.triple;
let ci_llvm_bin = ci_llvm_root(&dwn_ctx).join("bin");
let ci_llvm_bin = ci_llvm_root(&dwn_ctx, llvm_from_ci, &out).join("bin");
let build_target =
target_config.entry(host_target).or_insert_with(|| Target::from_triple(triple));
dwn_ctx.target_config.entry(host_target).or_insert_with(|| Target::from_triple(triple));
check_ci_llvm!(build_target.llvm_config);
check_ci_llvm!(build_target.llvm_filecheck);
build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", host_target)));
build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", host_target)));
}
let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx));
let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx, &out));
if matches!(rust_lld_mode.unwrap_or_default(), LldMode::SelfContained)
&& !lld_enabled
@ -998,7 +988,7 @@ impl Config {
);
}
if lld_enabled && is_system_llvm(&dwn_ctx, host_target) {
if lld_enabled && is_system_llvm(&dwn_ctx, &target_config, llvm_from_ci, host_target) {
panic!("Cannot enable LLD with `rust.lld = true` when using external llvm-config.");
}
@ -1392,7 +1382,7 @@ impl Config {
/// Returns the content of the given file at a specific commit.
pub(crate) fn read_file_by_commit(&self, file: &Path, commit: &str) -> String {
let dwn_ctx = DownloadContext::from(self);
read_file_by_commit(dwn_ctx, file, commit)
read_file_by_commit(dwn_ctx, &self.rust_info, file, commit)
}
/// Bootstrap embeds a version number into the name of shared libraries it uploads in CI.
@ -1464,7 +1454,7 @@ impl Config {
/// The absolute path to the downloaded LLVM artifacts.
pub(crate) fn ci_llvm_root(&self) -> PathBuf {
let dwn_ctx = DownloadContext::from(self);
ci_llvm_root(dwn_ctx)
ci_llvm_root(dwn_ctx, self.llvm_from_ci, &self.out)
}
/// Directory where the extracted `rustc-dev` component is stored.
@ -1628,7 +1618,7 @@ impl Config {
)]
pub(crate) fn update_submodule(&self, relative_path: &str) {
let dwn_ctx = DownloadContext::from(self);
update_submodule(dwn_ctx, relative_path);
update_submodule(dwn_ctx, &self.rust_info, relative_path);
}
/// Returns true if any of the `paths` have been modified locally.
@ -1744,7 +1734,7 @@ impl Config {
/// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set.
pub fn is_system_llvm(&self, target: TargetSelection) -> bool {
let dwn_ctx = DownloadContext::from(self);
is_system_llvm(dwn_ctx, target)
is_system_llvm(dwn_ctx, &self.target_config, self.llvm_from_ci, target)
}
/// Returns `true` if this is our custom, patched, version of LLVM.
@ -2038,6 +2028,7 @@ pub fn check_stage0_version(
pub fn download_ci_rustc_commit<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
rust_info: &channel::GitInfo,
download_rustc: Option<StringOrBool>,
llvm_assertions: bool,
) -> Option<String> {
@ -2057,7 +2048,7 @@ pub fn download_ci_rustc_commit<'a>(
None | Some(StringOrBool::Bool(false)) => return None,
Some(StringOrBool::Bool(true)) => false,
Some(StringOrBool::String(s)) if s == "if-unchanged" => {
if !dwn_ctx.rust_info.is_managed_git_subrepository() {
if !rust_info.is_managed_git_subrepository() {
println!(
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
);
@ -2071,7 +2062,7 @@ pub fn download_ci_rustc_commit<'a>(
}
};
let commit = if dwn_ctx.rust_info.is_managed_git_subrepository() {
let commit = if rust_info.is_managed_git_subrepository() {
// Look for a version to compare to based on the current commit.
// Only commits merged by bors will have CI artifacts.
let freshness = check_path_modifications_(dwn_ctx, RUSTC_IF_UNCHANGED_ALLOWED_PATHS);
@ -2145,6 +2136,8 @@ pub fn git_config(stage0_metadata: &build_helper::stage0_parser::Stage0) -> GitC
pub fn parse_download_ci_llvm<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
rust_info: &channel::GitInfo,
download_rustc_commit: &Option<String>,
download_ci_llvm: Option<StringOrBool>,
asserts: bool,
) -> bool {
@ -2160,7 +2153,7 @@ pub fn parse_download_ci_llvm<'a>(
let download_ci_llvm = download_ci_llvm.unwrap_or(default);
let if_unchanged = || {
if dwn_ctx.rust_info.is_from_tarball() {
if rust_info.is_from_tarball() {
// Git is needed for running "if-unchanged" logic.
println!("ERROR: 'if-unchanged' is only compatible with Git managed sources.");
crate::exit!(1);
@ -2168,7 +2161,7 @@ pub fn parse_download_ci_llvm<'a>(
// Fetching the LLVM submodule is unnecessary for self-tests.
#[cfg(not(test))]
update_submodule(dwn_ctx, "src/llvm-project");
update_submodule(dwn_ctx, rust_info, "src/llvm-project");
// Check for untracked changes in `src/llvm-project` and other important places.
let has_changes = has_changes_from_upstream(dwn_ctx, LLVM_INVALIDATION_PATHS);
@ -2183,7 +2176,7 @@ pub fn parse_download_ci_llvm<'a>(
match download_ci_llvm {
StringOrBool::Bool(b) => {
if !b && dwn_ctx.download_rustc_commit.is_some() {
if !b && download_rustc_commit.is_some() {
panic!(
"`llvm.download-ci-llvm` cannot be set to `false` if `rust.download-rustc` is set to `true` or `if-unchanged`."
);
@ -2226,9 +2219,13 @@ pub fn has_changes_from_upstream<'a>(
fields(relative_path = ?relative_path),
),
)]
pub(crate) fn update_submodule<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>, relative_path: &str) {
pub(crate) fn update_submodule<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
rust_info: &channel::GitInfo,
relative_path: &str,
) {
let dwn_ctx = dwn_ctx.as_ref();
if dwn_ctx.rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, &dwn_ctx.rust_info) {
if rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, rust_info) {
return;
}
@ -2357,12 +2354,14 @@ pub fn submodules_(submodules: &Option<bool>, rust_info: &channel::GitInfo) -> b
/// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set.
pub fn is_system_llvm<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
target_config: &HashMap<TargetSelection, Target>,
llvm_from_ci: bool,
target: TargetSelection,
) -> bool {
let dwn_ctx = dwn_ctx.as_ref();
match dwn_ctx.target_config.get(&target) {
match target_config.get(&target) {
Some(Target { llvm_config: Some(_), .. }) => {
let ci_llvm = dwn_ctx.llvm_from_ci && is_host_target(&dwn_ctx.host_target, &target);
let ci_llvm = llvm_from_ci && is_host_target(&dwn_ctx.host_target, &target);
!ci_llvm
}
// We're building from the in-tree src/llvm-project sources.
@ -2375,21 +2374,26 @@ pub fn is_host_target(host_target: &TargetSelection, target: &TargetSelection) -
host_target == target
}
pub(crate) fn ci_llvm_root<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>) -> PathBuf {
pub(crate) fn ci_llvm_root<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
llvm_from_ci: bool,
out: &Path,
) -> PathBuf {
let dwn_ctx = dwn_ctx.as_ref();
assert!(dwn_ctx.llvm_from_ci);
dwn_ctx.out.join(dwn_ctx.host_target).join("ci-llvm")
assert!(llvm_from_ci);
out.join(dwn_ctx.host_target).join("ci-llvm")
}
/// Returns the content of the given file at a specific commit.
pub(crate) fn read_file_by_commit<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
rust_info: &channel::GitInfo,
file: &Path,
commit: &str,
) -> String {
let dwn_ctx = dwn_ctx.as_ref();
assert!(
dwn_ctx.rust_info.is_managed_git_subrepository(),
rust_info.is_managed_git_subrepository(),
"`Config::read_file_by_commit` is not supported in non-git sources."
);

View file

@ -9,9 +9,8 @@ use std::sync::{Arc, Mutex, OnceLock};
use build_helper::git::PathFreshness;
use xz2::bufread::XzDecoder;
use crate::core::config::{BUILDER_CONFIG_FILENAME, Target, TargetSelection};
use crate::core::config::{BUILDER_CONFIG_FILENAME, TargetSelection};
use crate::utils::build_stamp::BuildStamp;
use crate::utils::channel;
use crate::utils::exec::{ExecutionContext, command};
use crate::utils::helpers::{exe, hex_encode, move_file};
use crate::{Config, t};
@ -73,7 +72,7 @@ impl Config {
fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
let dwn_ctx: DownloadContext<'_> = self.into();
download_file(dwn_ctx, url, dest_path, help_on_error);
download_file(dwn_ctx, &self.out, url, dest_path, help_on_error);
}
fn unpack(&self, tarball: &Path, dst: &Path, pattern: &str) {
@ -238,7 +237,7 @@ impl Config {
destination: &str,
) {
let dwn_ctx: DownloadContext<'_> = self.into();
download_component(dwn_ctx, mode, filename, prefix, key, destination);
download_component(dwn_ctx, &self.out, mode, filename, prefix, key, destination);
}
#[cfg(test)]
@ -403,13 +402,8 @@ impl Config {
pub(crate) struct DownloadContext<'a> {
pub path_modification_cache: Arc<Mutex<HashMap<Vec<&'static str>, PathFreshness>>>,
pub src: &'a Path,
pub rust_info: channel::GitInfo,
pub submodules: &'a Option<bool>,
pub download_rustc_commit: Option<String>,
pub host_target: TargetSelection,
pub llvm_from_ci: bool,
pub target_config: HashMap<TargetSelection, Target>,
pub out: PathBuf,
pub patch_binaries_for_nix: Option<bool>,
pub exec_ctx: &'a ExecutionContext,
pub stage0_metadata: &'a build_helper::stage0_parser::Stage0,
@ -430,12 +424,7 @@ impl<'a> From<&'a Config> for DownloadContext<'a> {
path_modification_cache: value.path_modification_cache.clone(),
src: &value.src,
host_target: value.host_target,
rust_info: value.rust_info.clone(),
download_rustc_commit: value.download_rustc_commit.clone(),
submodules: &value.submodules,
llvm_from_ci: value.llvm_from_ci,
target_config: value.target_config.clone(),
out: value.out.clone(),
patch_binaries_for_nix: value.patch_binaries_for_nix,
exec_ctx: &value.exec_ctx,
stage0_metadata: &value.stage0_metadata,
@ -495,6 +484,7 @@ pub(crate) fn is_download_ci_available(target_triple: &str, llvm_assertions: boo
#[cfg(test)]
pub(crate) fn maybe_download_rustfmt<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
out: &Path,
) -> Option<PathBuf> {
Some(PathBuf::new())
}
@ -504,6 +494,7 @@ pub(crate) fn maybe_download_rustfmt<'a>(
#[cfg(not(test))]
pub(crate) fn maybe_download_rustfmt<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
out: &Path,
) -> Option<PathBuf> {
use build_helper::stage0_parser::VersionMetadata;
@ -517,7 +508,7 @@ pub(crate) fn maybe_download_rustfmt<'a>(
let channel = format!("{version}-{date}");
let host = dwn_ctx.host_target;
let bin_root = dwn_ctx.out.join(host).join("rustfmt");
let bin_root = out.join(host).join("rustfmt");
let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host));
let rustfmt_stamp = BuildStamp::new(&bin_root).with_prefix("rustfmt").add_stamp(channel);
if rustfmt_path.exists() && rustfmt_stamp.is_up_to_date() {
@ -526,6 +517,7 @@ pub(crate) fn maybe_download_rustfmt<'a>(
download_component(
dwn_ctx,
out,
DownloadSource::Dist,
format!("rustfmt-{version}-{build}.tar.xz", build = host.triple),
"rustfmt-preview",
@ -535,6 +527,7 @@ pub(crate) fn maybe_download_rustfmt<'a>(
download_component(
dwn_ctx,
out,
DownloadSource::Dist,
format!("rustc-{version}-{build}.tar.xz", build = host.triple),
"rustc",
@ -543,13 +536,13 @@ pub(crate) fn maybe_download_rustfmt<'a>(
);
if should_fix_bins_and_dylibs(dwn_ctx.patch_binaries_for_nix, dwn_ctx.exec_ctx) {
fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustfmt"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("cargo-fmt"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(out, &bin_root.join("bin").join("rustfmt"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(out, &bin_root.join("bin").join("cargo-fmt"), dwn_ctx.exec_ctx);
let lib_dir = bin_root.join("lib");
for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) {
let lib = t!(lib);
if path_is_dylib(&lib.path()) {
fix_bin_or_dylib(&dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx);
fix_bin_or_dylib(out, &lib.path(), dwn_ctx.exec_ctx);
}
}
}
@ -559,10 +552,10 @@ pub(crate) fn maybe_download_rustfmt<'a>(
}
#[cfg(test)]
pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>) {}
pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>, out: &Path) {}
#[cfg(not(test))]
pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>) {
pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>, out: &Path) {
let dwn_ctx = dwn_ctx.as_ref();
dwn_ctx.exec_ctx.verbose(|| {
println!("downloading stage0 beta artifacts");
@ -574,6 +567,7 @@ pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef<DownloadContext<'a
let sysroot = "stage0";
download_toolchain(
dwn_ctx,
out,
&version,
sysroot,
&date,
@ -583,8 +577,10 @@ pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef<DownloadContext<'a
);
}
#[allow(clippy::too_many_arguments)]
fn download_toolchain<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
out: &Path,
version: &str,
sysroot: &str,
stamp_key: &str,
@ -594,7 +590,7 @@ fn download_toolchain<'a>(
) {
let dwn_ctx = dwn_ctx.as_ref();
let host = dwn_ctx.host_target.triple;
let bin_root = dwn_ctx.out.join(host).join(sysroot);
let bin_root = out.join(host).join(sysroot);
let rustc_stamp = BuildStamp::new(&bin_root).with_prefix("rustc").add_stamp(stamp_key);
if !bin_root.join("bin").join(exe("rustc", dwn_ctx.host_target)).exists()
@ -605,20 +601,28 @@ fn download_toolchain<'a>(
}
let filename = format!("rust-std-{version}-{host}.tar.xz");
let pattern = format!("rust-std-{host}");
download_component(dwn_ctx, mode.clone(), filename, &pattern, stamp_key, destination);
download_component(dwn_ctx, out, mode.clone(), filename, &pattern, stamp_key, destination);
let filename = format!("rustc-{version}-{host}.tar.xz");
download_component(dwn_ctx, mode.clone(), filename, "rustc", stamp_key, destination);
download_component(dwn_ctx, out, mode.clone(), filename, "rustc", stamp_key, destination);
for component in extra_components {
let filename = format!("{component}-{version}-{host}.tar.xz");
download_component(dwn_ctx, mode.clone(), filename, component, stamp_key, destination);
download_component(
dwn_ctx,
out,
mode.clone(),
filename,
component,
stamp_key,
destination,
);
}
if should_fix_bins_and_dylibs(dwn_ctx.patch_binaries_for_nix, dwn_ctx.exec_ctx) {
fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustc"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustdoc"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(out, &bin_root.join("bin").join("rustc"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(out, &bin_root.join("bin").join("rustdoc"), dwn_ctx.exec_ctx);
fix_bin_or_dylib(
&dwn_ctx.out,
out,
&bin_root.join("libexec").join("rust-analyzer-proc-macro-srv"),
dwn_ctx.exec_ctx,
);
@ -626,7 +630,7 @@ fn download_toolchain<'a>(
for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) {
let lib = t!(lib);
if path_is_dylib(&lib.path()) {
fix_bin_or_dylib(&dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx);
fix_bin_or_dylib(out, &lib.path(), dwn_ctx.exec_ctx);
}
}
}
@ -750,6 +754,7 @@ fn should_fix_bins_and_dylibs(
fn download_component<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
out: &Path,
mode: DownloadSource,
filename: String,
prefix: &str,
@ -763,14 +768,14 @@ fn download_component<'a>(
}
let cache_dst =
dwn_ctx.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| dwn_ctx.out.join("cache"));
dwn_ctx.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| out.join("cache"));
let cache_dir = cache_dst.join(key);
if !cache_dir.exists() {
t!(fs::create_dir_all(&cache_dir));
}
let bin_root = dwn_ctx.out.join(dwn_ctx.host_target).join(destination);
let bin_root = out.join(dwn_ctx.host_target).join(destination);
let tarball = cache_dir.join(&filename);
let (base_url, url, should_verify) = match mode {
DownloadSource::CI => {
@ -835,7 +840,7 @@ HELP: if trying to compile an old commit of rustc, disable `download-rustc` in b
download-rustc = false
";
}
download_file(dwn_ctx, &format!("{base_url}/{url}"), &tarball, help_on_error);
download_file(dwn_ctx, out, &format!("{base_url}/{url}"), &tarball, help_on_error);
if let Some(sha256) = checksum
&& !verify(dwn_ctx.exec_ctx, &tarball, sha256)
{
@ -953,6 +958,7 @@ fn unpack(exec_ctx: &ExecutionContext, tarball: &Path, dst: &Path, pattern: &str
fn download_file<'a>(
dwn_ctx: impl AsRef<DownloadContext<'a>>,
out: &Path,
url: &str,
dest_path: &Path,
help_on_error: &str,
@ -963,7 +969,7 @@ fn download_file<'a>(
println!("download {url}");
});
// Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
let tempfile = tempdir(&dwn_ctx.out).join(dest_path.file_name().unwrap());
let tempfile = tempdir(out).join(dest_path.file_name().unwrap());
// While bootstrap itself only supports http and https downloads, downstream forks might
// need to download components from other protocols. The match allows them adding more
// protocols without worrying about merge conflicts if we change the HTTP implementation.