如何修复 Rust clang crate 的符号查找错误:undefined symbol: LLVMInitializeAArch64TargetInfo
问题
在尝试运行使用 clang crate 的 Rust 可执行文件时,你会看到类似下面的错误信息:
clang_symbol_lookup_error.txt
$ cargo run clangtest.cpp
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/asx clangtest.cpp`
target/debug/clangtest: symbol lookup error: /lib/x86_64-linux-gnu/libclang-19.so.19: undefined symbol: LLVMInitializeAArch64TargetInfo, version LLVM_19.1解决方案
出现此错误是因为 Cargo 链接了错误的 libLLVM。常见原因是安装了 rocm(AMD 的计算栈),它自带了与 libclang 所使用的不兼容的 libLLVM。
要解决此问题,请添加 build.rs:
build.rs
use std::{env, path::{Path, PathBuf}};
fn main() {
// 允许通过环境变量覆盖,以提供灵活性。
// 示例:LLVM19_LIB_DIR=/custom/llvm19/lib cargo build
let llvm_dir = env::var("LLVM19_LIB_DIR").unwrap_or_else(|_| "/usr/lib/llvm-19/lib".to_string());
let llvm_so_candidates = [
"libLLVM.so", // soname 符号链接
"libLLVM-19.so", // 备选命名模式
"libLLVM.so.19", // 带版本号模式
"libLLVM.so.19.1", // 特定次版本
];
let dir_path = Path::new(&llvm_dir);
if !dir_path.is_dir() {
panic!("LLVM directory '{llvm_dir}' does not exist. Set LLVM19_LIB_DIR to the correct path.");
}
// 尝试找到一个实际存在的库文件,以便显式传递给链接器,
// 避免从其他位置(例如 /opt/amdgpu)选取。
let chosen_lib: Option<PathBuf> = llvm_so_candidates.iter()
.map(|name| dir_path.join(name))
.find(|p| p.exists());
if let Some(lib_path) = chosen_lib {
let lib_dir = lib_path.parent().unwrap();
// 确保优先搜索我们期望的目录
println!("cargo:rustc-link-search=native={}", lib_dir.display());
// 仍然发出通用的 link-lib,以满足可能分散在各组件中的符号。
println!("cargo:rustc-link-lib=dylib=LLVM");
// 通过将库的绝对路径作为链接器参数传递来强制使用该库
// (放在对象之后,以便用于符号解析)
println!("cargo:rustc-link-arg={}", lib_path.display());
// 添加 rpath,使运行时加载器也优先使用此目录。
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_dir.display());
// 可选地,将我们的路径添加到 RUNPATH 以同样优先使用
// (GNU ld 对 rpath/runpath 的处理略有不同;在此使用 rpath 对大多数系统已足够)
println!("cargo:rerun-if-env-changed=LLVM19_LIB_DIR");
} else {
panic!("Could not locate any libLLVM* candidate in {llvm_dir}. Candidates tried: {:?}", llvm_so_candidates);
}
}此外,还需要在 Cargo.toml 中配置使用该构建脚本:
Cargo.toml
[package]
build = "build.rs"Check out similar posts by category:
Rust
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow