Skip to content

Commit c1d9382

Browse files
Add support for downloading libgccjit.so file to prevent requiring to build it yourself
1 parent e936289 commit c1d9382

File tree

7 files changed

+112
-14
lines changed

7 files changed

+112
-14
lines changed

compiler/rustc_codegen_gcc/build_system/src/config.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,17 @@ impl ConfigInfo {
444444
"build_sysroot/sysroot/lib/rustlib/{}/lib",
445445
self.target_triple,
446446
));
447-
let ld_library_path = format!(
448-
"{target}:{sysroot}:{gcc_path}",
449-
target = self.cargo_target_dir,
450-
sysroot = sysroot.display(),
451-
gcc_path = self.gcc_path,
452-
);
453-
env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone());
454-
env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone());
455-
env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path);
447+
if !use_system_gcc {
448+
let ld_library_path = format!(
449+
"{target}:{sysroot}:{gcc_path}",
450+
target = self.cargo_target_dir,
451+
sysroot = sysroot.display(),
452+
gcc_path = self.gcc_path,
453+
);
454+
env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone());
455+
env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone());
456+
env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path);
457+
}
456458

457459
// NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc.
458460
// To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH.

config.example.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@
155155
# Custom CMake defines to set when building LLVM.
156156
#build-config = {}
157157

158+
# =============================================================================
159+
# General configuration options for the GCC backend
160+
# =============================================================================
161+
[gcc]
162+
# Change to `true` if you want to use the version used in Rust CI.
163+
# download-gccjit = false
164+
158165
# =============================================================================
159166
# General build configuration options
160167
# =============================================================================

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3489,6 +3489,7 @@ impl Step for CodegenGCC {
34893489
// Avoid incremental cache issues when changing rustc
34903490
cargo.env("CARGO_BUILD_INCREMENTAL", "false");
34913491
cargo.rustflag("-Cpanic=abort");
3492+
cargo.add_rustc_lib_path(builder);
34923493

34933494
cargo
34943495
};

src/bootstrap/src/core/builder.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ use crate::core::config::flags::{Color, Subcommand};
2020
use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection};
2121
use crate::prepare_behaviour_dump_dir;
2222
use crate::utils::cache::Cache;
23-
use crate::utils::helpers::{self, add_dylib_path, add_link_lib_path, exe, linker_args};
24-
use crate::utils::helpers::{check_cfg_arg, libdir, linker_flags, output, t, LldThreads};
23+
use crate::utils::helpers::{
24+
self, add_dylib_path, add_link_lib_path, check_cfg_arg, detect_gccjit_sha, exe, libdir,
25+
linker_args, linker_flags, output, t, LldThreads,
26+
};
2527
use crate::EXTRA_CHECK_CFGS;
2628
use crate::{Build, CLang, Crate, DocTests, GitRepo, Mode};
2729

@@ -1165,6 +1167,10 @@ impl<'a> Builder<'a> {
11651167
let ci_llvm_lib = self.out.join(&*compiler.host.triple).join("ci-llvm").join("lib");
11661168
dylib_dirs.push(ci_llvm_lib);
11671169
}
1170+
if self.config.gcc_download_gccjit {
1171+
let libgccjit_path = self.config.libgccjit_folder(&detect_gccjit_sha());
1172+
dylib_dirs.push(libgccjit_path);
1173+
}
11681174

11691175
dylib_dirs
11701176
}

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ pub struct Config {
250250
pub llvm_ldflags: Option<String>,
251251
pub llvm_use_libcxx: bool,
252252

253+
pub gcc_download_gccjit: bool,
254+
253255
// rust codegen options
254256
pub rust_optimize: RustOptimize,
255257
pub rust_codegen_units: Option<u32>,
@@ -617,6 +619,7 @@ pub(crate) struct TomlConfig {
617619
build: Option<Build>,
618620
install: Option<Install>,
619621
llvm: Option<Llvm>,
622+
gcc: Option<Gcc>,
620623
rust: Option<Rust>,
621624
target: Option<HashMap<String, TomlTarget>>,
622625
dist: Option<Dist>,
@@ -651,7 +654,7 @@ trait Merge {
651654
impl Merge for TomlConfig {
652655
fn merge(
653656
&mut self,
654-
TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id }: Self,
657+
TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id, gcc }: Self,
655658
replace: ReplaceOpt,
656659
) {
657660
fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
@@ -669,6 +672,7 @@ impl Merge for TomlConfig {
669672
do_merge(&mut self.llvm, llvm, replace);
670673
do_merge(&mut self.rust, rust, replace);
671674
do_merge(&mut self.dist, dist, replace);
675+
do_merge(&mut self.gcc, gcc, replace);
672676
assert!(target.is_none(), "merging target-specific config is not currently supported");
673677
}
674678
}
@@ -923,6 +927,13 @@ define_config! {
923927
}
924928
}
925929

930+
define_config! {
931+
/// TOML representation of how the GCC backend is configured.
932+
struct Gcc {
933+
download_gccjit: Option<bool> = "download-gccjit",
934+
}
935+
}
936+
926937
#[derive(Clone, Debug, Deserialize)]
927938
#[serde(untagged)]
928939
pub enum StringOrBool {
@@ -1749,6 +1760,14 @@ impl Config {
17491760
config.omit_git_hash = omit_git_hash.unwrap_or(default);
17501761
config.rust_info = GitInfo::new(config.omit_git_hash, &config.src);
17511762

1763+
if let Some(gcc) = toml.gcc {
1764+
let Gcc { download_gccjit } = gcc;
1765+
config.gcc_download_gccjit = download_gccjit.unwrap_or(false);
1766+
}
1767+
if config.gcc_enabled(config.build) {
1768+
config.maybe_download_gccjit();
1769+
}
1770+
17521771
if let Some(llvm) = toml.llvm {
17531772
let Llvm {
17541773
optimize: optimize_toml,
@@ -2315,6 +2334,18 @@ impl Config {
23152334
self.codegen_backends(target).contains(&"llvm".to_owned())
23162335
}
23172336

2337+
pub fn gcc_enabled(&self, target: TargetSelection) -> bool {
2338+
self.codegen_backends(target).contains(&"gcc".to_owned())
2339+
}
2340+
2341+
pub fn libgccjit_folder(&self, gcc_sha: &str) -> PathBuf {
2342+
assert!(self.gcc_download_gccjit);
2343+
let cache_prefix = format!("libgccjit-{gcc_sha}");
2344+
let cache_dst =
2345+
self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache"));
2346+
cache_dst.join(cache_prefix)
2347+
}
2348+
23182349
pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {
23192350
self.target_config
23202351
.get(&target)

src/bootstrap/src/core/download.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use build_helper::ci::CiEnv;
1212
use xz2::bufread::XzDecoder;
1313

1414
use crate::core::config::RustfmtMetadata;
15-
use crate::utils::helpers::{check_run, exe, program_out_of_date};
15+
use crate::utils::helpers::{check_run, detect_gccjit_sha, exe, program_out_of_date};
1616
use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
1717
use crate::{t, Config};
1818

@@ -229,7 +229,7 @@ impl Config {
229229
tempfile.to_str().unwrap(),
230230
"--retry",
231231
"3",
232-
"-SRf",
232+
"-SRfL",
233233
]);
234234
// Don't print progress in CI; the \r wrapping looks bad and downloads don't take long enough for progress to be useful.
235235
if CiEnv::is_ci() {
@@ -742,6 +742,38 @@ download-rustc = false
742742
let llvm_root = self.ci_llvm_root();
743743
self.unpack(&tarball, &llvm_root, "rust-dev");
744744
}
745+
746+
pub(crate) fn maybe_download_gccjit(&self) {
747+
if !self.gcc_download_gccjit {
748+
return;
749+
}
750+
self.download_gccjit(&detect_gccjit_sha());
751+
}
752+
753+
fn download_gccjit(&self, gcc_sha: &str) {
754+
let help_on_error = "ERROR: failed to download libgccjit
755+
756+
HELP: There could be two reasons behind this:
757+
1) The host triple is not supported for `download-gccjit`.
758+
2) Old builds get deleted after a certain time.
759+
";
760+
if !self.build.triple.contains("linux") || !self.build.triple.contains("x86_64") {
761+
eprintln!("{help_on_error}");
762+
return;
763+
}
764+
let rustc_cache = self.libgccjit_folder(gcc_sha);
765+
if !rustc_cache.exists() {
766+
t!(fs::create_dir_all(&rustc_cache));
767+
}
768+
769+
let lib_path = rustc_cache.join("libgccjit.so.0");
770+
if !lib_path.exists() {
771+
let url = format!(
772+
"https://github.com/rust-lang/gcc/releases/download/master-{gcc_sha}/libgccjit.so",
773+
);
774+
self.download_file(&url, &lib_path, help_on_error);
775+
}
776+
}
745777
}
746778

747779
fn path_is_dylib(path: &Path) -> bool {

src/bootstrap/src/utils/helpers.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,3 +574,22 @@ pub fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String {
574574
};
575575
format!("--check-cfg=cfg({name}{next})")
576576
}
577+
578+
/// This retrieves the gccjit sha we use.
579+
pub fn detect_gccjit_sha() -> String {
580+
// FIXME: This is absolutely ugly. Please find another way to do that.
581+
let content = include_str!("../../../ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh");
582+
if let Some(commit) = content
583+
.lines()
584+
.filter_map(|line| line.strip_prefix("GIT_COMMIT=\""))
585+
.filter_map(|commit| commit.strip_suffix('"'))
586+
.next()
587+
{
588+
if !commit.is_empty() {
589+
return commit.to_string();
590+
}
591+
}
592+
593+
eprintln!("error: could not find commit hash for downloading libgccjit");
594+
panic!();
595+
}

0 commit comments

Comments
 (0)