How to build LLVM from source
UPDATE, November 2019: The old llvm-mirror on GitHub is dead; long live the monorepo! Updated instructions on how to build LLVM from source are available in this later blog post.
There are two plausible sources of the LLVM codebase:
https://llvm.org/git/$FOO.git
and https://github.com/llvm-mirror/$FOO.git
.
The GitHub mirror seems to be faster than llvm.org
; plus, we’re
going to want to fork it on GitHub to track our changes.
(However, to submit patches to LLVM projects, you must use
the official Phabricator;
don’t submit GitHub pull requests against the llvm-mirror
mirrors!)
Step 1: Fork!
Go to your GitHub account and fork each of the following repos:
Step 2: Get the code!
Locally clone the repos to the right places.
cd $ROOT ; git clone git@github.com:llvm-mirror/llvm
cd $ROOT/llvm/tools ; git clone git@github.com:llvm-mirror/clang
Here are the right places for some other useful (but unnecessary) repos.
cd $ROOT/llvm/projects ; git clone git@github.com:llvm-mirror/libcxx
cd $ROOT/llvm/projects ; git clone git@github.com:llvm-mirror/compiler-rt
cd $ROOT/llvm/tools ; git clone git@github.com:llvm-mirror/lldb
cd $ROOT/llvm/tools/clang/tools ; git clone git@github.com:llvm-mirror/clang-tools-extra extra
(Notice that clang-tools-extra
’s repo name doesn’t match its expected directory name.
We snuck an extra
parameter onto the end of that git clone
line.)
This is a good time to set up the .git/config
for each of the repos
you just cloned (for example, $ROOT/llvm/.git/config
).
I set it up this way:
[remote "origin"]
url = git@github.com:Quuxplusone/llvm.git
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "upstream"]
url = git@github.com:llvm-mirror/llvm.git
fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "master"]
remote = upstream
merge = refs/heads/master
This gives me two remotes: one named upstream
whence I can pull,
and one named origin
whither I can push. My local master
and origin/master
will both track upstream/master
. Anything I do in my local repo, I will do in a
feature branch; my feature branches will track origin
.
Step 3: Build!
mkdir -p $ROOT/llvm/build
cd $ROOT/llvm/build
cmake -G 'Unix Makefiles' \
-DCMAKE_BUILD_TYPE=RelWithDebInfo ..
make -j5 clang
make -j5 check-clang
If you omit -DCMAKE_BUILD_TYPE=RelWithDebInfo
, this first part will still work, but you’ll produce
a “debug-build” version of clang
that is super slow, and then the “bootstrap” step below will
take days instead of minutes. So watch out for that.
make -j5 clang
takes about 80 minutes on my laptop.
make -j5 check-clang
takes another 37 minutes
(27 minutes to build clang-tidy
for some reason, and then another 10 minutes to run the actual tests).
Making clang
will build both clang
and clang++
.
Making cxx
will build libc++
(and also libc++abi
, which is included in the libcxx
repo).
Making check-$FOO
will build and run the test suite for $FOO
:
make -j5 check-clang check-cxx
If something goes wrong, you can usually recover via
rm $ROOT/llvm/build/CMakeCache.txt
and, absolute worst case, you can blow away $ROOT/llvm/build
and start over.
Step 4: Run specific tests.
Running a specific test or directory-of-tests for any product is easy:
cd $ROOT/llvm/build
./bin/llvm-lit -sv ../test/Analysis
./bin/llvm-lit -sv ../tools/clang/test/ARCMT
./bin/llvm-lit -sv ../projects/libcxx/test/std/re
However, it looks like before you can successfully run one of these lines,
you must have run the corresponding one of make check-{llvm,clang,cxx}
at least once, to initialize the right stuff in the build
directory.
(Thanks to Brian Cain for documenting this recipe.)
But watch out! Both make check-cxx
and llvm-lit
will by default use your system compiler
to run the libc++ tests! This is not what you want! Tell llvm-lit
to use your newly built Clang
by passing the cxx_under_test
parameter, like this:
./bin/llvm-lit -sv --param cxx_under_test=`pwd`/bin/clang ../projects/libcxx/test/
Step 5: Bootstrap!
This is where it might get non-portable for people who aren’t on OS X, I’m not sure. Here we will not be installing Clang over top of the system compiler (super dangerous!); but we will instruct CMake to build Clang using the previously built Clang.
There is apparently an official way to bootstrap Clang:
cd $ROOT/llvm/build
make -j5 clang
cmake -G 'Unix Makefiles' \
-DCLANG_ENABLE_BOOTSTRAP=On \
-DCMAKE_BUILD_TYPE=RelWithDebInfo ..
make -j5 stage2
However, when I get to make -j5 stage2
, it fails with a CMake error:
Host Clang must be able to find libstdc++4.8 or newer!
So when I bootstrap Clang, I use this crude approach inspired by the CMake FAQ:
cd $ROOT/llvm/build
rm CMakeCache.txt
CXX="$ROOT/llvm/build/bin/clang++" \
CXXFLAGS="-cxx-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 -isystem /usr/include" \
cmake -G 'Unix Makefiles' \
-DCMAKE_BUILD_TYPE=RelWithDebInfo ..
cp bin/clang-8 clang-ok
find ../include/ -name '*.h' | xargs touch
make -j5 clang VERBOSE=1
(This takes the same 80 minutes as the original make -j5 clang
did.)
(If you have checked out libcxx
, you can try substituting
$ROOT/llvm/projects/libcxx/include
for /Library/Developer/CommandLineTools/usr/include/c++/v1
.)
This crude approach will of course overwrite your “good” build/bin/clang++
(the one that successfully compiled Clang) with a new version (which for all
you know might not compile Clang), so that’s why I did cp bin/clang-8 clang-ok
before running make -j5 clang
the second time.
(Make sure you cp
the actual executable and not just a symlink to it!)