在macOS上链接rustc_driver时,针对x86_64架构出现未定义符号
此步骤失败:
我想在macOS 10.13(High Sierra)上构建Rust 1.83。
我已经用llvm@15构建了Rust 1.74。
我想将Rust升级到1.83,它需要llvm@18。
我已经构建好了llvm@18。
在使用以下命令安装Rust时:
brew install rust --cc=llvm_clang --debug
它通过前两个阶段:
构建引导程序
完成 dev 配置文件 [未优化] 目标
构建stage0库产物(x86_64-apple-darwin)
完成 release 配置文件 [优化] 目标
此步骤失败:
构建编译器产物(stage0 -> stage1,x86_64-apple-darwin)
Compiling rustc_driver v0.0.0 (/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/compiler/rustc_driver)
错误:与 cc 的链接失败:退出状态1
= 注:环境变量 -u IPHONEOS_DEPLOYMENT_TARGET -u TVOS_DEPLOYMENT_TARGET -u XROS_DEPLOYMENT_TARGET LC_ALL="C" PATH="/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-sysroot/lib/rustlib/x86_64-apple-darwin/bin:/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0/lib/rustlib/x86_64-apple-darwin/bin:/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0/lib/rustlib/x86_64-apple-darwin/bin:/usr/local/Homebrew/Library/Homebrew/shims/mac/super:/usr/local/opt/openssl@3/bin:/usr/local/opt/[email protected]/bin:/usr/local/opt/lz4/bin:/usr/local/opt/xz/bin:/usr/local/opt/zstd/bin:/usr/local/opt/llvm@18/bin:/usr/local/opt/pkgconf/bin:/usr/local/opt/[email protected]/bin:/usr/local/opt/[email protected]/libexec/bin:/usr/bin:/bin:/usr/sbin:/sbin" VSLANG="1033" ZERO_AR_DATE="1" "cc" "-Wl,-exported_symbols_list" "-Wl,/private/tmp/rustcOEG45K/list" "-arch" "x86_64" "-m64" "/private/tmp/rustcOEG45K/symbols.o" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/rustc_driver-f95b5e658c91b7ee.rustc_driver.889d9b77049e32a9-cgu.0.rcgu.o" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/rustc_driver-f95b5e658c91b7ee.6qwd3s8qwowechi8rleewsxw6.rcgu.rmeta" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/rustc_driver-f95b5e658c91b7ee.dkiskpjvobyynmlg3nn6jgt7n.rcgu.o" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/librustc_driver_impl-a700fc44515a0e81.rlib" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/libctrlc-7a60cb697c45b146.rlib" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/libnix-f36c83a9e46a3b69.rlib"
...
很长的日志,包含大量 "xxx.rlib",因此我没有粘贴全部。
...
"/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-sysroot/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-2bd8a1aedecf36a6.rlib" "-lz" "-lLLVM-18" "-lc++" "-liconv" "-lSystem" "-lc" "-lm" "-L" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/build/psm-b4e3eaf56eb782b8/out" "-L" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/build/blake3-bf8fb3eee317eacd/out" "-L" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/build/blake3-bf8fb3eee317eacd/out" "-L" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/build/rustc_llvm-caa2cf5c24c78a7c/out" "-L" "/usr/local/Cellar/llvm@18/18.1.8/lib" "-o" "/private/tmp/rust-20260227-81377-lg6x85/rustc-1.83.0-src/build/x86_64-apple-darwin/stage0-rustc/x86_64-apple-darwin/release/deps/librustc_driver-f95b5e658c91b7ee.dylib" "-Wl,-dead_strip" "-dynamiclib" "-Wl,-dylib" "-Wl,-install_name" "-Wl,@rpath/librustc_driver-f95b5e658c91b7ee.dylib" "-nodefaultlibs" "-Wl,-rpath,@loader_path/../lib"
= 注:在x86_64架构下未定义符号: "vtable for std::__1::basic_ostringstream, std::__1::allocator\ >", 在librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) 被引用。NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. "std::__1::basic_stringbuf, std::__1::allocator\ >::str() const", 在librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) 引用。 "VTT for std::__1::basic_ostringstream, std::__1::allocator\ >", 引用自: _LLVMRustPrintTargetCPUs in librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) __ZNSt3::__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ne180100Ev in librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) std::__1::basic_ostringstream, std::__1::allocator\ >::~basic_ostringstream() in librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) "vtable for std::__1::basic_stringbuf, std::__1::allocator\ >", 在librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) 引用自:__ZNSt3::__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ne180100Ev in librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o) NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. ld: 为架构x86_64找不到符号clang: 错误:链接器命令失败,退出状态1(使用 -v查看调用信息)
看起来像是没有链接到某些库,但我还没能查出具体缺少的是哪些。
我猜这个错误与函数
LLVMRustPrintTargetCPUs
在
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp中有关。
所以我创建了一个简单的测试C++文件test-stringstream.cpp,用来模拟对ostringstream的函数调用
#include <iostream>
#include <sstream>
#include <iomanip>
#include <llvm/ADT/ArrayRef.h>
using StringRef = std::string_view;
/// getLongestEntryLength - Return the length of the longest entry in the table.
template <typename KV> static size_t getLongestEntryLength(llvm::ArrayRef<KV> Table) {
size_t MaxLen = 0;
for (auto &I : Table)
MaxLen = std::max(MaxLen, std::strlen(I.Key));
return MaxLen;
}
using PrintBackendInfo = void(void *, const char *Data, size_t Len);
int main() {
std::cout << std::stringstream("hi\n").str();
std::ostringstream Buf;
const StringRef HostCPU = "skylake";
unsigned MaxCPULen = 7;
Buf << " " << std::left << std::setw(MaxCPULen) << "native"
<< " - Select the CPU of the current host "
"(currently "
<< HostCPU << ").\n";
const auto &BufString = Buf.str();
// Print(Out, BufString.data(), BufString.size());
std::cout << "buf:" << BufString.data() << "\n";
}
它可以被编译,也可以执行且没有任何错误。
[2/2] Linking CXX executable test-stringstream
ld: warning: object file (CMakeFiles/test-stringstream.dir/src/test-stringstream.cpp.o) was built for newer OSX version (10.14) than being linked (10.13)
$ ./test-stringstream
hi
buf: native - Select the CPU of the current host (currently skylake).
我不知道如何解决这些错误:
note: Undefined symbols for architecture x86_64:
"vtable for std::__1::basic_ostringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >", referenced from:
__ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ne180100Ev in librustc_codegen_llvm-ca4c576b704b5d25.rlib(7372e21ddc8be4fd-PassWrapper.o)
解决方案
命令中的编译器参数应为 --cc=llvm_clang++
brew install rust --cc=llvm_clang++ --debug