CMakeでは、コンパイラがClangかどうかをどのようにテストできますか?


151

一連のクロスプラットフォームCMakeビルドスクリプトがあり、Visual C ++およびGCCでのビルドをサポートしています。

Clangを試していますが、CMakeスクリプトでコンパイラがClangであるかどうかをテストする方法がわかりません。

コンパイラがClangかどうかを確認するには何をテストすればよいですか?現在Visual C ++とGCC を使用MSVCCMAKE_COMPILER_IS_GNU<LANG>てテストしています。


CMAKE_C_COMPILERおよびCMAKE_CXX_COMPILERをclangまたはclang ++へのパスに設定することにより、コンパイラを設定できます。clangの+1。
Zaffy

なぜあなたは気にする必要がありますか?Clangは、受け入れられるコンパイラオプションの点で、GCCに非常に似ています...
Basile Starynkevitch

2
@BasileStarynkevitch MSVCをサポートしていたため、Clangを検出する必要があったため、GCCのようなオプションをオンにするか、MSVCのようなオプションをオンにするかを知っていました。覚えるには長すぎますが、Clangでサポートされていないオプションを使用していた可能性もあります。
leedm777 2015年

1
@BasileStarynkevitch -クランは両方のふり__GNUC__して_MSC_VER、それがいずれかのコンパイラと同じプログラムを消費することはできません。LLVM ClangおよびApple Clangを検出することは、コードが期待どおりにコンパイルおよび実行されるようにするために重要です。ClangのBSに対処するのにうんざりしているので、Windowsでコンパイルを中断するだけです。ユーザーがLLVMに文句を言うことを許可するポリシーを採用して、Clang開発者が動作を変更するようにしました。他のコンパイラを装うのをやめるようにClangに指示する方法
jww 2016

回答:


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ます。アップルが提供するClangと通常のClangの両方をテストするには、次のif条件を使用します。

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

AppleClangポリシーの説明もご覧ください。

CMake 3.15は、clang-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/...
ニック・ハッチンソン

9
CMAKE_CXX_COMPILER_ID変数はコマンドの後でのみ使用できることに注意してくださいproject(Foo CXX)
厄介な

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 2017年

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 2012

1
これは私にとってはうまくいきません${CMAKE_CXX_COMPILER} == /Library/Developer/CommandLineTools/usr/bin/c++。受け入れられた答えは機能します。
フレッドシェーン2017年

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

これは、サクラの回答から変更された、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.