Skip to content

Linux 下 llvm 工具链链接阶段传入 --no-default-config,丢失 clang++.cfg 中的 --sysroot,导致 cannot open Scrt1.o/crti.o/crtn.o #195

Description

@1115040131

环境

  • mcpp 0.0.81
  • 工具链:llvm@22.1.8(通过 mcpp toolchain install llvm 22.1.8 安装)
  • 系统:Linux x86_64(Ubuntu24.04 WSL2)
  • 标准库:libc++,目标三元组 x86_64-unknown-linux-gnu

复现步骤

  1. mcpp new hello,在 src/main.cpp 中使用 import std;std::println
  2. mcpp.toml 中将工具链设为 llvm:
    [toolchain]
    linux = "llvm@22.1.8"
  3. 执行 mcpp run

实际结果

编译阶段成功,链接阶段失败:

ld.lld: error: cannot open Scrt1.o: No such file or directory
ld.lld: error: cannot open crti.o: No such file or directory
ld.lld: error: cannot open crtn.o: No such file or directory
clang++: error: linker command failed with exit code 1

根因分析

mcpp 生成的链接命令中包含 --no-default-config,该标志会让 clang 跳过工具链自带的 bin/clang++.cfg。而 --sysroot=<subos> 只在这个 cfg 文件里设置,CRT 启动对象(Scrt1.o/crti.o/crtn.o)位于 <subos>/lib(以及 xim-x-glibc/2.39/lib64)下。缺少 --sysroot/-B 时,clang driver 会把裸文件名 Scrt1.o 等直接传给 lld,lld 无法解析。这个 --no-default-config 来自缓存的 std-module.jsonstd_build_commands),在链接阶段被复用,却没有把 sysroot 相关的 flag 补回来。

验证

以下任一方式都能让 mcpp run 成功:

  • CCC_OVERRIDE_OPTIONS='+--sysroot=<subos>' mcpp run
  • 在链接命令中手动加 -B<glibc>/lib64
  • 从链接命令中去掉 --no-default-config(使 clang++.cfg 生效)

修复建议

当 mcpp 传入 --no-default-config 时,应在链接阶段自行注入 sysroot/CRT 相关 flag(--sysroot、dynamic-linker、rpath),与 clang++.cfg 已计算好的内容保持一致;或者在最终链接时不传 --no-default-config,让 cfg 文件生效。

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions