Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switching between GCC and Clang/LLVM using CMake

Tags:

llvm

cmake

clang

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?

like image 294
Rezzie Avatar asked Aug 11 '11 18:08

Rezzie


People also ask

How do I use GCC instead of clang?

If you want to use clang instead of GCC, you can add -DCMAKE_C_COMPILER=/path/to/clang -DCMAKE_CXX_COMPILER=/path/to/clang++ . You can also use ccmake , which provides a curses interface to configure CMake variables in an interactive manner.

Are GCC and clang interchangeable?

TL;DR: Clang is highly compatible to GCC - just give it a go. In most cases, Clang could be used as a GCC drop in replacement ( clang and clang++ are "GCC compatible drivers").

Is LLVM better than GCC?

While LLVM and GCC both support a wide variety languages and libraries, they are licensed and developed differently. LLVM libraries are licensed more liberally and GCC has more restrictions for its reuse. When it comes to performance differences, GCC has been considered superior in the past.

Is LLVM compatible with GCC?

Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.)


2 Answers

CMake honors the environment variables CC and CXX upon detecting the C and C++ compiler to use:

$ export CC=/usr/bin/clang $ export CXX=/usr/bin/clang++ $ cmake .. -- The C compiler identification is Clang -- The CXX compiler identification is Clang 

The compiler specific flags can be overridden by putting them into a make override file and pointing the CMAKE_USER_MAKE_RULES_OVERRIDE variable to it. Create a file ~/ClangOverrides.txt with the following contents:

SET (CMAKE_C_FLAGS_INIT                "-Wall -std=c99") SET (CMAKE_C_FLAGS_DEBUG_INIT          "-g") SET (CMAKE_C_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG") SET (CMAKE_C_FLAGS_RELEASE_INIT        "-O3 -DNDEBUG") SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")  SET (CMAKE_CXX_FLAGS_INIT                "-Wall") SET (CMAKE_CXX_FLAGS_DEBUG_INIT          "-g") SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG") SET (CMAKE_CXX_FLAGS_RELEASE_INIT        "-O3 -DNDEBUG") SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") 

The suffix _INIT will make CMake initialize the corresponding *_FLAGS variable with the given value. Then invoke cmake in the following way:

$ cmake -DCMAKE_USER_MAKE_RULES_OVERRIDE=~/ClangOverrides.txt .. 

Finally to force the use of the LLVM binutils, set the internal variable _CMAKE_TOOLCHAIN_PREFIX. This variable is honored by the CMakeFindBinUtils module:

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- .. 

Putting this all together you can write a shell wrapper which sets up the environment variables CC and CXX and then invokes cmake with the mentioned variable overrides.

Also see this CMake FAQ on make override files.

like image 59
sakra Avatar answered Sep 29 '22 11:09

sakra


System wide C++ change on Ubuntu:

sudo apt-get install clang sudo update-alternatives --config c++ 

Will print something like this:

  Selection    Path              Priority   Status ------------------------------------------------------------ * 0            /usr/bin/g++       20        auto mode   1            /usr/bin/clang++   10        manual mode   2            /usr/bin/g++       20        manual mode 

Then just select clang++.

like image 22
Coder Avatar answered Sep 29 '22 12:09

Coder