208 votes

Dans CMake, comment puis-je tester si le compilateur est Clang ?

Nous avons un ensemble de scripts de construction CMake multiplateforme et nous soutenons la construction avec Visual C++ et CCG .

Nous essayons Clang mais je n'arrive pas à trouver comment tester si le compilateur est Clang ou non avec notre CMake script.

Que dois-je tester pour savoir si le compilateur est Clang ou non ? Nous utilisons actuellement MSVC et CMAKE_COMPILER_IS_GNU<LANG> pour tester Visual C++ et GCC, respectivement.

1 votes

Vous pouvez définir le compilateur en définissant CMAKE_C_COMPILER et CMAKE_CXX_COMPILER comme chemin vers clang ou clang++. +1 pour clang.

0 votes

Pourquoi devriez-vous vous en soucier ? Clang est très proche de GCC, en termes d'options de compilation acceptées ...

2 votes

@BasileStarynkevitch Depuis que nous supportons MSVC, nous avons besoin de détecter Clang pour savoir si nous devons activer les options de type GCC ou celles de type MSVC. Cela fait trop longtemps pour que je m'en souvienne, mais il est également possible que nous utilisions des options non supportées par Clang.

333voto

sakra Points 13373

Une vérification fiable consiste à utiliser le CMAKE_<LANG>_COMPILER_ID variables. Par exemple, pour vérifier le compilateur 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()

Ceux-ci fonctionnent également correctement si un wrapper de compilateur comme ccache est utilisé.

À partir de CMake 3.0.0, l'option CMAKE_<LANG>_COMPILER_ID pour le Clang fourni par Apple est maintenant AppleClang . Pour tester à la fois le Clang fourni par Apple et le Clang normal, utilisez la condition if suivante :

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

Voir également le Description de la politique d'AppleClang .

CMake 3.15 a ajouté un support pour les deux clang-club et le frontal clang normal. Vous pouvez déterminer la variante du front-end en inspectant la variable 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()

0 votes

Le site Documentation de cmake indique "Ceci est utilisé pour déterminer le compilateur et est sujet à changement". Sinon, ce serait parfait :-(

0 votes

Ce n'est probablement pas une bonne idée d'utiliser l'option CMAKE_CXX_COMPILER_ARG1 une solution basée sur la technologie, non plus. Celle-ci ne semble pas être documentée du tout.

18 votes

Depuis CMake 2.8.10, cette variable est (enfin !) documentée. Voir : cmake.org/cmake/help/v2.8.10/

7voto

MarkZar Points 1056

Voici une réponse un peu plus détaillée pour les novices de cmake, modifiée à partir de la réponse de sakra. La version minimale de 3.1 semble être importante car elle change la façon dont CMake traite la chaîne citée "MSVC" (selon la politique CMP0054).

cmake_minimum_required(VERSION 3.1)
project(MyProject CXX)

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

3voto

ChrisZZ Points 679

Si votre VERSION cmake_minimum_required est inférieure à 3.1, alors vous devez utiliser la variable citée pour déterminer le compilateur, si elle est associée à la variable STREQUAL la commande, c'est-à-dire

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

Ou, si vous n'aimez pas les citations, vous pouvez utiliser MATCHES commandement :

if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  MESSAGE("MSVC")
endif()

Et si vous spécifiez cmake_minimum_required VERSION >= 3.1, alors vous pouvez utiliser avec bonheur STREQUAL sans guillemets :

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

le problème de la version 3.1 de cmake, est documenté ici : https://cmake.org/cmake/help/latest/policy/CMP0054.html

2voto

Antonio Points 2246

Afin d'éviter tout problème d'orthographe, j'utilise la comparaison insensible à la casse, par exemple :

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

Pour rendre la regex de MATCHES insensible à la casse, j'ai tout essayé ici sans succès (cela ne semble pas être supporté par CMake).

2voto

arrowdodger Points 7611

Le code source du moteur OGRE 3D utilise les éléments suivants vérifier :

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

3 votes

C'est presque ça, mais ça ne fonctionne pas quand on utilise ccache (c'est-à-dire, export CXX="ccache clang++" )

4 votes

Assez proche, je vous le donne. J'ai utilisé if ("${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") pour gérer le cas du ccache.

1 votes

Cela ne fonctionne pas pour moi car ${CMAKE_CXX_COMPILER} == /Library/Developer/CommandLineTools/usr/bin/c++ . La réponse acceptée fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X