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.
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
(This also made cxxabi)
The libraries are now in /usr/local/lib. That's it!
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.
yum install clang
and tried to build a trivial C++ program. However, it could not find
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.
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
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:
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.