Di CMake, bagaimana saya bisa menguji apakah kompilernya Dentang?

151

Kami memiliki serangkaian skrip build CMake lintas-platform , dan kami mendukung pembangunan dengan Visual C ++ dan GCC .

Kami mencoba Clang , tetapi saya tidak tahu bagaimana cara menguji apakah kompilernya Clang dengan skrip CMake kami.

Apa yang harus saya uji untuk melihat apakah kompilernya Dentang atau tidak? Kami saat ini menggunakan MSVCdan CMAKE_COMPILER_IS_GNU<LANG>untuk menguji Visual C ++ dan GCC, masing-masing.

leedm777
sumber
Anda dapat mengatur kompiler dengan mengatur CMAKE_C_COMPILER dan CMAKE_CXX_COMPILER untuk path ke dentang atau dentang ++. +1 untuk dentang.
Zaffy
Kenapa kamu harus peduli? Dentang sangat seperti GCC, dalam hal opsi kompiler yang diterima ...
Basile Starynkevitch
2
@BasileStarynkevitch Karena kami mendukung MSVC, kami perlu mendeteksi Dentang sehingga kami tahu apakah akan mengaktifkan opsi seperti GCC, atau opsi seperti MSVC. Sudah terlalu lama bagi saya untuk mengingat, tetapi juga mungkin kita menggunakan opsi yang tidak didukung oleh Dentang juga.
leedm777
1
@ BasileStarynkevitch - Dentang berpura-pura menjadi keduanya __GNUC__dan _MSC_VER, tetapi tidak dapat mengkonsumsi program yang sama seperti kompiler. Mendeteksi LLVM Clang dan Apple Clang sangat penting untuk memastikan kompilasi dan eksekusi kode seperti yang diharapkan. Saya sangat lelah berurusan dengan BS Clang, kami hanya memecahkan kompilasi pada Windows . Kami telah mengadopsi kebijakan membiarkan pengguna mengeluh ke LLVM sehingga pengembang Dentang mengubah perilaku mereka. Lihat juga Bagaimana cara memberitahu Dentang untuk berhenti berpura-pura menjadi kompiler lain?
jww

Jawaban:

242

Pemeriksaan yang andal adalah menggunakan CMAKE_<LANG>_COMPILER_IDvariabel. Misalnya, untuk memeriksa kompiler 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()

Ini juga berfungsi dengan benar jika pembungkus kompiler seperti ccache digunakan.

Pada CMake 3.0.0 CMAKE_<LANG>_COMPILER_IDnilai untuk Dentang yang disediakan Apple sekarang AppleClang. Untuk menguji baik Dentang yang disediakan Apple maupun Dentang biasa, gunakan kondisi jika berikut:

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

Lihat juga deskripsi kebijakan AppleClang .

CMake 3.15 telah menambahkan dukungan untuk clang-cl dan front end clang biasa. Anda dapat menentukan varian ujung depan dengan memeriksa variabel 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()
sakra
sumber
The dokumentasi cmake menyatakan "ini digunakan dalam menentukan compiler dan tunduk pada perubahan". Kalau tidak, akan sempurna :-(
leedm777
17
Pada CMake 2.8.10, variabel ini (akhirnya!) Didokumentasikan. Lihat: cmake.org/cmake/help/v2.8.10/…
Nick Hutchinson
9
Perhatikan bahwa CMAKE_CXX_COMPILER_IDvariabel hanya tersedia setelah perintah project(Foo CXX).
waldyrious
5
Dan untuk bendera yang diterima oleh gcc dan dentang, saya menggunakanif (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") ... endif()
Fred Schoen
4
Jika Anda bingung mengapa Anda tidak dapat mendeteksi AppleClangsecara khusus, @sakra menunjukkan bahwa cmake 3.0.0dilepaskanAppleClang . Namun, hanya karena cmake --versionlaporan yang sama atau lebih tinggi tidak cukup - Anda harus cmake_minimum_required(VERSION 3.0.0)menggunakan 3.0.0standar!
svenev
2

Kode sumber mesin OGRE 3D menggunakan pemeriksaan berikut :

if (CMAKE_CXX_COMPILER MATCHES ".*clang")
    set(CMAKE_COMPILER_IS_CLANGXX 1)
endif ()
panah
sumber
3
Itu dekat, tetapi tidak berfungsi ketika Anda menggunakan ccache (mis. export CXX="ccache clang++")
leedm777
4
Cukup dekat, saya akan memberikannya kepada Anda. Saya dulu if ("${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang")menangani kasut ccache.
leedm777
1
Ini tidak berfungsi untuk saya sebagai ${CMAKE_CXX_COMPILER} == /Library/Developer/CommandLineTools/usr/bin/c++. Jawaban yang diterima bekerja.
Fred Schoen
1

Untuk menghindari masalah kesalahan ejaan, saya menggunakan perbandingan yang tidak sensitif terhadap kasus, seperti:

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

Untuk membuat regex dari MATCHEScase-insensitive, saya mencoba semuanya di sini tanpa hasil (sepertinya tidak didukung di CMake).

Antonio
sumber
memang, seperti hari ini, pencocokan case-sensitive tidak mungkin cmake.org/pipermail/cmake/2017-May/065432.html
fferri
-2

Ini adalah jawaban yang sedikit lebih rinci untuk pemula cmake, dimodifikasi dari jawaban sakra, tambahkan saja baris berikut ke 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()

Kemudian jalankan cmake .di folder di mana CMakeLists.txt berada. Kemudian Anda akan melihat banyak output beserta jawaban Anda.

...
-- Detecting CXX compile features
-- Detecting CXX compile features - done
GNU
-- Configuring done
-- Generating done
...
Searene
sumber