-
Notifications
You must be signed in to change notification settings - Fork 31
CMake Options for LLVM
LLVM uses CMake and has extensive additions to the default options, documented here.
Here are some of the most common patterns to use with CMake options to avoid build problems or to get what you want.
First, you're strongly encouraged to use Ninja
as the generator. Not only it's faster than Make
on Unix, but it's also supported in many UI editors, too. The option is -G Ninja
.
You can also remove CMake developer messages by adding this alias
on your start up files:
alias cmake='cmake -Wno-dev`
It's also a good practice to enable assertions on every build, even (and especially) release builds. The option is -DLLVM_ENABLE_ASSERTIONS=True
and is enabled by default on Debug builds, but not Release ones.
LLVM defaults to clang when it can find it, but you can change the compiler (or force a particular version of clang) with the options -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
.
You may also like to use LLD as the default linker, but not all distros put LLD as the default linker, so you can force it with the option -DLLVM_USE_LINKER=lld
.
Finally, the -j
option controls the number of jobs in general, but linker jobs can take all available memory, especially in Debug mode, so it's recommended that you set the number of link jobs to a smaller number than what Ninja
picks for -j
(which is more than the number of cores), with -DLLVM_PARALLEL_LINK_JOBS=4
. Divide your available RAM by 8 to be safe, as LLVM static debug objects are known to cause linkers to use 6GB or more per process.
If you use ccache
, and it's installed in the system, then you just need to enable via the option -DLLVM_CCACHE_BUILD=ON
and CMake/Ninja will do the right thing.
If you don't care about all the multiple targets LLVM supports (not many people do), you can limit the targets with the option -DLLVM_TARGETS_TO_BUILD="host"
and get only the host you're building on. This is helpful, as you can build on multiple types of hosts and not have to change the command line.
If you want to add more, you can add a list separated by semi-colon (;
) like -DLLVM_TARGETS_TO_BUILD="X86;ARM;AARCH64"
.
For LLVM projects, the problem is the reverse. By default, LLVM only builds the llvm
project. For everything else, you need to add them via the option -DLLVM_ENABLE_PROJECTS="clang;mlir"
. Both clang
and mlir
are big projects, only add them if you want.
You should use clang
and lld
from the system (via packages) and not have to build yours every time, especially because the releases are tested and your tree isn't. So there's no need to build lld
, libc++
, etc. unless you're changing them.
The default build type is Release
.
If you just want line information to step through a debugger in LLVM code (between your own code's calls), you can just use -DCMAKE_BUILD_TYPE=RelWithDebInfo
. This is the same as Release
, but with line information. You can't print the value of variables, but you can step through the code, which is often enough when you want to go through LLVM when stepping over your code.
Full debug builds are enabled with -DCMAKE_BUILD_TYPE=Debug
and have all symbols. The binaries (libraries, executables) are huge. It will take a long time to link them, use a lot of RAM and disk and probably crash your build if you didn't use the -DLLVM_PARALLEL_LINK_JOBS
flag (see above).
A way to reduce the size and time of debug builds is to build the librarys as shared libraryes instead of static ones. You do that with the flag -DBUILD_SHARED_LIBS=True
. This isn't the default, and the configuration isn't as well tested as static builds, so be ready for weird bugs if you try that.
When running ninja check-all
, LLVM uses LIT to run the tests. You can pass options to LIT via the flag -DLLVM_LIT_ARGS="-sv"
. Here, -s
shows only a progress bar (instead of a full list of tests) and -v
shows errors if tests fail. This is the most helpful combination for developers.
Since LLVM does not use C++ exceptions, by default, LLVM drops exception handling from C++, passing -no-eh
options to the compiler. But if your project uses exceptions, you'll get linker errors. So LLVM has a pair of options to enable that, which is -DLLVM_ENABLE_EH=ON -DLLVM_ENABLE_RTTI=ON
. You need both.
It won't make LLVM use exceptions, but it will build LLVM objects with exception and RTTI information, allowing your program to link against it without errors.
Here's a helpful alias section for your startup files (ex. .bashrc
):
alias cmake='cmake -Wno-dev'
alias cmake_llvm_base='cmake -G Ninja -DLLVM_ENABLE_ASSERTIONS=True -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_USE_LINKER=lld -DLLVM_PARALLEL_LINK_JOBS=4 -DLLVM_ENABLE_PROJECTS="clang;mlir" -DLLVM_LIT_ARGS="-sv" -DLLVM_TARGETS_TO_BUILD="host" -DCMAKE_INSTALL_PREFIX=install -DLLVM_CCACHE_BUILD=ON'
alias cmake_llvm="cmake_llvm_base -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TESTS=True"
alias cmake_llvm_eh="cmake_llvm -DLLVM_ENABLE_EH=ON -DLLVM_ENABLE_RTTI=ON"
alias cmake_llvm_dbg="cmake_llvm_base -DCMAKE_BUILD_TYPE=Debug -DLLVM_BUILD_TESTS=False"
alias cmake_llvm_dbg_eh="cmake_llvm_dbg -DLLVM_ENABLE_EH=ON -DLLVM_ENABLE_RTTI=ON"
alias cmake_llvm_dbg_shr="cmake_llvm_dbg -DBUILD_SHARED_LIBS=True"
alias cmake_llvm_dbg_shr_eh="cmake_llvm_dbg_shr -DLLVM_ENABLE_EH=ON -DLLVM_ENABLE_RTTI=ON"
To use them, you still need to pass the source directory, so:
$ cmake_llvm_dbg_eh ../llvm
should do the trick.