From c93545de5eb45d17d0afe14f11b913f7a652a329 Mon Sep 17 00:00:00 2001 From: LunaStev Date: Wed, 1 Apr 2026 16:55:29 +0900 Subject: [PATCH] feat(cli): add `-C link-sysroot` option and custom linker validation This commit introduces a new `-C link-sysroot=` option to explicitly pass a sysroot argument to the linking stage. It also adds a safety validation check to the build request: when both a custom linker (`-C linker=...`) and a general sysroot (`--sysroot=...`) are specified, the CLI now requires the user to explicitly define the linker's sysroot. This prevents confusing build failures where the general sysroot is applied only to the compile stage but ignored during the link stage by the custom linker. [Details] - Added `-C link-sysroot=` to `parse_llvm_codegen_spec`. - Added validation in `validate_build_request` to enforce explicit link sysroot when using a custom linker alongside a general sysroot. - Added helper functions (`is_link_sysroot_arg`, `has_explicit_link_sysroot_arg`, `set_link_sysroot_arg`) to safely manage, check, and deduplicate sysroot link arguments. - Updated the CLI help output (`print_help`) to document the new option. Signed-off-by: LunaStev --- src/cli.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/cli.rs b/src/cli.rs index 80aa8215..43156d2c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -739,11 +739,12 @@ fn parse_llvm_codegen_spec(spec: &str, llvm: &mut LlvmFlags) -> Result<(), CliEr match key { "linker" => llvm.linker = Some(value.to_string()), "link-arg" => llvm.link_args.push(value.to_string()), + "link-sysroot" => set_link_sysroot_arg(&mut llvm.link_args, value), "code-model" => llvm.code_model = Some(value.to_string()), "relocation-model" => llvm.relocation_model = Some(value.to_string()), _ => { return Err(CliError::usage(format!( - "unsupported -C option '{}': supported keys are linker, link-arg, no-default-libs, code-model, relocation-model", + "unsupported -C option '{}': supported keys are linker, link-arg, link-sysroot, no-default-libs, code-model, relocation-model", key ))); } @@ -1413,6 +1414,18 @@ fn validate_build_request( )); } + if need_link + && global.llvm.linker.is_some() + && global.llvm.sysroot.is_some() + && !has_explicit_link_sysroot_arg(&global.llvm.link_args) + { + return Err(CliError::usage( + "when using -C linker=..., --sysroot= is compile-stage only; \ + pass linker sysroot explicitly with -C link-sysroot= \ + (or -C link-arg=--sysroot=)", + )); + } + if build.output.is_some() { let compile_count = classified .iter() @@ -1433,6 +1446,19 @@ fn validate_build_request( Ok(()) } +fn is_link_sysroot_arg(arg: &str) -> bool { + arg == "--sysroot" || arg.starts_with("--sysroot=") || arg.contains("--sysroot=") +} + +fn has_explicit_link_sysroot_arg(args: &[String]) -> bool { + args.iter().any(|arg| is_link_sysroot_arg(arg)) +} + +fn set_link_sysroot_arg(link_args: &mut Vec, value: &str) { + link_args.retain(|arg| !is_link_sysroot_arg(arg)); + link_args.push(format!("--sysroot={}", value)); +} + fn create_build_plan( build: &BuildRequest, classified: &[ClassifiedInput], @@ -2716,6 +2742,11 @@ pub fn print_help() { "-C link-arg=".color("38,139,235"), "Append raw linker argument" ); + println!( + " {:<24} {}", + "-C link-sysroot=".color("38,139,235"), + "Set linker sysroot as --sysroot=" + ); println!( " {:<24} {}", "-C relocation-model=".color("38,139,235"),