I decided to start playing around with building my own programming language recently, and to use LLVM to handle the assembly-level details. I’m on Kubuntu 18.04, and I started out using LLVM 6.0 from Kubuntu’s packages. I put together code for dealing with my language, then went over the Kaleidoscope tutorials (which have been extremely helpful btw!). I was able to successfully get my own compiler to generate IR using LLVM, use PassManager to write that to a native .o file, use gcc to link that, and execute a tiny program written in my own language.
I also decided it was a good time to learn CMake, so I set up my project using that. The CMakeLists.txt file I’m using is essentially just taken from: https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project - though originally it would not link. From scouring the internet I made 2 changes to get that working: replaced “support core irreader” with “all”, and replaced “${llvm_libs}” with just “LLVM”.
However as I was starting to play with setting up JIT, I hit more differences between the version of LLVM in Kubuntu and the version the examples and documentation were written against. So I decided to try to update to a newer version of LLVM… and this is where I’ve been stuck for several days now. Here are the steps I’ve taken:
- Uninstalled any llvm packages I could find from Kubuntu’s package manager.
- Followed the getting started guide: https://llvm.org/docs/GettingStarted.html - I git cloned LLVM, checked out the 10.0.0 tag, ran cmake as instructed, with the Release type. When that completed successfully I ran sudo ninja install.
- I then went back to my project and adjusted a couple places to successfully compile against the new version.
- At this point I put “${llvm_libs}” in the CMakeLists.txt file back to match the example. However I was getting a massive wall of link errors.
- I assumed I must have built LLVM incorrectly somehow, so in an effort to undo that install, I deleted everything I could find under /usr/local that had LLVM in its name, downloaded the 10.0 release from https://releases.llvm.org/download.html for ubuntu 18.04, and extracted that all to /usr/local.
- I can still successfully compile, but not link.
At this point I’m not sure what to try next. Is there additional documentation somewhere for how to “install” a current release of LLVM correctly?
For reference here’s my final CMakeLists.txt file:
cmake_minimum_required(VERSION 3.10)
project(CBreakCompiler)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_compile_options(-Wall)
find_package(LLVM 10.0.0 REQUIRED CONFIG)
message(STATUS “Found LLVM ${LLVM_PACKAGE_VERSION}”)
message(STATUS “Using LLVMConfig.cmake in: ${LLVM_DIR}”)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
add_executable(CBreakCompiler
src/main.cpp
src/Parser.cpp
src/SourceTokenizer.cpp
src/IRCompiler.cpp
src/CompiledOutput.cpp)
llvm_map_components_to_libnames(llvm_libs all)
target_link_libraries(CBreakCompiler ${llvm_libs})
And a snippet from the cmake output corresponding to those message lines:
– Found LLVM 10.0.0
– Using LLVMConfig.cmake in: /usr/local/lib/cmake/llvm
There are dozens of link errors… the first few and last few are:
CMakeFiles/CBreakCompiler.dir/src/main.cpp.o:(.data.rel+0x0): undefined reference to llvm::DisableABIBreakingChecks' CMakeFiles/CBreakCompiler.dir/src/main.cpp.o: In function
std::default_deletellvm::LLVMContext::operator()(llvm::LLVMContext*) const’:
main.cpp:(.text.ZNKSt14default_deleteIN4llvm11LLVMContextEEclEPS1[ZNKSt14default_deleteIN4llvm11LLVMContextEEclEPS1]+0x1e): undefined reference to llvm::LLVMContext::~LLVMContext()' ... CMakeFiles/CBreakCompiler.dir/src/CompiledOutput.cpp.o:(.[data.rel.ro](http://data.rel.ro)+0xe0): undefined reference to
llvm::raw_ostream::anchor()’
CMakeFiles/CBreakCompiler.dir/src/CompiledOutput.cpp.o:(.data.rel.ro+0xf8): undefined reference to typeinfo for llvm::raw_pwrite_stream' CMakeFiles/CBreakCompiler.dir/src/CompiledOutput.cpp.o:(.[data.rel.ro](http://data.rel.ro)+0x110): undefined reference to
typeinfo for llvm::raw_ostream’