[cmake] CMake를 사용하여 GCC와 Clang / LLVM 간 전환

CMake를 사용하여 빌드 된 많은 프로젝트가 있으며 GCC 또는 Clang / LLVM을 사용하여 쉽게 컴파일하여 컴파일 할 수 있기를 바랍니다. Clang을 사용하려면 다음을 설정해야한다고 생각합니다 (잘못하면 수정하십시오!).

    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")

이러한 변수와 기본 GCC 변수 사이를 쉽게 전환 할 수있는 방법이 있습니까 (예 : 프로젝트의 특정 변수가 아니라 프로젝트 전체의 CMakeLists.txt에 추가하는 것이 아니라) 시스템 전체의 변경 사항이 있습니까?

또한 llvm-*gcc 대신 clang을 사용하여 컴파일 할 때 시스템 기본값 대신 프로그램 을 사용해야 합니까? 차이점이 뭐야?



답변

CMake는 다음 CC과 같이 사용할 환경 변수 와 CXXC 및 C ++ 컴파일러 감지시 다음을 수행합니다.

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

컴파일러 특정 플래그는 시스템 전체 CMake 파일에 넣고 CMAKE_USER_MAKE_RULES_OVERRIDE변수를 지정하여 재정의 할 수 있습니다 . ~/ClangOverrides.txt다음 내용 으로 파일 을 작성하십시오 .

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")

접미사 _INIT는 CMake *_FLAGS가 주어진 값으로 해당 변수를 초기화하게합니다 . 그런 cmake다음 다음과 같은 방법으로 호출 하십시오.

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

마지막으로 LLVM binutils를 강제로 사용하려면 내부 변수를 설정하십시오 _CMAKE_TOOLCHAIN_PREFIX. 이 변수는 CMakeFindBinUtils모듈에 의해 존중됩니다 :

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

모두 함께이 퍼팅 당신은 환경 변수를 설정하는 쉘 래퍼 쓸 수 있습니다 CCCXX다음과 원용 cmake언급 된 변수 대체에 있습니다.


답변

우분투의 시스템 전체 C ++ 변경 :

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

다음과 같이 인쇄합니다 :

  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

그런 다음 clang ++을 선택하십시오.


답변

옵션 명령을 사용할 수 있습니다.

option(USE_CLANG "build application with clang" OFF) # OFF is the default

그런 다음 clang-compiler 설정을 if () s로 래핑하십시오.

if(USE_CLANG)
    SET (...)
    ....
endif(USE_CLANG)

이런 식으로 GUI 구성 도구에서 cmake 옵션으로 표시됩니다.

시스템 전체에서 환경 변수를 기본값으로 사용하거나 Ferruccio의 답변을 유지할 수 있습니다.


답변

Ubuntu의 시스템 전체 C 변경 :

sudo update-alternatives --config cc

우분투의 시스템 전체 C ++ 변경 :

sudo update-alternatives --config c++

위의 각 항목에 대해 선택 번호 (1)와 Enter를 눌러 Clang을 선택하십시오.

  Selection    Path            Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc     20        auto mode
  1            /usr/bin/clang   10        manual mode
  2            /usr/bin/gcc     20        manual mode
Press enter to keep the current choice[*], or type selection number:


답변

이를 위해 cmake의 툴체인 파일 메커니즘을 사용할 수 있습니다 (예 : here 참조) . 해당 정의가 포함 된 각 컴파일러에 대한 툴체인 파일을 작성합니다. 설정시, 당신은 예를 들어 실행

 cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/clang-toolchain.cmake ..

모든 컴파일러 정보는 toolchain 파일에서 project () 호출 중에 설정됩니다. 문서에는 크로스 컴파일 환경에서만 언급되었지만 동일한 시스템의 다른 컴파일러에서도 잘 작동합니다.


답변

다양한 llvm-ar etc 프로그램을 사용할 필요는 없습니다.

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")

이들은 llvm 내부 형식으로 작동하도록 만들어 졌으므로 응용 프로그램을 빌드하는 데 유용하지 않습니다.

참고로 -O4는 프로그램에서 LTO를 호출하여 원하지 않는 경우 (컴파일 시간이 크게 증가 함) clang은 기본적으로 c99 모드로 설정되므로 플래그도 필요하지 않습니다.


답변

가 선택한 기본 컴파일러 경우 cmake입니다 gcc당신이 설치 한 clang, 당신은 당신의 프로젝트를 컴파일하는 쉬운 방법을 사용할 수 있습니다 clang:

$ mkdir build && cd build
$ CXX=clang++ CC=clang cmake ..
$ make -j2