I am following the LLVM tutorial : Kaleidoscope: Code generation to LLVM IR, which will use LLVM libraries like LLVMContext, Module and so on. Different from the tutorial, I am trying to write the lexer, parser and code generator in different source file and link them into one executable file. Here is my compile command on the Ubuntu 20.04:
clang++ -g -O3 -I /home/therlf/LLVM/include -I ./ -I /home/therlf/LLVM_Temp/llvm/include `llvm-config --cxxflags --ldflags --system-libs --libs all` ast/CallExprAST.o ast/NumberExprAST.o ast/PrototypeAST.o ast/FunctionAST.o ast/BinaryExprAST.o ast/VariableExprAST.o lexer/lexer.o logger/logger.o parser/parser.o main.cpp -o main
But I only get lots of "undefined error". Here are some of them:
/usr/bin/ld: /tmp/main-2b71c8.o:(.data+0x0): undefined reference to `llvm::DisableABIBreakingChecks
/home/therlf/MyProject/tmp/ast/CallExprAST.cpp:6: undefined reference to `llvm::Module::getFunction(llvm::StringRef) const'
/home/therlf/LLVM/include/llvm/IR/InstrTypes.h:1112: undefined reference to `llvm::Instruction::Instruction(llvm::Type*, unsigned int, llvm::Use*, unsigned int, llvm::Instruction*)'
/usr/bin/ld: /home/therlf/LLVM/include/llvm/IR/InstrTypes.h:977: undefined reference to `llvm::VectorType::get(llvm::Type*, llvm::ElementCount)'
At first I thought it's including path's error. But when I compiled and ran the source file in the tutorial successfully, which is just a whole source file with everything packed into file, I knew the including path is nothing wrong.
I have searched for this question, and some blogs say that you should link them with lld
and use the -fuse-ld=lld
in the compile command. But I don't have lld
, and the clang++
doesn't know the argument -fuse-ld
, which will report an error. The blog says that you should have lld
as long as you have installed LLVM. In fact here are what I got: LLVM tools
And I know the llvm-link
is used to link IR file, not the object file compiled from cpp source file.
Here is my LLVM version:
10.0.0svn
And here is my 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++
# -stdlib=libc++ -std=c++11
CFLAGS = -g -O3 -I /home/therlf/LLVM/include -I ./ -I /home/therlf/LLVM_Temp/llvm/include
LLVMFLAGS = `llvm-config --cxxflags --ldflags --system-libs --libs all`
.PHONY: main
main: main.cpp ${OBJ}
${CC} ${CFLAGS} ${LLVMFLAGS} ${OBJ} $< -o $@
clean:
rm -r ${OBJ}
%.o: %.cpp ${HEADERS}
${CC} ${CFLAGS} ${LLVMFLAGS} -c $< -o $@
In fact, I follow the project structure from the repository : ghaiklor/llvm-kaleidoscope and the Makefile is nearly identical.
Sincerely thank you for your answers!
I have sloved this problem by exchanging my linker ld
with linker lld
.
You should install lld
first by this command in ubuntu if you can't find it in the LLVM/tools directory like I did.
sudo apt-get update
sudo apt-get -y install lld
And then you can add -fuse-ld=lld
to your compile command
or you can
cd /usr/bin
ln -s /path/to/ld.lld /usr/bin/ld
This should work if everything goes well.
But I still can't figure out the reason behand this situation :-(