Start with the first enabled linker target

This commit is contained in:
Rui Ueyama committed 2026-09-13 20:15:17 +09:00
1 parent dcf75d7d8b
commit df5a97ede2
2 files changed
+67 -53

No files matched your search

+59 -47
View File
@@ -14,59 +14,71 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
// and huge pages improve large links. The Rust entry point currently does
// neither.
// Each target has its own monomorphized link function. Start with x86-64 and,
// if the inputs use another machine type, run the matching function instead.
type LinkFn = fn(&[std::ffi::OsString]) -> Result<i32, String>;
// Each target has its own monomorphized link function. Start with the first
// enabled target and switch to the matching function if the inputs differ.
const TARGETS: &[(&str, LinkFn)] = &[
#[cfg(feature = "x86_64")]
("x86_64", mold_target_x86_64::link),
#[cfg(feature = "i386")]
("i386", mold_target_i386::link),
#[cfg(feature = "arm32")]
("arm32", mold_target_arm32::link),
#[cfg(feature = "arm32be")]
("arm32be", mold_target_arm32be::link),
#[cfg(feature = "arm64")]
("arm64", mold_target_arm64::link),
#[cfg(feature = "arm64be")]
("arm64be", mold_target_arm64be::link),
#[cfg(feature = "riscv64")]
("riscv64", mold_target_riscv64::link),
#[cfg(feature = "riscv64be")]
("riscv64be", mold_target_riscv64be::link),
#[cfg(feature = "riscv32")]
("riscv32", mold_target_riscv32::link),
#[cfg(feature = "riscv32be")]
("riscv32be", mold_target_riscv32be::link),
#[cfg(feature = "ppc64v2")]
("ppc64v2", mold_target_ppc64v2::link),
#[cfg(feature = "ppc32")]
("ppc32", mold_target_ppc32::link),
#[cfg(feature = "ppc64v1")]
("ppc64v1", mold_target_ppc64v1::link),
#[cfg(feature = "s390x")]
("s390x", mold_target_s390x::link),
#[cfg(feature = "sparc64")]
("sparc64", mold_target_sparc64::link),
#[cfg(feature = "m68k")]
("m68k", mold_target_m68k::link),
#[cfg(feature = "sh4")]
("sh4", mold_target_sh4::link),
#[cfg(feature = "sh4be")]
("sh4be", mold_target_sh4be::link),
#[cfg(feature = "loongarch64")]
("loongarch64", mold_target_loongarch64::link),
#[cfg(feature = "loongarch32")]
("loongarch32", mold_target_loongarch32::link),
];
fn link_for_target(target: &str, cmdline: &[std::ffi::OsString]) -> Result<i32, String> {
match target {
#[cfg(feature = "x86_64")]
"x86_64" => mold_target_x86_64::link(cmdline),
#[cfg(feature = "i386")]
"i386" => mold_target_i386::link(cmdline),
#[cfg(feature = "arm32")]
"arm32" => mold_target_arm32::link(cmdline),
#[cfg(feature = "arm32be")]
"arm32be" => mold_target_arm32be::link(cmdline),
#[cfg(feature = "arm64")]
"arm64" => mold_target_arm64::link(cmdline),
#[cfg(feature = "arm64be")]
"arm64be" => mold_target_arm64be::link(cmdline),
#[cfg(feature = "riscv64")]
"riscv64" => mold_target_riscv64::link(cmdline),
#[cfg(feature = "riscv64be")]
"riscv64be" => mold_target_riscv64be::link(cmdline),
#[cfg(feature = "riscv32")]
"riscv32" => mold_target_riscv32::link(cmdline),
#[cfg(feature = "riscv32be")]
"riscv32be" => mold_target_riscv32be::link(cmdline),
#[cfg(feature = "ppc64v2")]
"ppc64v2" => mold_target_ppc64v2::link(cmdline),
#[cfg(feature = "ppc32")]
"ppc32" => mold_target_ppc32::link(cmdline),
#[cfg(feature = "ppc64v1")]
"ppc64v1" => mold_target_ppc64v1::link(cmdline),
#[cfg(feature = "s390x")]
"s390x" => mold_target_s390x::link(cmdline),
#[cfg(feature = "sparc64")]
"sparc64" => mold_target_sparc64::link(cmdline),
#[cfg(feature = "m68k")]
"m68k" => mold_target_m68k::link(cmdline),
#[cfg(feature = "sh4")]
"sh4" => mold_target_sh4::link(cmdline),
#[cfg(feature = "sh4be")]
"sh4be" => mold_target_sh4be::link(cmdline),
#[cfg(feature = "loongarch64")]
"loongarch64" => mold_target_loongarch64::link(cmdline),
#[cfg(feature = "loongarch32")]
"loongarch32" => mold_target_loongarch32::link(cmdline),
_ => {
eprintln!("mold: unsupported target: {target}; rebuild mold with the appropriate target support");
std::process::exit(1);
for &(name, link) in TARGETS {
if name == target {
return link(cmdline);
}
}
eprintln!(
"mold: unsupported target: {target}; rebuild mold with the appropriate target support"
);
std::process::exit(1);
}
fn main() {
let Some(&(initial_target, _)) = TARGETS.first() else {
eprintln!("mold: no targets enabled; rebuild mold with the appropriate target support");
std::process::exit(1);
};
let args = std::env::args_os().collect();
let status = mold::driver::main(args, link_for_target);
let status = mold::driver::main(args, initial_target, link_for_target);
std::process::exit(status);
}
+8 -6
View File
@@ -17,11 +17,13 @@ use crate::{error, fatal, passes};
/// Runs the linker with the given command line. Returns the exit status.
///
/// `link_for_target` links for a named target, or reports the target the
/// inputs are actually for; the executable provides it, as the targets
/// are instantiated in crates of their own.
/// `initial_target` is an enabled target used for the initial argument
/// parsing. `link_for_target` links for a named target, or reports the
/// target the inputs are actually for; the executable provides both, as
/// the targets are instantiated in crates of their own.
pub fn main(
argv: Vec<std::ffi::OsString>,
initial_target: &str,
link_for_target: impl Fn(&str, &[std::ffi::OsString]) -> Result<i32, String>,
) -> i32 {
// Process -run option first. process_run_subcommand() does not return.
@@ -37,9 +39,9 @@ pub fn main(
// Parse non-positional command line options
let cmdline = cmdline::expand_response_files(&argv);
// Parse with x86-64 defaults; if the target turns out to be different,
// start over with the right one.
let mut target = "x86_64".to_string();
// Parse with an enabled target's defaults; if the target turns out to
// be different, start over with the right one.
let mut target = initial_target.to_string();
loop {
if let Some(cwd) = &orig_cwd {
let _ = std::env::set_current_dir(cwd);