环境
- 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
复现步骤
mcpp new hello,在 src/main.cpp 中使用 import std; 和 std::println
- 在
mcpp.toml 中将工具链设为 llvm:
[toolchain]
linux = "llvm@22.1.8"
- 执行
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.json(std_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 文件生效。
环境
mcpp toolchain install llvm 22.1.8安装)x86_64-unknown-linux-gnu复现步骤
mcpp new hello,在src/main.cpp中使用import std;和std::printlnmcpp.toml中将工具链设为 llvm:mcpp run实际结果
编译阶段成功,链接阶段失败:
根因分析
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.json(std_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 文件生效。