available on YouTube
Redhat 7On RedHat 7, Clang is not included in the official repositories, however older versions (v3.4) are included in the epel repository.
If you are unable to use the epel repository, or want a newer version of clang, the below script can be used to get and install v3.9.1 of llvm, clang, clang tools and the include what you use tool.
mkdir clang_llvm_391_build cd clang_llvm_391_build svn co http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_391/final llvm cd llvm/tools svn co http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_391/final clang cd ../.. cd llvm/tools/clang/tools svn co http://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_391/final extra cd ../../../.. cd llvm/projects svn co http://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_391/final compiler-rt cd ../.. #cd llvm/projects #svn co http://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_391/final libcxx #cd ../.. cd llvm/tools/clang/tools git clone https://github.com/include-what-you-use/include-what-you-use.git cd include-what-you-use git checkout clang_3.9 cd .. echo "" >> CMakeLists.txt echo "add_subdirectory(include-what-you-use)" >> CMakeLists.txt cd ../../../.. mkdir llvm.build cd llvm.build cmake -G Ninja -DCMAKE_INSTALL_PREFIX=/opt/software/clang -DCMAKE_BUILD_TYPE=Release ../llvm ninja mkdir -p /opt/software/clang cmake -DCMAKE_INSTALL_PREFIX=/opt/software/clang -P cmake_install.cmake
As you can see this installs the software to /opt/software/clang If you want to install to a different location change the CMAKE_INSTALL_PREFIX locations in the line 26 and 29.
The script doesn't compile the version of the C++ standard library (libcxx) available with Clang as I had compiler errors when building it with the default version of gcc (v4.8.5) available with RHEL 7.3
Redhat 6For RHEL 6, there is also a epel repository with v3.4 available. However, if you want a later version of Clang you have some hoops to run through.
This is because Clang requires a C++11 compiler and Clang v3.9.1, mentioned above, requires at least v4.8 of gcc. The version of gcc available on RHEL 6 is too old and you have to manually build a later version before you can build Clang. You can find instructions on doing so from this blog post.
CompilingTo build your software using Clang with CMake you should override the CMAKE_C_COMPILER and CMAKE_CXX_COMPILER variables. Using the install from my script above this would be done using
$ cmake -DCMAKE_C_COMPILER=/opt/software/clang/bin/clang -DCMAKE_CXX_COMPILER=/opt/software/clang/bin/clang++ .. $ make
You can see more details in my cmake-examples GitHub repository.
Similar methods of overriding the C and C++ compiler environments may work with other build tools. e.g. using CC and CXX with Makefiles.
Using Clang Static AnalyzerUsing the Clang Static Analyzer is easy too as it includes a tool scan-build which can be used to scan your source code at the same time as it builds it
$ /opt/software/clang/bin/scan-build cmake .. $ /opt/software/clang/bin/scan-build make
On RedHat the above will use gcc to build your software while scanning it with the Clang Static Analyzer.
To get extra coverage for your code I also recommend to use clang to compile it. This can be done at the same time as your static analysis by using the --use-cc and --use-c++ flags for scan-build
$ /opt/software/clang/bin/scan-build --use-cc=/opt/software/clang/bin//clang --use-c++=/opt/software/clang/bin//clang++ cmake .. $ /opt/software/clang/bin/scan-build --use-cc=/opt/software/clang/bin//clang --use-c++=/opt/software/clang/bin//clang++ make
Advantages of having Clang AvailableThe main reason I have for using Clang on RedHat is to get access to it's tooling and static analyzer.
However as a side effect of this it also makes the compiler available for use. Using this second compiler can give you more chance of finding errors. For example, when compiling with Clang I had an error:
file included from /path/to/myclass.cpp:22: /path/to/logger.h:1:9: warning: '_LIBMYLIB_LOGGER_H_' is used as a header guard here, followed by #define of a different macro [-Wheader-guard] #ifndef _LIBMYLIB_LOGGER_H_ ^~~~~~~~~~~~~~~~~ /path/to/logger.h:2:9: note: '_LINMYLIB_LOGGER_H_' is defined here; did you mean '_LIBMYLIB_LOGGER_H_'? #define _LINMYLIB_LOGGER_H_ ^~~~~~~~~~~~~~~~~ _LIBMYLIB_LOGGER_H_ 6 warnings generated.
This did not cause any errors or warnings on my version of GCC and while it didn't cause any issues (because I only included that header once), it could potentially have lead to a later error.