mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Fix linking on Aarch64 with nix
This commit is contained in:
parent
29c1dc35de
commit
81c0050683
3 changed files with 45 additions and 12 deletions
|
@ -5,6 +5,8 @@ use inkwell::targets::{CodeModel, FileType, RelocMode};
|
||||||
use libloading::{Error, Library};
|
use libloading::{Error, Library};
|
||||||
use roc_gen::llvm::build::OptLevel;
|
use roc_gen::llvm::build::OptLevel;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::env;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Child, Command, Output};
|
use std::process::{Child, Command, Output};
|
||||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||||
|
@ -25,7 +27,6 @@ pub fn link(
|
||||||
) -> io::Result<(Child, PathBuf)> {
|
) -> io::Result<(Child, PathBuf)> {
|
||||||
match target {
|
match target {
|
||||||
Triple {
|
Triple {
|
||||||
architecture: Architecture::X86_64,
|
|
||||||
operating_system: OperatingSystem::Linux,
|
operating_system: OperatingSystem::Linux,
|
||||||
..
|
..
|
||||||
} => link_linux(target, output_path, input_paths, link_type),
|
} => link_linux(target, output_path, input_paths, link_type),
|
||||||
|
@ -46,9 +47,11 @@ pub fn rebuild_host(host_input_path: &Path) {
|
||||||
let cargo_host_src = host_input_path.with_file_name("Cargo.toml");
|
let cargo_host_src = host_input_path.with_file_name("Cargo.toml");
|
||||||
let host_dest = host_input_path.with_file_name("host.o");
|
let host_dest = host_input_path.with_file_name("host.o");
|
||||||
|
|
||||||
|
let env_path = env::var("PATH").unwrap_or_else(|_| "".to_string());
|
||||||
// Compile host.c
|
// Compile host.c
|
||||||
let output = Command::new("clang")
|
let output = Command::new("clang")
|
||||||
.env_clear()
|
.env_clear()
|
||||||
|
.env("PATH", &env_path)
|
||||||
.args(&[
|
.args(&[
|
||||||
"-c",
|
"-c",
|
||||||
c_host_src.to_str().unwrap(),
|
c_host_src.to_str().unwrap(),
|
||||||
|
@ -75,6 +78,7 @@ pub fn rebuild_host(host_input_path: &Path) {
|
||||||
|
|
||||||
let output = Command::new("ld")
|
let output = Command::new("ld")
|
||||||
.env_clear()
|
.env_clear()
|
||||||
|
.env("PATH", &env_path)
|
||||||
.args(&[
|
.args(&[
|
||||||
"-r",
|
"-r",
|
||||||
"-L",
|
"-L",
|
||||||
|
@ -103,6 +107,7 @@ pub fn rebuild_host(host_input_path: &Path) {
|
||||||
|
|
||||||
let output = Command::new("ld")
|
let output = Command::new("ld")
|
||||||
.env_clear()
|
.env_clear()
|
||||||
|
.env("PATH", &env_path)
|
||||||
.args(&[
|
.args(&[
|
||||||
"-r",
|
"-r",
|
||||||
c_host_dest.to_str().unwrap(),
|
c_host_dest.to_str().unwrap(),
|
||||||
|
@ -145,18 +150,29 @@ fn link_linux(
|
||||||
input_paths: &[&str],
|
input_paths: &[&str],
|
||||||
link_type: LinkType,
|
link_type: LinkType,
|
||||||
) -> io::Result<(Child, PathBuf)> {
|
) -> io::Result<(Child, PathBuf)> {
|
||||||
let libcrt_path = if Path::new("/usr/lib/x86_64-linux-gnu").exists() {
|
let arch = arch_str(target);
|
||||||
Path::new("/usr/lib/x86_64-linux-gnu")
|
let usr_lib_path = Path::new("/usr/lib").to_path_buf();
|
||||||
|
let usr_lib_gnu_path = usr_lib_path.join(format!("{}-linux-gnu", arch));
|
||||||
|
let lib_gnu_path = Path::new("/lib/").join(format!("{}-linux-gnu", arch));
|
||||||
|
|
||||||
|
let libcrt_path = if usr_lib_gnu_path.exists() {
|
||||||
|
&usr_lib_gnu_path
|
||||||
} else {
|
} else {
|
||||||
Path::new("/usr/lib")
|
&usr_lib_path
|
||||||
};
|
};
|
||||||
|
|
||||||
let libgcc_path = if Path::new("/lib/x86_64-linux-gnu/libgcc_s.so.1").exists() {
|
let libgcc_name = "libgcc_s.so.1";
|
||||||
Path::new("/lib/x86_64-linux-gnu/libgcc_s.so.1")
|
let libgcc_path = if lib_gnu_path.join(libgcc_name).exists() {
|
||||||
} else if Path::new("/usr/lib/x86_64-linux-gnu/libgcc_s.so.1").exists() {
|
lib_gnu_path.join(libgcc_name)
|
||||||
Path::new("/usr/lib/x86_64-linux-gnu/libgcc_s.so.1")
|
} else if usr_lib_gnu_path.join(libgcc_name).exists() {
|
||||||
|
usr_lib_gnu_path.join(libgcc_name)
|
||||||
} else {
|
} else {
|
||||||
Path::new("/usr/lib/libgcc_s.so.1")
|
usr_lib_path.join(libgcc_name)
|
||||||
|
};
|
||||||
|
let ld_linux = match target.architecture {
|
||||||
|
Architecture::X86_64 => "/lib64/ld-linux-x86-64.so.2",
|
||||||
|
Architecture::Aarch64(_) => "/lib/ld-linux-aarch64.so.1",
|
||||||
|
_ => panic!("TODO gracefully handle unsupported linux architecture: {:?}", target.architecture),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut soname;
|
let mut soname;
|
||||||
|
@ -194,12 +210,16 @@ fn link_linux(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let env_path = env::var("PATH").unwrap_or_else(|_| "".to_string());
|
||||||
// NOTE: order of arguments to `ld` matters here!
|
// NOTE: order of arguments to `ld` matters here!
|
||||||
// The `-l` flags should go after the `.o` arguments
|
// The `-l` flags should go after the `.o` arguments
|
||||||
Ok((
|
Ok((
|
||||||
Command::new("ld")
|
Command::new("ld")
|
||||||
// Don't allow LD_ env vars to affect this
|
// Don't allow LD_ env vars to affect this
|
||||||
.env_clear()
|
.env_clear()
|
||||||
|
.env("PATH", &env_path)
|
||||||
|
// Keep NIX_ env vars
|
||||||
|
.envs(env::vars().filter(|&(ref k, _)| k.starts_with("NIX_")).collect::<HashMap<String, String>>())
|
||||||
.args(&[
|
.args(&[
|
||||||
"-arch",
|
"-arch",
|
||||||
arch_str(target),
|
arch_str(target),
|
||||||
|
@ -207,7 +227,7 @@ fn link_linux(
|
||||||
libcrt_path.join("crtn.o").to_str().unwrap(),
|
libcrt_path.join("crtn.o").to_str().unwrap(),
|
||||||
])
|
])
|
||||||
.args(&base_args)
|
.args(&base_args)
|
||||||
.args(&["-dynamic-linker", "/lib64/ld-linux-x86-64.so.2"])
|
.args(&["-dynamic-linker", ld_linux])
|
||||||
.args(input_paths)
|
.args(input_paths)
|
||||||
.args(&[
|
.args(&[
|
||||||
// Libraries - see https://github.com/rtfeldman/roc/pull/554#discussion_r496365925
|
// Libraries - see https://github.com/rtfeldman/roc/pull/554#discussion_r496365925
|
||||||
|
@ -220,6 +240,7 @@ fn link_linux(
|
||||||
"-lutil",
|
"-lutil",
|
||||||
"-lc_nonshared",
|
"-lc_nonshared",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
|
"-lc++abi",
|
||||||
"-lunwind",
|
"-lunwind",
|
||||||
libgcc_path.to_str().unwrap(),
|
libgcc_path.to_str().unwrap(),
|
||||||
// Output
|
// Output
|
||||||
|
|
|
@ -14,6 +14,11 @@ pub fn target_triple_str(target: &Triple) -> &'static str {
|
||||||
operating_system: OperatingSystem::Linux,
|
operating_system: OperatingSystem::Linux,
|
||||||
..
|
..
|
||||||
} => "x86_64-unknown-linux-gnu",
|
} => "x86_64-unknown-linux-gnu",
|
||||||
|
Triple {
|
||||||
|
architecture: Architecture::Aarch64(_),
|
||||||
|
operating_system: OperatingSystem::Linux,
|
||||||
|
..
|
||||||
|
} => "aarch64-unknown-linux-gnu",
|
||||||
Triple {
|
Triple {
|
||||||
architecture: Architecture::X86_64,
|
architecture: Architecture::X86_64,
|
||||||
operating_system: OperatingSystem::Darwin,
|
operating_system: OperatingSystem::Darwin,
|
||||||
|
@ -36,6 +41,10 @@ pub fn arch_str(target: &Triple) -> &'static str {
|
||||||
|
|
||||||
"x86-64"
|
"x86-64"
|
||||||
}
|
}
|
||||||
|
Architecture::Aarch64(_) => {
|
||||||
|
Target::initialize_aarch64(&InitializationConfig::default());
|
||||||
|
"aarch64"
|
||||||
|
}
|
||||||
Architecture::Arm(_) if cfg!(feature = "target-arm") => {
|
Architecture::Arm(_) if cfg!(feature = "target-arm") => {
|
||||||
// NOTE: why not enable arm and wasm by default?
|
// NOTE: why not enable arm and wasm by default?
|
||||||
//
|
//
|
||||||
|
@ -67,7 +76,7 @@ pub fn target_machine(
|
||||||
|
|
||||||
Target::from_name(arch).unwrap().create_target_machine(
|
Target::from_name(arch).unwrap().create_target_machine(
|
||||||
&TargetTriple::create(target_triple_str(target)),
|
&TargetTriple::create(target_triple_str(target)),
|
||||||
arch,
|
"generic",
|
||||||
"", // TODO: this probably should be TargetMachine::get_host_cpu_features() to enable all features.
|
"", // TODO: this probably should be TargetMachine::get_host_cpu_features() to enable all features.
|
||||||
opt,
|
opt,
|
||||||
reloc,
|
reloc,
|
||||||
|
|
|
@ -66,6 +66,9 @@ let
|
||||||
libffi
|
libffi
|
||||||
libxml2
|
libxml2
|
||||||
zlib
|
zlib
|
||||||
|
llvmPkgs.libcxx
|
||||||
|
llvmPkgs.libcxxabi
|
||||||
|
libunwind
|
||||||
# faster builds - see https://github.com/rtfeldman/roc/blob/trunk/BUILDING_FROM_SOURCE.md#use-lld-for-the-linker
|
# faster builds - see https://github.com/rtfeldman/roc/blob/trunk/BUILDING_FROM_SOURCE.md#use-lld-for-the-linker
|
||||||
llvmPkgs.lld
|
llvmPkgs.lld
|
||||||
# dev tools
|
# dev tools
|
||||||
|
@ -79,7 +82,7 @@ in mkShell {
|
||||||
LLVM_SYS_100_PREFIX = "${llvmPkgs.llvm}";
|
LLVM_SYS_100_PREFIX = "${llvmPkgs.llvm}";
|
||||||
|
|
||||||
APPEND_LIBRARY_PATH = stdenv.lib.makeLibraryPath
|
APPEND_LIBRARY_PATH = stdenv.lib.makeLibraryPath
|
||||||
([ pkgconfig llvmPkgs.libcxx llvmPkgs.libcxxabi libunwind ] ++ linux-only);
|
([ pkg-config llvmPkgs.libcxx llvmPkgs.libcxxabi libunwind ] ++ linux-only);
|
||||||
|
|
||||||
# Aliases don't work cross shell, so we do this
|
# Aliases don't work cross shell, so we do this
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue