App and Web Development Information and Services

Bootstrapping Clang on Linux

This article is for those who are curious, like I was, about using Clang to build LLVM and Clang on Linux. In fact, if you want to build LLVM and Clang that don't depend on libstdc++, you will probably have to use Clang to do this. At least I wasn't able to use GCC for this. I could use GCC to build libc++ and libc++abi, as well as to build a LLVM+Clang linked with libstdc++, i.e. libstdc++-dependent, see this article. However, trying to build LLVM linked with libc++/libc++abi using GCC resulted in compilation errors having to do with move constructors, deleted functions and the like.

I am not sure if there is a practical value in building LLVM+Clang linked with libc++ as opposed to libstdc++. There may be, but in my testing, Clang linked with libstdc++ could be used to build software linked with libc++/libc++abi. But, in case there is a value in this or you are just as curious as I am, here we go!


Configuring the LLVM, Clang, libc++, and libc++abi Source

First you need to download and unpack the LLVM, Clang, libc++, and libc++abi source code. Then you can run cmake to configure it, there are two choices:
The Easy Way: Wrapper Script for clang++
Writing a wrapper script around clang++ is an easy way to build a C++ software package linked with libc++ instead of libstdc++. The problem with using clang++ directly is that we need to provide compiler and linker flags to make it use libc++ and its headers in place of libstdc++. With old-style configure scripts it is relatively easy by setting environment variables, but with CMake we would most likely need to edit the source configuration files as well as files generated in the build directory, and the way to edit them would differ from package to package. A wrapper script makes this easier, but there may be situations when it fails, even though I haven't seen any. You can use this script as a sample.

Assuming we are in the build directory and the script is named clang++w and is in the path, the LLVM/Clang/libc++(abi) source tree, located in ../llvm_src in this example, can be configured as follows: cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++w -G "Unix Makefiles" ../llvm_src/

The Hard Way: Edit CMake Configuration and Output Files
If we don't use a clang++ wrapper, we need to edit some CMake files. When building Clang 3.6.2, I had to edit the following file in the source tree: lib/Support/CMakeLists.txt to add the following line after everything else was set in the system_libs variable: set(system_libs ${system_libs} c++ c++abi c m gcc_s gcc) See below about the files that had to be edited in the build directory.

Building LLVM, Clang, libc++, and libc++abi

Now we need to issue make in the build directory. If cmake was used with a clang++ wrapper, everything should go smoothly. If we edited the CMake files, then we may need to edit some link.txt files in the build directory. If a build fails at some point, we can run make VERBOSE=1 to see what the command line was and edit the appropriate link.txt file to append -lc++ -lc++abi -lm -lc -lgcc_s -lgcc to the command line found in the file. In my case, with Clang 3.6.2, I had to edit the following files: utils/PerfectShuffle/CMakeFiles/llvm-PerfectShuffle.dir/link.txt utils/count/CMakeFiles/count.dir/link.txt tools/clang/tools/c-index-test/CMakeFiles/c-index-test.dir/link.txt tools/clang/tools/c-arcmt-test/CMakeFiles/c-arcmt-test.dir/link.txt Now do make install, and you have an LLVM, Clang, and libc++/libc++abi installation in /usr/local/lib, which is where it goes by default. Congratulations!
Problem Testing: Unresolved __cxa_thread_atexit
If you do make check-all after building your code, it may fail with the following error: /tmp/cxa_thread_atexit_test-aed951.o: In function `main': /root/llvm_src/projects/libcxxabi/test/cxa_thread_atexit_test.cpp:(.text+0x115): undefined reference to `__cxa_thread_atexit' Looking at the source being compiled, cxa_thread_atexit_test.cpp, the problem must be with the call to __cxxabiv1::__cxa_thread_atexit(). The function is defined in projects/libcxxabi/src/cxa_thread_atexit.cpp, which you can find in your build directory: namespace __cxxabiv1 { extern "C" { #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL int __cxa_thread_atexit(...) {...} However, looking at projects/libcxxabi/src/CMakeLists.txt the macro HAVE___CXA_THREAD_ATEXIT_IMPL is conditionally defined thus: if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL) endif() An in projects/libcxxabi/cmake/config-ix.cmake: check_library_exists(c __cxa_thread_atexit_impl "" LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) So, it's looking for __cxa_thread_atexit_impl() function in libc. The one on my machine doesn't have such a symbol, which explains the error. I guess the tests could have been written better.