From 74bcdd680f3ff40dac263c32c30208194876b080 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Jul 2026 18:20:00 +0200 Subject: [PATCH 1/2] Add new `--with-llvm-sysroot` test option --- .github/workflows/ci.yml | 4 ++++ build_system/src/config.rs | 10 +++++----- build_system/src/test.rs | 23 +++++++++++++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4463a6bd53c..7b304983a1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,10 @@ jobs: "--test-successful-rustc --nb-parts 2 --current-part 1", "--projects", "--gcc-asm-tests", + # With the LLVM sysroot now. + "--test-successful-rustc --nb-parts 2 --current-part 0 --use-llvm-sysroot", + "--test-successful-rustc --nb-parts 2 --current-part 1 --use-llvm-sysroot", + "--projects --use-llvm-sysroot", ] steps: diff --git a/build_system/src/config.rs b/build_system/src/config.rs index fd78f691d16..6c6b4e69909 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -122,6 +122,7 @@ pub struct ConfigInfo { pub no_default_features: bool, pub backend: Option, pub features: Vec, + pub use_llvm_sysroot: bool, } impl ConfigInfo { @@ -394,11 +395,10 @@ impl ConfigInfo { // by its build system directly so no need to set it ourselves. rustflags.push(format!("-Zcodegen-backend={backend}")); } else { - rustflags.extend_from_slice(&[ - "--sysroot".to_string(), - self.sysroot_path.clone(), - format!("-Zcodegen-backend={}", self.cg_backend_path), - ]); + if !self.use_llvm_sysroot { + rustflags.extend_from_slice(&["--sysroot".to_string(), self.sysroot_path.clone()]); + } + rustflags.push(format!("-Zcodegen-backend={}", self.cg_backend_path)); } // This environment variable is useful in case we want to change options of rustc commands. diff --git a/build_system/src/test.rs b/build_system/src/test.rs index f0c6960b68a..4ffbaf4031d 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -70,6 +70,7 @@ fn show_usage() { --features [arg] : Add a new feature [arg] --use-system-gcc : Use system installed libgccjit + --use-llvm-sysroot : Use LLVM sysroot instead of the one compiled with `cg_gcc` --build-only : Only build rustc_codegen_gcc then exits --nb-parts : Used to split rustc_tests (for CI needs) --current-part : Used with `--nb-parts`, allows you to specify which parts to test"# @@ -132,6 +133,9 @@ impl TestArg { "--keep-lto-tests" => { test_arg.keep_lto_tests = true; } + "--use-llvm-sysroot" => { + test_arg.config_info.use_llvm_sysroot = true; + } "--sysroot-features" => match args.next() { Some(feature) if !feature.is_empty() => { test_arg.sysroot_features.push(feature); @@ -283,6 +287,9 @@ fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> { fn build_sysroot(env: &Env, args: &TestArg) -> Result<(), String> { // FIXME: create a function "display_if_not_quiet" or something along the line. println!("[BUILD] sysroot"); + if !args.config_info.use_llvm_sysroot { + println!("`--use-llvm-sysroot` option was used, skipping sysroot build"); + } let mut config = args.config_info.clone(); config.features.extend(args.sysroot_features.iter().cloned()); build::build_sysroot(env, &config)?; @@ -630,8 +637,12 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; let rustc_args = format!( - "-Zpanic-abort-tests -Zcodegen-backend={codegen_backend_path} --sysroot {} -Cpanic=abort{extra}", - args.config_info.sysroot_path + "-Zpanic-abort-tests -Zcodegen-backend={codegen_backend_path}{} -Cpanic=abort{extra}", + if args.config_info.use_llvm_sysroot { + String::new() + } else { + format!(" --sysroot {}", args.config_info.sysroot_path) + }, ); run_command_with_env( @@ -1124,10 +1135,14 @@ where if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; let rustc_args = format!( - "{test_flags} -Zcodegen-backend={backend} --sysroot {sysroot}{extra}", + "{test_flags} -Zcodegen-backend={backend}{sysroot}{extra}", test_flags = env.get("TEST_FLAGS").unwrap_or(&String::new()), backend = args.config_info.cg_backend_path, - sysroot = args.config_info.sysroot_path, + sysroot = if args.config_info.use_llvm_sysroot { + String::new() + } else { + format!(" --sysroot {}", args.config_info.sysroot_path) + }, extra = extra, ); From fd4ab3291f4a5c4d91fbe21841c3f1e68e06db98 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jul 2026 00:36:01 +0200 Subject: [PATCH 2/2] Create new `CG_LIBGCCJIT_PATH` env variable to specify the path for `libgccjit.so` --- build_system/src/config.rs | 4 ++++ src/lib.rs | 30 +++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 6c6b4e69909..6283542da13 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -397,6 +397,10 @@ impl ConfigInfo { } else { if !self.use_llvm_sysroot { rustflags.extend_from_slice(&["--sysroot".to_string(), self.sysroot_path.clone()]); + } else { + let libgccjit_path = + Path::new(self.gcc_path.as_deref().unwrap()).join("libgccjit.so"); + env.insert("CG_LIBGCCJIT_PATH".into(), libgccjit_path.display().to_string()); } rustflags.push(format!("-Zcodegen-backend={}", self.cg_backend_path)); } diff --git a/src/lib.rs b/src/lib.rs index 9a75aef25bc..c45ba88dcdc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -207,25 +207,33 @@ impl CodegenBackend for GccCodegenBackend { .join("libgccjit.so") } - // We use all_paths() instead of only path() in case the path specified by --sysroot is - // invalid. - // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. - for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = file_path(path, sess); - if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { - load_libgccjit_if_needed(&libgccjit_target_lib_file); - break; + let mut attempted_paths = Vec::new(); + if let Ok(libgccjit_path) = std::env::var("CG_LIBGCCJIT_PATH") { + let libgccjit_path = PathBuf::from(libgccjit_path); + if let Ok(true) = fs::exists(&libgccjit_path) { + load_libgccjit_if_needed(&libgccjit_path); + } else { + attempted_paths.push(libgccjit_path); } } if !gccjit::is_loaded() { - let mut paths = vec![]; + // We use all_paths() instead of only path() in case the path specified by --sysroot is + // invalid. + // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { let libgccjit_target_lib_file = file_path(path, sess); - paths.push(libgccjit_target_lib_file); + if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { + load_libgccjit_if_needed(&libgccjit_target_lib_file); + break; + } else { + attempted_paths.push(libgccjit_target_lib_file); + } } + } - panic!("Could not load libgccjit.so. Attempted paths: {:#?}", paths); + if !gccjit::is_loaded() { + panic!("Could not load libgccjit.so. Attempted paths: {:#?}", attempted_paths); } #[cfg(feature = "master")]