如何将不同目标文件与LLVM库链接?编译报错求助
问题分析与解决方案
你的问题核心是多文件拆分后链接顺序错误,以及编译目标文件时误用了链接参数,导致LLVM库的符号无法被正确解析。以下是具体解决步骤:
1. 核心问题拆解
- 链接顺序错误:GCC/Clang链接器是从左到右处理符号的,必须先列出你的目标文件(
.o)和源文件,再列出依赖的库。你的原Makefile把LLVM库参数放在目标文件前面,导致链接器先处理库时,还未遇到你的代码中的未定义符号,后续处理代码时无法回溯查找库中的实现。 - 编译阶段冗余参数:编译
.o目标文件时不需要--ldflags --system-libs --libs这类链接参数,仅需编译相关的--cxxflags即可,多余参数可能导致编译过程中出现不必要的冲突。
2. 修改后的Makefile
SOURCES = $(shell find ast kaleidoscope lexer logger parser -name '*.cpp') HEADERS = $(shell find ast kaleidoscope lexer logger parser -name '*.h') OBJ = ${SOURCES:.cpp=.o} CC = clang++ CFLAGS = -g -O3 -I /home/therlf/LLVM/include -I ./ -I /home/therlf/LLVM_Temp/llvm/include # 仅编译阶段需要的LLVM参数 LLVM_CXXFLAGS = `llvm-config --cxxflags` # 链接阶段需要的LLVM参数 LLVM_LDFLAGS = `llvm-config --ldflags --system-libs --libs all` .PHONY: main clean main: main.cpp ${OBJ} ${CC} ${CFLAGS} ${OBJ} $< ${LLVM_LDFLAGS} -o $@ clean: rm -f ${OBJ} main %.o: %.cpp ${HEADERS} ${CC} ${CFLAGS} ${LLVM_CXXFLAGS} -c $< -o $@
3. 关键修改说明
- 拆分LLVM参数:将原
LLVMFLAGS拆分为编译用的LLVM_CXXFLAGS和链接用的LLVM_LDFLAGS,避免编译阶段混入链接参数。 - 调整链接顺序:链接命令中先放置你的目标文件和
main.cpp,再追加LLVM链接参数,确保链接器先处理你的代码中的未定义符号,再从LLVM库中查找对应实现。 - 优化clean命令:添加删除
main可执行文件的操作,用rm -f避免目录不存在时的报错。
4. 额外排查建议
- 验证LLVM配置:运行
llvm-config --cxxflags --ldflags --system-libs --libs all,确认输出的库路径和库名称指向你安装的LLVM 10.0.0svn版本,无路径错误。 - 缩小链接范围:如果
--libs all导致链接过多冗余库,可以替换为Kaleidoscope实际需要的组件,比如--libs core irreader analysis executionengine mcjit interpreter,减少潜在冲突。
内容的提问来源于stack exchange,提问作者TherLF
相关产品推荐
相关产品推荐

