CMake에서 컴파일러가 Clang인지 어떻게 테스트합니까?


151

크로스 플랫폼 CMake 빌드 스크립트 세트가 있으며 Visual C ++GCC를 사용한 빌드 를 지원 합니다.

Clang을 시도하고 있지만 CMake 스크립트를 사용하여 컴파일러가 Clang인지 여부를 테스트하는 방법을 알 수 없습니다.

컴파일러가 Clang인지 아닌지 테스트하려면 어떻게해야합니까? 우리는 현재 사용하고있는 MSVCCMAKE_COMPILER_IS_GNU<LANG>각각 GCC 비주얼 C를 테스트 ++합니다.


CMAKE_C_COMPILER 및 CMAKE_CXX_COMPILER를 clang 또는 clang ++의 경로로 설정하여 컴파일러를 설정할 수 있습니다. 클랜 +1
Zaffy

왜 걱정해야합니까? Clang은 허용되는 컴파일러 옵션의 관점에서 매우 GCC입니다 ...
Basile Starynkevitch

2
@BasileStarynkevitch MSVC를 지원 했으므로 CCC를 감지하여 GCC와 같은 옵션 또는 MSVC와 같은 옵션을 켤지 여부를 알 필요가있었습니다. 기억하기에는 너무 오래되었지만 Clang이 지원하지 않는 옵션을 사용하고 있었을 가능성도 있습니다.
leedm777

1
@BasileStarynkevitch-Clang은 __GNUC__and 인 것처럼 가장 _MSC_VER하지만 어느 컴파일러와 동일한 프로그램을 사용할 수 없습니다. LLVM Clang 및 Apple Clang 감지는 코드가 예상대로 컴파일되고 실행되도록하는 데 중요합니다. Clang의 BS를 다루는 데 너무 피곤 하여 Windows에서 컴파일을 중단합니다 . Clang 개발자가 자신의 행동을 변경하도록 LLVM에 사용자가 불만을 제기하도록하는 정책을 채택했습니다. 또한 Clang에게 다른 컴파일러 인척을 중지하도록 지시하는 방법을
jww

답변:


242

신뢰할 수있는 점검은 CMAKE_<LANG>_COMPILER_ID변수 를 사용하는 것 입니다. 예를 들어 C ++ 컴파일러를 확인하려면 다음을 수행하십시오.

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  # using Clang
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  # using GCC
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  # using Intel C++
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  # using Visual Studio C++
endif()

ccache 와 같은 컴파일러 래퍼 를 사용 하는 경우에도 올바르게 작동합니다 .

CMake 3.0.0부터 CMAKE_<LANG>_COMPILER_IDApple 제공 Clang 의 값은 현재 AppleClang입니다. Apple 제공 Clang과 일반 Clang을 모두 테스트하려면 다음 조건을 사용하십시오.

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  # using regular Clang or AppleClang
endif()

AppleClang 정책 설명 도 참조하십시오 .

CMake 3.15clang-cl 과 일반 clang 프론트 엔드 를 모두 지원합니다 . 변수를 검사하여 프런트 엔드 변형을 결정할 수 있습니다 CMAKE_CXX_COMPILER_FRONTEND_VARIANT.

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
    # using clang with clang-cl front end
  elseif (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
    # using clang with regular front end
  endif()
endif()

cmake 문서는 "이것은 컴파일러를 결정하는 데 사용 및 변경 될 수 있습니다"상태. 그렇지 않으면 완벽 할 것입니다 :-(
leedm777

17
CMake 2.8.10부터이 변수는 (최종!) 문서화되어 있습니다. 참조 : cmake.org/cmake/help/v2.8.10/…
Nick Hutchinson 1

9
점을 유의 CMAKE_CXX_COMPILER_ID변수는 명령 이후에만 사용할 수 있습니다 project(Foo CXX).
waldyrious

5
gcc와 clang이 모두 허용하는 플래그에는 다음을 사용합니다.if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") ... endif()
Fred Schoen

4
AppleClang구체적으로 감지 할 수 없는지 혼란 스러우면 @sakra가 cmake 3.0.0릴리스 된AppleClang 것을 나타냅니다 . 그러나 cmake --version동일하거나 더 높은 보고서로는 충분하지 않기 때문에 표준을 사용 cmake_minimum_required(VERSION 3.0.0)하기 위해 3.0.0해야합니다!
svenevs

2

OGRE 3D 엔진 소스 코드는 다음 검사를 사용합니다 .

if (CMAKE_CXX_COMPILER MATCHES ".*clang")
    set(CMAKE_COMPILER_IS_CLANGXX 1)
endif ()

3
즉 가까운, 그러나 사용할 때 작동하지 않습니다 ccache (즉, export CXX="ccache clang++")
leedm777

4
충분히 가까이, 나는 당신에게 줄 것이다. 나는 if ("${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang")ccache 케이스를 처리하는 데 사용 했다.
leedm777

1
이것은 나를 위해 작동하지 않습니다 ${CMAKE_CXX_COMPILER} == /Library/Developer/CommandLineTools/usr/bin/c++. 허용 된 답변이 작동합니다.
Fred Schoen

1

맞춤법 오류를 피하기 위해 대소 문자를 구분하지 않는 비교를 사용합니다.

string( TOLOWER "${CMAKE_CXX_COMPILER_ID}" COMPILER_ID )
if (COMPILER_ID STREQUAL "clang")
    set(IS_CLANG_BUILD true)
else ()
    set(IS_CLANG_BUILD false)
endif ()

의 정규식 만들기 위해 MATCHES대소 문자 구분을, 나는 모든 노력 여기 (CMake에서 지원하지 않는 것) 성공하지 않고있다.


실제로 오늘날과 같이 대소 문자를 구분하지 않는 일치는 불가능합니다 cmake.org/pipermail/cmake/2017-May/065432.html
fferri

-2

이것은 sakra의 답변에서 수정 된 cmake 초보자를위한 약간 더 자세한 답변입니다. 다음 줄을 추가하십시오 CMakeLists.txt.

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  MESSAGE("Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  MESSAGE("GNU")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
  MESSAGE("Intel")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

그런 다음 cmake .CMakeLists.txt가있는 폴더에서 실행 하십시오. 그러면 답변과 함께 많은 결과가 나타납니다.

...
-- Detecting CXX compile features
-- Detecting CXX compile features - done
GNU
-- Configuring done
-- Generating done
...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.