CMake'te, derleyicinin Clang olup olmadığını nasıl test edebilirim?


151

Bir dizi çapraz platform CMake derleme betiğimiz var ve Visual C ++ ve GCC ile oluşturmayı destekliyoruz .

Clang'ı deniyoruz , ancak CMake betiğimizle derleyicinin Clang olup olmadığını nasıl test edeceğimizi anlayamıyorum.

Derleyicinin Clang olup olmadığını görmek için ne test etmeliyim? Şu anda sırasıyla Visual C ++ ve GCC'yi test etmek için MSVCve kullanıyoruz CMAKE_COMPILER_IS_GNU<LANG>.


Derleyiciyi CMAKE_C_COMPILER ve CMAKE_CXX_COMPILER değerini clang veya clang ++ yoluna ayarlayarak ayarlayabilirsiniz. Clang için +1.
Zaffy

Neden umursasın ki? Clang, kabul edilen derleyici seçenekleri açısından çok GCC gibi ...
Basile Starynkevitch

2
@BasileStarynkevitch MSVC'yi desteklediğimizden beri Clang'ı tespit etmemiz gerekiyordu, bu yüzden GCC benzeri seçenekleri mi yoksa MSVC benzeri seçenekleri mi açacağımızı biliyorduk. Hatırlamam çok uzun sürdü, ancak Clang tarafından desteklenmeyen seçenekleri de kullanmak kesinlikle mümkündür.
leedm777

1
@BasileStarynkevitch - Clang yerindeymiş gibi hem olmak __GNUC__ve _MSC_VERfakat her iki derleyici aynı programlar tüketmek olamaz. LLVM Clang ve Apple Clang'ı algılamak, kodun beklendiği gibi derlenmesini ve yürütülmesini sağlamak için çok önemlidir. Clang BS ile uğraşmaktan çok yoruldum, sadece Windows'daki derlemeyi bozuyoruz . Clang geliştiricilerinin davranışlarını değiştirmesi için kullanıcıların LLVM'ye şikayet etmesine izin verme politikasını kabul ettik. Ayrıca bkz. Clang'a diğer derleyicilermiş gibi davranmayı bırakmasını nasıl söyleyebilirim?
jww

Yanıtlar:


242

Güvenilir bir kontrol CMAKE_<LANG>_COMPILER_IDdeğişkenlerin kullanılmasıdır. Örneğin, C ++ derleyicisini kontrol etmek için:

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

Bunlar , ccache gibi bir derleyici sarıcı kullanıldığında da düzgün çalışır .

CMake 3.0.0'dan itibaren CMAKE_<LANG>_COMPILER_IDApple tarafından sağlanan Clang değeri artık AppleClang. Hem Apple tarafından sağlanan Clang'ı hem de normal Clang'ı test etmek için aşağıdaki if koşulunu kullanın:

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

Ayrıca AppleClang ilke açıklamasına bakın .

CMake 3.15 , hem clang-cl hem de normal clang ön ucu için destek ekledi . Ön uç değişkenini, değişkeni inceleyerek belirleyebilirsiniz 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 dokümantasyon "Bu derleyici belirlenmesinde kullanılan ve değişime tabidir" belirtiyor. Aksi takdirde, mükemmel olurdu :-(
leedm777

17
CMake 2.8.10 itibariyle bu değişken (nihayet!) Belgelenmiştir. Bakınız: cmake.org/cmake/help/v2.8.10/…
Nick Hutchinson

9
CMAKE_CXX_COMPILER_IDDeğişkenin yalnızca komuttan sonra kullanılabileceğini unutmayın project(Foo CXX).
16'da

5
Hem gcc hem de clang'ın kabul ettiği bayraklar için kullanıyorumif (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") ... endif()
Fred Schoen

4
Neden AppleClangözel olarak tespit edemediğiniz konusunda kafanız karıştıysa, @sakra bunun cmake 3.0.0serbest bırakıldığınıAppleClang gösterir . Ancak, cmake --versionraporların eşit veya daha yüksek olması yeterli olmadığından cmake_minimum_required(VERSION 3.0.0), 3.0.0standartların kullanılabilmesi için yapmanız gerekir !
svenevs

2

OGRE 3D motor kaynak kodu aşağıdaki denetimi kullanır :

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

3
Bu yakın, ancak ccache (yani export CXX="ccache clang++") kullandığınızda çalışmıyor
leedm777

4
Yeterince yakın, sana vereceğim. Ben if ("${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang")ccache kasasını idare ederdim .
leedm777

1
Bu benim için işe yaramıyor ${CMAKE_CXX_COMPILER} == /Library/Developer/CommandLineTools/usr/bin/c++. Kabul edilen cevap işe yarıyor.
Fred Schoen

1

Herhangi bir yanlış yazım probleminden kaçınmak için, Case-duyarsız karşılaştırmayı kullanıyorum, örneğin:

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

Büyük / MATCHESküçük harfe duyarsız hale getirmek için , burada her şeyi başarılı olmadan denedim (CMake'de desteklenmiyor gibi görünüyor).


Gerçekten de, bugün olduğu gibi, büyük / küçük harfe duyarlı olmayan eşleşme mümkün değildir cmake.org/pipermail/cmake/2017-May/065432.html
fferri

-2

Bu, sakra'nın cevabından değiştirilen cmake yeni başlayanlar için biraz daha ayrıntılı bir cevaptır, sadece aşağıdaki satırları ekleyin 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()

Ardından cmake .CMakeLists.txt dosyasının bulunduğu klasörde çalıştırın . Sonra cevabınızla birlikte bir sürü çıktı göreceksiniz.

...
-- Detecting CXX compile features
-- Detecting CXX compile features - done
GNU
-- Configuring done
-- Generating done
...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.