libgcc_s.so.1 fix #5732

This commit is contained in:
Anton-4 2023-08-08 19:55:38 +02:00
parent 00b4be2d31
commit 387b6927d5
No known key found for this signature in database
GPG key ID: 0971D718C0A9B937
4 changed files with 63 additions and 53 deletions

View file

@ -4,6 +4,7 @@ use roc_command_utils::{cargo, clang, rustup, zig};
use roc_error_macros::internal_error; use roc_error_macros::internal_error;
use roc_mono::ir::OptLevel; use roc_mono::ir::OptLevel;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::OsString;
use std::fs::DirEntry; use std::fs::DirEntry;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -785,11 +786,25 @@ fn get_target_str(target: &Triple) -> &str {
} }
} }
fn nix_path_opt() -> Option<String> { fn nix_paths() -> Vec<String> {
env::var_os("NIX_GLIBC_PATH").map(|path| path.into_string().unwrap()) let mut paths = vec![];
if let Some(nix_libgcc_s_path) = env::var_os("NIX_LIBGCC_S_PATH") {
paths.push(nix_libgcc_s_path.into_string().unwrap())
} }
fn library_path<const N: usize>(segments: [&str; N]) -> Option<PathBuf> { if let Some(nix_glibc_path) = nix_glibc_path_opt() {
paths.push(nix_glibc_path.into_string().unwrap())
}
paths
}
fn nix_glibc_path_opt() -> Option<OsString> {
env::var_os("NIX_GLIBC_PATH")
}
fn build_path<const N: usize>(segments: [&str; N]) -> Option<PathBuf> {
let mut guess_path = PathBuf::new(); let mut guess_path = PathBuf::new();
for s in segments { for s in segments {
guess_path.push(s); guess_path.push(s);
@ -812,22 +827,21 @@ fn library_path<const N: usize>(segments: [&str; N]) -> Option<PathBuf> {
/// match will be returned. /// match will be returned.
/// ///
/// If there are no matches, [`None`] will be returned. /// If there are no matches, [`None`] will be returned.
fn look_for_library(lib_dirs: &[&[&str]], lib_filename: &str) -> Option<PathBuf> { fn look_for_library(lib_dirs: &[PathBuf], lib_filename: &str) -> Option<PathBuf> {
lib_dirs lib_dirs
.iter() .iter()
.map(|lib_dir| { .map(|path| {
lib_dir.iter().fold(PathBuf::new(), |mut path, segment| { let mut path_cl = path.clone();
path.push(segment); path_cl.push(lib_filename);
path path_cl
})
})
.map(|mut path| {
path.push(lib_filename);
path
}) })
.find(|path| path.exists()) .find(|path| path.exists())
} }
fn strs_to_path(strs: &[&str]) -> PathBuf {
strs.iter().collect()
}
fn link_linux( fn link_linux(
target: &Triple, target: &Triple,
output_path: PathBuf, output_path: PathBuf,
@ -863,49 +877,39 @@ fn link_linux(
} }
// Some things we'll need to build a list of dirs to check for libraries // Some things we'll need to build a list of dirs to check for libraries
let maybe_nix_path = nix_path_opt(); //env::var_os("NIX_GLIBC_PATH").map(|path| path.into_string().unwrap()),
let usr_lib_arch = ["/usr", "lib", &architecture]; //env::var_os("NIX_LIBGCC_S_PATH").map(|path| path.into_string().unwrap())
let lib_arch = ["/lib", &architecture]; let nix_paths_vec_string = nix_paths();
let nix_path_segments; let nix_paths_vec: Vec<PathBuf> = nix_paths_vec_string.iter().map(|path_string| PathBuf::from(path_string)).collect();
let lib_dirs_if_nix: [&[&str]; 5]; let usr_lib_arch_path = strs_to_path(&["/usr", "lib", &architecture]);
let lib_dirs_if_nonix: [&[&str]; 4]; let lib_arch_path = strs_to_path(&["/lib", &architecture]);
// Build the aformentioned list let mut lib_dirs: Vec<PathBuf> = vec![];
let lib_dirs: &[&[&str]] =
// give preference to nix_path if it's defined, this prevents bugs // start with nix paths, this prevents bugs
if let Some(nix_path) = &maybe_nix_path { if !nix_paths_vec.is_empty() {
nix_path_segments = [nix_path.as_str()]; lib_dirs.extend(nix_paths_vec)
lib_dirs_if_nix = [ }
&nix_path_segments,
&usr_lib_arch, lib_dirs.extend( [
&lib_arch, usr_lib_arch_path,
&["/usr", "lib"], lib_arch_path,
&["/usr", "lib64"], strs_to_path(&["/usr", "lib"]),
]; strs_to_path(&["/usr", "lib64"]),
&lib_dirs_if_nix ]);
} else {
lib_dirs_if_nonix = [
&usr_lib_arch,
&lib_arch,
&["/usr", "lib"],
&["/usr", "lib64"],
];
&lib_dirs_if_nonix
};
// Look for the libraries we'll need // Look for the libraries we'll need
let libgcc_name = "libgcc_s.so.1"; let libgcc_name = "libgcc_s.so.1";
let libgcc_path = look_for_library(lib_dirs, libgcc_name); let libgcc_path = look_for_library(&lib_dirs, libgcc_name);
let crti_name = "crti.o"; let crti_name = "crti.o";
let crti_path = look_for_library(lib_dirs, crti_name); let crti_path = look_for_library(&lib_dirs, crti_name);
let crtn_name = "crtn.o"; let crtn_name = "crtn.o";
let crtn_path = look_for_library(lib_dirs, crtn_name); let crtn_path = look_for_library(&lib_dirs, crtn_name);
let scrt1_name = "Scrt1.o"; let scrt1_name = "Scrt1.o";
let scrt1_path = look_for_library(lib_dirs, scrt1_name); let scrt1_path = look_for_library(&lib_dirs, scrt1_name);
// Unwrap all the paths at once so we can inform the user of all missing libs at once // Unwrap all the paths at once so we can inform the user of all missing libs at once
let (libgcc_path, crti_path, crtn_path, scrt1_path) = let (libgcc_path, crti_path, crtn_path, scrt1_path) =
@ -925,7 +929,7 @@ fn link_linux(
let dirs = lib_dirs let dirs = lib_dirs
.iter() .iter()
.map(|segments| segments.join("/")) .map(|path_buf| path_buf.as_path().to_str().unwrap_or("FAILED TO CONVERT PATH TO STR").to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join("\n"); .join("\n");
eprintln!("We looked in the following directories:\n{dirs}"); eprintln!("We looked in the following directories:\n{dirs}");
@ -936,13 +940,13 @@ fn link_linux(
let ld_linux = match target.architecture { let ld_linux = match target.architecture {
Architecture::X86_64 => { Architecture::X86_64 => {
// give preference to nix_path if it's defined, this prevents bugs // give preference to nix_path if it's defined, this prevents bugs
if let Some(nix_path) = nix_path_opt() { if let Some(nix_glibc_path) = nix_glibc_path_opt() {
library_path([&nix_path, "ld-linux-x86-64.so.2"]) build_path([&nix_glibc_path.into_string().unwrap(), "ld-linux-x86-64.so.2"])
} else { } else {
library_path(["/lib64", "ld-linux-x86-64.so.2"]) build_path(["/lib64", "ld-linux-x86-64.so.2"])
} }
} }
Architecture::Aarch64(_) => library_path(["/lib", "ld-linux-aarch64.so.1"]), Architecture::Aarch64(_) => build_path(["/lib", "ld-linux-aarch64.so.1"]),
_ => internal_error!( _ => internal_error!(
"TODO gracefully handle unsupported linux architecture: {:?}", "TODO gracefully handle unsupported linux architecture: {:?}",
target.architecture target.architecture

View file

@ -63,7 +63,7 @@ fn roc_function<'a, 'b>(
let context = inkwell::context::Context::create(); let context = inkwell::context::Context::create();
let (main_fn_name, errors, lib) = let (main_fn_name, errors, lib) =
helpers::llvm::helper(arena, config, source, arena.alloc(context)); helpers::llvm::helper(arena, config, source, arena.alloc(context), roc_load::FunctionKind::LambdaSet);
assert!(errors.is_empty(), "Encountered errors:\n{errors}"); assert!(errors.is_empty(), "Encountered errors:\n{errors}");

View file

@ -92,7 +92,7 @@ fn roc_function<'a>(
let context = inkwell::context::Context::create(); let context = inkwell::context::Context::create();
let (main_fn_name, errors, lib) = let (main_fn_name, errors, lib) =
helpers::llvm::helper(arena, config, source, arena.alloc(context)); helpers::llvm::helper(arena, config, source, arena.alloc(context), roc_load::FunctionKind::LambdaSet);
assert!(errors.is_empty(), "Encountered errors:\n{errors}"); assert!(errors.is_empty(), "Encountered errors:\n{errors}");

View file

@ -125,9 +125,15 @@
[ ]); [ ]);
LLVM_SYS_130_PREFIX = "${llvmPkgs.llvm.dev}"; LLVM_SYS_130_PREFIX = "${llvmPkgs.llvm.dev}";
# nix does not store libs in /usr/lib or /lib # nix does not store libs in /usr/lib or /lib
# for libgcc_s.so.1
NIX_LIBGCC_S_PATH =
if pkgs.stdenv.isLinux then "${pkgs.stdenv.cc.cc.lib}/lib" else "";
# for crti.o, crtn.o, and Scrt1.o
NIX_GLIBC_PATH = NIX_GLIBC_PATH =
if pkgs.stdenv.isLinux then "${pkgs.glibc.out}/lib" else ""; if pkgs.stdenv.isLinux then "${pkgs.glibc.out}/lib" else "";
LD_LIBRARY_PATH = with pkgs; LD_LIBRARY_PATH = with pkgs;
lib.makeLibraryPath lib.makeLibraryPath
([ pkg-config stdenv.cc.cc.lib libffi ncurses zlib ] ([ pkg-config stdenv.cc.cc.lib libffi ncurses zlib ]