Skip to content

Commit 389cb6f

Browse files
committed
Do not build or download libgccjit if using libgccjit-libs-dir
1 parent 70d4545 commit 389cb6f

File tree

5 files changed

+47
-23
lines changed

5 files changed

+47
-23
lines changed

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2857,7 +2857,9 @@ impl Step for Gcc {
28572857
fn run(self, builder: &Builder<'_>) -> Self::Output {
28582858
let tarball = Tarball::new(builder, "gcc", &self.target.triple);
28592859
let output = builder.ensure(super::gcc::Gcc { target: self.target });
2860-
tarball.add_file(&output.libgccjit, "lib", FileType::NativeLibrary);
2860+
if let Some(ref path) = output.libgccjit {
2861+
tarball.add_file(path, "lib", FileType::NativeLibrary);
2862+
}
28612863
tarball.generate()
28622864
}
28632865

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

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ pub struct Gcc {
2626

2727
#[derive(Clone)]
2828
pub struct GccOutput {
29-
pub libgccjit: PathBuf,
29+
/// Path to a built or downloaded libgccjit.
30+
/// Is None when setting libgccjit-libs-dir.
31+
/// FIXME: it seems wrong to make this an Option.
32+
/// Perhaps it should be a Vec so that we can install all libs from libgccjit-libs-dir?
33+
pub libgccjit: Option<PathBuf>,
3034
}
3135

3236
impl GccOutput {
@@ -36,18 +40,20 @@ impl GccOutput {
3640
return;
3741
}
3842

39-
let target_filename = self.libgccjit.file_name().unwrap().to_str().unwrap().to_string();
43+
if let Some(ref path) = self.libgccjit {
44+
let mut target_filename = path.file_name().unwrap().to_str().unwrap().to_string();
4045

41-
// If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink.
42-
// In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink,
43-
// which wouldn't work.
44-
let actual_libgccjit_path = t!(
45-
self.libgccjit.canonicalize(),
46-
format!("Cannot find libgccjit at {}", self.libgccjit.display())
47-
);
46+
// If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink.
47+
// In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink,
48+
// which wouldn't work.
49+
let actual_libgccjit_path = t!(
50+
path.canonicalize(),
51+
format!("Cannot find libgccjit at {}", path.display())
52+
);
4853

49-
let dst = directory.join(&target_filename);
50-
builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary);
54+
let dst = directory.join(&target_filename);
55+
builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary);
56+
}
5157

5258
if let Some(ref path) = builder.config.libgccjit_libs_dir {
5359
let host_target = builder.config.host_target.triple;
@@ -59,13 +65,14 @@ impl GccOutput {
5965
.map(|target| target.triple)
6066
.chain(std::iter::once(host_target));
6167

68+
let target_filename = "libgccjit.so.0";
6269
for target in targets {
63-
let source = source.join(target).join(&target_filename);
70+
let source = source.join(target).join(target_filename);
6471
// To support symlinks in libgccjit-libs-dir, we have to resolve it first,
6572
// otherwise we'd create a symlink to a symlink, which wouldn't work.
6673
let actual_libgccjit_path = t!(
6774
source.canonicalize(),
68-
format!("Cannot find libgccjit at {}", self.libgccjit.display())
75+
format!("Cannot find libgccjit at {}", source.display())
6976
);
7077
let target_dir = dst.join(target);
7178
t!(
@@ -99,7 +106,8 @@ impl Step for Gcc {
99106

100107
// If GCC has already been built, we avoid building it again.
101108
let metadata = match get_gcc_build_status(builder, target) {
102-
GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path },
109+
GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: Some(path) },
110+
GccBuildStatus::InLibsDir => return GccOutput { libgccjit: None },
103111
GccBuildStatus::ShouldBuild(m) => m,
104112
};
105113

@@ -109,14 +117,14 @@ impl Step for Gcc {
109117

110118
let libgccjit_path = libgccjit_built_path(&metadata.install_dir);
111119
if builder.config.dry_run() {
112-
return GccOutput { libgccjit: libgccjit_path };
120+
return GccOutput { libgccjit: Some(libgccjit_path) };
113121
}
114122

115123
build_gcc(&metadata, builder, target);
116124

117125
t!(metadata.stamp.write());
118126

119-
GccOutput { libgccjit: libgccjit_path }
127+
GccOutput { libgccjit: Some(libgccjit_path) }
120128
}
121129
}
122130

@@ -130,6 +138,7 @@ pub struct Meta {
130138
pub enum GccBuildStatus {
131139
/// libgccjit is already built at this path
132140
AlreadyBuilt(PathBuf),
141+
InLibsDir,
133142
ShouldBuild(Meta),
134143
}
135144

@@ -194,6 +203,11 @@ fn try_download_gcc(_builder: &Builder<'_>, _target: TargetSelection) -> Option<
194203
/// It's used to avoid busting caches during x.py check -- if we've already built
195204
/// GCC, it's fine for us to not try to avoid doing so.
196205
pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> GccBuildStatus {
206+
if matches!(builder.config.gcc_ci_mode, crate::core::config::GccCiMode::CopyFromLibsDir) {
207+
// TODO: check if this is OK.
208+
return GccBuildStatus::InLibsDir;
209+
}
210+
197211
if let Some(path) = try_download_gcc(builder, target) {
198212
return GccBuildStatus::AlreadyBuilt(path);
199213
}
@@ -317,7 +331,9 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
317331
/// Configures a Cargo invocation so that it can build the GCC codegen backend.
318332
pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) {
319333
// Add the path to libgccjit.so to the linker search paths.
320-
cargo.rustflag(&format!("-L{}", gcc.libgccjit.parent().unwrap().to_str().unwrap()));
334+
if let Some(ref path) = gcc.libgccjit {
335+
cargo.rustflag(&format!("-L{}", path.parent().unwrap().to_str().unwrap()));
336+
}
321337
}
322338

323339
/// The absolute path to the downloaded GCC artifacts.

src/bootstrap/src/core/build_steps/test.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,13 +3938,17 @@ impl Step for CodegenGCC {
39383938
.arg("test")
39393939
.arg("--use-backend")
39403940
.arg("gcc")
3941-
.arg("--gcc-path")
3942-
.arg(gcc.libgccjit.parent().unwrap())
39433941
.arg("--out-dir")
39443942
.arg(builder.stage_out(compilers.build_compiler(), Mode::Codegen).join("cg_gcc"))
39453943
.arg("--release")
39463944
.arg("--mini-tests")
39473945
.arg("--std-tests");
3946+
3947+
if let Some(ref path) = gcc.libgccjit {
3948+
cargo
3949+
.arg("--gcc-path")
3950+
.arg(path.parent().unwrap());
3951+
}
39483952
cargo.args(builder.config.test_args());
39493953

39503954
cargo.into_cmd().run(builder);

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,12 +1219,13 @@ impl Config {
12191219
Warnings::Default => rust_deny_warnings.unwrap_or(true),
12201220
};
12211221

1222-
let gcc_ci_mode = match gcc_download_ci_gcc {
1223-
Some(value) => match value {
1222+
let gcc_ci_mode = match (&libgccjit_libs_dir, gcc_download_ci_gcc) {
1223+
(Some(_), _) => GccCiMode::CopyFromLibsDir,
1224+
(None, Some(value)) => match value {
12241225
true => GccCiMode::DownloadFromCi,
12251226
false => GccCiMode::BuildLocally,
12261227
},
1227-
None => GccCiMode::default(),
1228+
(None, None) => GccCiMode::default(),
12281229
};
12291230

12301231
let targets = flags_target

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ pub enum GccCiMode {
433433
/// If it is not available on CI, it will be built locally instead.
434434
#[default]
435435
DownloadFromCi,
436+
CopyFromLibsDir,
436437
}
437438

438439
pub fn threads_from_config(v: u32) -> u32 {

0 commit comments

Comments
 (0)