App and Web Development Information and Services

Using Repository Clang to Build libc++ and libc++abi on Linux

If you have installed Clang (and LLVM that it depends on) from your Linux repository, you may be interested in using it to build libc++ and libc++abi libraries that provide an alternative C++ library implementation that can be used instead of the ubiquitous libstdc++. If you build Clang from source or install it from binary packages available at llvm.org, these libraries will be available to you, but Clang and LLVM packages typically found in Linux repositories don't come with libc++, so it needs to be built separately. It is quite easy to build libc++/abi using GCC, but in case you believe that it makes a difference or are just curious and want to build the libc++/libc++abi libraries using Clang provided by your Linux repository, you may find this article helpful.

Building libc++/libc++abi using repo Clang on a Ubuntu-like system is still easy, but on RPM-based systems, like Fedora, CentOS, and RedHat, it is more challenging.

Building libc++ and libc++abi Using Clang on Ubuntu

We will be working on a Ubuntu 14.04 64-bit Amazon VM. We are starting without GCC, but with Clang 3.4 installed from the repository. We also need CMake, so we install it from the repository, which also sneaks in GCC as a dependency, so we remove it to avoid confusion.

Assuming LLVM, libc++, and libc++abi sources are in some_directory/llvm_src, and the source tree is structured as described here, we can create build directory some_directory/llvm_build, change to it and then: cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ../llvm_src make cxx (This also made cxxabi) cd projects/libcxx make install cd ../libcxxabi make install The libraries are now in /usr/local/lib. That's it!

Building libc++ and libc++abi Using Clang on RedHat 7.1

Here is how I did it on a 64-bit RedHat 7.1 VM in Amazon Web Services; this was much more involved.

Unfortunately, the default repository does not provide Clang, but this is easy to solve. Downloaded https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm and installed it. When you are reading this, there may be a newer version, you can always find it at https://fedoraproject.org/wiki/EPEL.

Did yum install clang and tried to build a trivial C++ program. However, it could not find iostream and bits/c++config.h headers, which was easy to solve by adding the -I/usr/include/c++/4.8.2 -I//usr/include/c++/4.8.2/x86_64-redhat-linux flags. The headers are provided by the libstdc++-devel package installed as a dependency of clang.

Then bits/wordsize.h could not be found. In fact, it wasn't anywhere on the system. Installed the gcc package. The wordsize.h header was then found in the glibc-headers package. Now libstdc++ could not be found, so had to create a symlink: libstdc++.so -> libstdc++.so.6 in /usr/lib64 in order for the simple test program to finally build successfully.

Building with the -v option reveals that clang++ depends on a number of object files and libraries from the gcc package. So, copied them to /usr/lib64 and created symlink libgcc_s.so -> libgcc_s.so.1 there. Then uninstalled gcc, and clang could still be used.

Unpacked the LLVM and libc++/libc++abi sources as described earlier and tried configuring with CMake, but there was another surprise: CMake from the repository is too old. So, had to download a newer one from cmake.org. To run its configure script, had to set the following environment variables: CC=clang CXX=clang++ CXXFLAGS="-I/usr/include/c++/4.8.2 -I//usr/include/c++/4.8.2/x86_64-redhat-linux" Then used CMake to configure LLVM etc. as follows: cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-I/usr/include/c++/4.8.2/x86_64-redhat-linux -I/usr/include/c++/4.8.2" -G "Unix Makefiles" ../llvm_src Followed the same procedure as described above for Ubuntu. Doing make cxx got: /root/llvm_src/projects/libcxxabi/src/cxa_aux_runtime.cpp:23:1: error: unknown type name 'LIBCXXABI_NORETURN' The problem is that LIBCXXABI_NORETURN is defined in llvm_src/projects/libcxxabi/include/cxxabi.h, but there also exists /usr/include/c++/4.8.2/cxxabi.h, which does not define that macro. This latter header is picked up by the compiler, hence the error. So, re-configuring using cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-I/root/llvm_src/projects/libcxx/include -I/root/llvm_src/projects/libcxxabi/include -I/usr/include/c++/4.8.2/x86_64-redhat-linux -I/usr/include/c++/4.8.2" -G "Unix Makefiles" ../llvm_src It is important to include both cxx and cxxabi headers. In the absence of gcc it's OK to omit the compiler on the cmake command line. This did the trick. After doing make install for both libraries, found them in /usr/local/lib along with the headers in /usr/local/include/c++/v1 and was able to use them.

It really looks like the RPM repository could be improved by adding some more dependencies to the clang package and moving some libraries and object files out of gcc to other packages, like it is done in Ubuntu's repository.