Move libgccjit.so in the sysroot

This will be useful for the unification work of the handling of the
library between all Rust setups.
This commit is contained in:
Antoni Boucher 2025-11-26 12:13:29 -05:00
parent 9d4c385c34
commit 2567d8171a
8 changed files with 27 additions and 82 deletions

View file

@ -54,8 +54,6 @@ jobs:
if: matrix.libgccjit_version.gcc == 'libgccjit12.so' if: matrix.libgccjit_version.gcc == 'libgccjit12.so'
run: | run: |
echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml
echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV
echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV
- name: Download artifact - name: Download artifact
if: matrix.libgccjit_version.gcc != 'libgccjit12.so' if: matrix.libgccjit_version.gcc != 'libgccjit12.so'

View file

@ -51,12 +51,6 @@ jobs:
- name: Setup path to libgccjit - name: Setup path to libgccjit
run: echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml run: echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml
- name: Set env
run: |
echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV
echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV
echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV
#- name: Cache rust repository #- name: Cache rust repository
## We only clone the rust repository for rustc tests ## We only clone the rust repository for rustc tests
#if: ${{ contains(matrix.commands, 'rustc') }} #if: ${{ contains(matrix.commands, 'rustc') }}

View file

@ -59,9 +59,8 @@ jobs:
sudo ln -s /usr/share/intel-sde/sde /usr/bin/sde sudo ln -s /usr/share/intel-sde/sde /usr/bin/sde
sudo ln -s /usr/share/intel-sde/sde64 /usr/bin/sde64 sudo ln -s /usr/share/intel-sde/sde64 /usr/bin/sde64
- name: Set env - name: Set config
run: | run: |
echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV
echo 'download-gccjit = true' > config.toml echo 'download-gccjit = true' > config.toml
- name: Build - name: Build
@ -69,12 +68,6 @@ jobs:
./y.sh prepare --only-libcore ./y.sh prepare --only-libcore
./y.sh build --sysroot --release --release-sysroot ./y.sh build --sysroot --release --release-sysroot
- name: Set env (part 2)
run: |
# Set the `LD_LIBRARY_PATH` and `LIBRARY_PATH` env variables...
echo "LD_LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV
echo "LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV
- name: Clean - name: Clean
if: ${{ !matrix.cargo_runner }} if: ${{ !matrix.cargo_runner }}
run: | run: |

View file

@ -1,7 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs; use std::fs;
use std::path::Path; use std::os::unix::fs::symlink;
use std::path::{Path, PathBuf};
use crate::config::{Channel, ConfigInfo}; use crate::config::{Channel, ConfigInfo};
use crate::utils::{ use crate::utils::{
@ -100,6 +101,18 @@ fn cleanup_sysroot_previous_build(library_dir: &Path) {
pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Result<(), String> { pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Result<(), String> {
let start_dir = get_sysroot_dir(); let start_dir = get_sysroot_dir();
// Symlink libgccjit.so to sysroot.
let lib_path = start_dir.join("sysroot").join("lib");
let libgccjit_path =
PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point"))
.join("libgccjit.so");
let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so");
// First remove the file to be able to create the symlink even when the file already exists.
let _ = fs::remove_file(&libgccjit_in_sysroot_path);
create_dir(&lib_path)?;
symlink(libgccjit_path, libgccjit_in_sysroot_path)
.map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?;
let library_dir = start_dir.join("sysroot_src").join("library"); let library_dir = start_dir.join("sysroot_src").join("library");
cleanup_sysroot_previous_build(&library_dir); cleanup_sysroot_previous_build(&library_dir);
@ -148,7 +161,7 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
run_command_with_output_and_env(&args, Some(&sysroot_dir), Some(&env))?; run_command_with_output_and_env(&args, Some(&sysroot_dir), Some(&env))?;
// Copy files to sysroot // Copy files to sysroot
let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); let sysroot_path = lib_path.join(format!("rustlib/{}/lib/", config.target_triple));
// To avoid errors like "multiple candidates for `rmeta` dependency `core` found", we clean the // To avoid errors like "multiple candidates for `rmeta` dependency `core` found", we clean the
// sysroot directory before copying the sysroot build artifacts. // sysroot directory before copying the sysroot build artifacts.
let _ = fs::remove_dir_all(&sysroot_path); let _ = fs::remove_dir_all(&sysroot_path);
@ -175,13 +188,6 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
fn build_codegen(args: &mut BuildArg) -> Result<(), String> { fn build_codegen(args: &mut BuildArg) -> Result<(), String> {
let mut env = HashMap::new(); let mut env = HashMap::new();
let gcc_path =
args.config_info.gcc_path.clone().expect(
"The config module should have emitted an error if the GCC path wasn't provided",
);
env.insert("LD_LIBRARY_PATH".to_string(), gcc_path.clone());
env.insert("LIBRARY_PATH".to_string(), gcc_path);
if args.config_info.no_default_features { if args.config_info.no_default_features {
env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string()); env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string());
} }

View file

@ -429,19 +429,6 @@ impl ConfigInfo {
// display metadata load errors // display metadata load errors
env.insert("RUSTC_LOG".to_string(), "warn".to_string()); env.insert("RUSTC_LOG".to_string(), "warn".to_string());
let sysroot = current_dir
.join(get_sysroot_dir())
.join(format!("sysroot/lib/rustlib/{}/lib", self.target_triple));
let ld_library_path = format!(
"{target}:{sysroot}:{gcc_path}",
target = self.cargo_target_dir,
sysroot = sysroot.display(),
gcc_path = gcc_path,
);
env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone());
env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone());
env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path);
// NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc. // NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc.
// To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH. // To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH.
// Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc // Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc

View file

@ -214,14 +214,6 @@ fn cargo_tests(test_env: &Env, test_args: &TestArg) -> Result<(), String> {
// We don't want to pass things like `RUSTFLAGS`, since they contain the -Zcodegen-backend flag. // We don't want to pass things like `RUSTFLAGS`, since they contain the -Zcodegen-backend flag.
// That would force `cg_gcc` to *rebuild itself* and only then run tests, which is undesirable. // That would force `cg_gcc` to *rebuild itself* and only then run tests, which is undesirable.
let mut env = HashMap::new(); let mut env = HashMap::new();
env.insert(
"LD_LIBRARY_PATH".into(),
test_env.get("LD_LIBRARY_PATH").expect("LD_LIBRARY_PATH missing!").to_string(),
);
env.insert(
"LIBRARY_PATH".into(),
test_env.get("LIBRARY_PATH").expect("LIBRARY_PATH missing!").to_string(),
);
env.insert( env.insert(
"CG_RUSTFLAGS".into(), "CG_RUSTFLAGS".into(),
test_env.get("CG_RUSTFLAGS").map(|s| s.as_str()).unwrap_or("").to_string(), test_env.get("CG_RUSTFLAGS").map(|s| s.as_str()).unwrap_or("").to_string(),
@ -1276,11 +1268,6 @@ pub fn run() -> Result<(), String> {
if !args.use_system_gcc { if !args.use_system_gcc {
args.config_info.setup_gcc_path()?; args.config_info.setup_gcc_path()?;
let gcc_path = args.config_info.gcc_path.clone().expect(
"The config module should have emitted an error if the GCC path wasn't provided",
);
env.insert("LIBRARY_PATH".to_string(), gcc_path.clone());
env.insert("LD_LIBRARY_PATH".to_string(), gcc_path);
} }
build_if_no_backend(&env, &args)?; build_if_no_backend(&env, &args)?;

View file

@ -72,7 +72,7 @@ use std::any::Any;
use std::ffi::CString; use std::ffi::CString;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -180,13 +180,17 @@ pub struct GccCodegenBackend {
static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false);
fn load_libgccjit_if_needed() { fn load_libgccjit_if_needed(sysroot_path: &Path) {
if gccjit::is_loaded() { if gccjit::is_loaded() {
// Do not load a libgccjit second time. // Do not load a libgccjit second time.
return; return;
} }
let string = CString::new("libgccjit.so").expect("string to libgccjit path"); let sysroot_lib_dir = sysroot_path.join("lib");
let libgccjit_target_lib_file = sysroot_lib_dir.join("libgccjit.so");
let path = libgccjit_target_lib_file.to_str().expect("libgccjit path");
let string = CString::new(path).expect("string to libgccjit path");
if let Err(error) = gccjit::load(&string) { if let Err(error) = gccjit::load(&string) {
panic!("Cannot load libgccjit.so: {}", error); panic!("Cannot load libgccjit.so: {}", error);
@ -202,12 +206,12 @@ impl CodegenBackend for GccCodegenBackend {
"gcc" "gcc"
} }
fn init(&self, _sess: &Session) { fn init(&self, sess: &Session) {
load_libgccjit_if_needed(); load_libgccjit_if_needed(sess.opts.sysroot.path());
#[cfg(feature = "master")] #[cfg(feature = "master")]
{ {
let target_cpu = target_cpu(_sess); let target_cpu = target_cpu(sess);
// Get the second TargetInfo with the correct CPU features by setting the arch. // Get the second TargetInfo with the correct CPU features by setting the arch.
let context = Context::default(); let context = Context::default();

View file

@ -2,11 +2,10 @@
#![allow(clippy::uninlined_format_args)] #![allow(clippy::uninlined_format_args)]
use std::env::{self, current_dir}; use std::env::current_dir;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use boml::Toml;
use lang_tester::LangTester; use lang_tester::LangTester;
use tempfile::TempDir; use tempfile::TempDir;
@ -23,29 +22,6 @@ pub fn main_inner(profile: Profile) {
let current_dir = current_dir().expect("current dir"); let current_dir = current_dir().expect("current dir");
let current_dir = current_dir.to_str().expect("current dir").to_string(); let current_dir = current_dir.to_str().expect("current dir").to_string();
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml"))
.ok()
.and_then(|v| {
let toml = Toml::parse(&v).expect("Failed to parse `config.toml`");
toml.get_string("gcc-path").map(PathBuf::from).ok()
})
.unwrap_or_else(|| {
// then we try to retrieve it from the `target` folder.
let commit = include_str!("../libgccjit.version").trim();
Path::new("build/libgccjit").join(commit)
});
let gcc_path = Path::new(&gcc_path)
.canonicalize()
.expect("failed to get absolute path of `gcc-path`")
.display()
.to_string();
unsafe {
env::set_var("LD_LIBRARY_PATH", gcc_path);
}
fn rust_filter(path: &Path) -> bool { fn rust_filter(path: &Path) -> bool {
path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs" path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs"
} }