I have a number of projects built using CMake and I'd like to be able to easily switch between using GCC or Clang/LLVM to compile them. I believe (please correct me if I'm mistaken!) that to use Clang I need to set the following:
SET (CMAKE_C_COMPILER "/usr/bin/clang")
SET (CMAKE_C_FLAGS "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
SET (CMAKE_CXX_FLAGS "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_AR "/usr/bin/llvm-ar")
SET (CMAKE_LINKER "/usr/bin/llvm-ld")
SET (CMAKE_NM "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")
Is there an easy way of switching between these and the default GCC variables, preferably as a system-wide change rather than project specific (i.e. not just adding them into a project's CMakeLists.txt)?
Also, is it necessary to use the llvm-*
programs rather than the system defaults when compiling using clang instead of gcc? What's the difference?
You can use the syntax:
$ENV{environment-variable}
in yourCMakeLists.txt
to access environment variables. You could create scripts which initialize a set of environment variables appropriately and just have references to those variables in yourCMakeLists.txt
files.According to the help of
cmake
:You make be able to create files like
gcc_compiler.txt
andclang_compiler.txt
to includes all relative configuration in CMake syntax.Clang Example (clang_compiler.txt):
Then run it as
GCC:
Clang:
You can use the toolchain file mechanism of cmake for this purpose, see e.g. here. You write a toolchain file for each compiler containing the corresponding definitions. At config time, you run e.g
and all the compiler information will be set during the project() call from the toolchain file. Though in the documentation is mentionend only in the context of cross-compiling, it works as well for different compilers on the same system.
If the default compiler chose by
cmake
isgcc
and you have installedclang
, you can use the easy way to compile your project withclang
:System wide C++ change on Ubuntu:
Will print something like this:
Then just select clang++.
CMake honors the environment variables
CC
andCXX
upon detecting the C and C++ compiler to use:The compiler specific flags can be overridden by putting them into a system wide CMake file and pointing the CMAKE_USER_MAKE_RULES_OVERRIDE variable to it. Create a file
~/ClangOverrides.txt
with the following contents:The suffix _INIT will make CMake initialize the corresponding
*_FLAGS
variable with the given value. Then invoke cmake in the following way:Finally to force the use of the LLVM binutils, set the internal variable
_CMAKE_TOOLCHAIN_PREFIX
. This variable is honored by theCMakeFindBinUtils
module:Putting this all together you can write a shell wrapper which sets up the environment variables
CC
andCXX
and then invokes cmake with the mentioned variable overrides.