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
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!
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.