使用LLVM和C++构建共享库时出现链接错误
问题
我正在开发一个使用C++和LLVM构建共享库的项目,目标是从某编程语言的抽象语法树(AST)生成LLVM IR。但构建过程中出现了链接错误,我认为这些错误与LLVM库相关,但无法解决。
用于构建共享库的命令:
g++ -shared -o libNodeBridge.dylib Compiler/bridge/bridge/JavaBridge.cpp Compiler/bridge/token/Token.cpp Compiler/bridge/parser/ParseTokenToAst.cpp Compiler/llvm_codegen/LLVMCodeGen.cpp \ $(/Users/kagelol/_development/Compiler/bin/llvm-config --cxxflags) -frtti \ -I/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/include/darwin
构建时的链接错误:
ld: Undefined symbols: llvm::LLVMContext::LLVMContext(), referenced from: LLVMCodeGen::LLVMCodeGen() in LLVMCodeGen-76e962.o llvm::LLVMContext::~LLVMContext(), referenced from: LLVMCodeGen::~LLVMCodeGen() in JavaBridge-773828.o ...
我使用Xcode开发,已在开发环境中添加必要的头文件和库路径,怀疑问题与LLVM库的链接方式有关,但不确定具体原因。请问:
- 与llvm::LLVMContext及其析构函数等相关符号的链接错误可能由什么导致?
- 构建基于LLVM的共享库时是否需要额外的链接标志或库?
- 在Xcode中配置LLVM库链接是否有遗漏的步骤?
解答
1. 符号未定义的原因
核心原因是编译阶段仅引入了LLVM的头文件(通过--cxxflags参数),但链接阶段未关联LLVM的实现库。llvm-config --cxxflags仅提供编译所需的头文件路径、C++标准等编译选项,不会告知链接器需要链接哪些LLVM库,导致链接器找不到llvm::LLVMContext等类的具体实现代码。
2. 需要的额外链接标志
必须添加LLVM的链接相关选项,修改构建命令时需加入llvm-config的--libs、--ldflags和--system-libs参数:
g++ -shared -o libNodeBridge.dylib Compiler/bridge/bridge/JavaBridge.cpp Compiler/bridge/token/Token.cpp Compiler/bridge/parser/ParseTokenToAst.cpp Compiler/llvm_codegen/LLVMCodeGen.cpp \ $(/Users/kagelol/_development/Compiler/bin/llvm-config --cxxflags --libs --ldflags --system-libs) -frtti \ -I/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/include/darwin
--libs:列出项目需要链接的LLVM核心库(如LLVMCore、LLVMIRReader等)--ldflags:提供链接器所需的路径和通用链接选项--system-libs:列出LLVM依赖的系统库(如zlib、ncurses等)
3. Xcode中可能遗漏的配置步骤
如果用Xcode构建,除了添加头文件和库路径,还要检查以下几点:
- Other Linker Flags:在Build Settings中添加
$(/Users/kagelol/_development/Compiler/bin/llvm-config --libs --ldflags --system-libs)的输出内容,确保链接器能找到LLVM库 - Runpath Search Paths:添加LLVM库的安装路径(如
/Users/kagelol/_development/Compiler/lib),确保运行时能加载到LLVM动态库 - C++标准一致性:确认Xcode的C++ Language Dialect和LLVM编译时使用的标准一致(可通过
llvm-config --cxxflags查看LLVM用的标准,比如-std=c++17) - RTTI开启:在Build Settings中找到
Enable C++ RTTI并设置为Yes,和命令行的-frtti对应
内容的提问来源于stack exchange,提问作者KAGE
相关产品推荐
相关产品推荐

