If I write this down, maybe I won’t forget it next time!
There are two plausible sources of the LLVM codebase:
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
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 firstname.lastname@example.org:llvm-mirror/llvm cd $ROOT/llvm/tools ; git clone email@example.com:llvm-mirror/clang
Here are the right places for some other useful (but unnecessary) repos.
cd $ROOT/llvm/projects ; git clone firstname.lastname@example.org:llvm-mirror/libcxx cd $ROOT/llvm/projects ; git clone email@example.com:llvm-mirror/compiler-rt cd $ROOT/llvm/tools ; git clone firstname.lastname@example.org:llvm-mirror/lldb cd $ROOT/llvm/tools/clang/tools ; git clone email@example.com:llvm-mirror/clang-tools-extra extra
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,
I set it up this way:
[remote "origin"] url = firstname.lastname@example.org:Quuxplusone/llvm.git fetch = +refs/heads/*:refs/remotes/origin/* [remote "upstream"] url = email@example.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
will both track
upstream/master. Anything I do in my local repo, I will do in a
feature branch; my feature branches will track
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).
clang will build both
cxx will build
libc++ (and also
libc++abi, which is included in the
check-$FOO will build and run the test suite for
make -j5 check-clang check-cxx
If something goes wrong, you can usually recover via
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
at least once, to initialize the right stuff in the
(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
This crude approach will of course overwrite your “good”
(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
make -j5 clang the second time.
(Make sure you
cp the actual executable and not just a symlink to it!)