web-dev-qa-db-fra.com

Comment détecter LLVM et sa version via les directives #define?

La question est assez claire, je pense. J'essaie d'écrire un en-tête de détection de compilateur pour pouvoir inclure dans l'application des informations sur quel compilateur a été utilisé et quelle version.

Cela fait partie du code que j'utilise:

/* GNU C Compiler Detection */
#Elif defined __GNUC__
    #ifdef __MINGW32__
        #define COMPILER "MinGW GCC %d.%d.%d"
    #else
        #define COMPILER "GCC %d.%d.%d"
    #endif
    #define COMP_VERSION __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__
#endif

Qui pourrait être utilisé comme ceci:

printf("  Compiled using " COMPILER "\n", COMP_VERSION);

Existe-t-il un moyen de détecter LLVM et sa version? Et CLANG?

62
Carla Álvarez

Le __llvm__ et __clang__ les macros sont le moyen officiel de rechercher un compilateur LLVM (llvm-gcc ou clang) ou clang, respectivement.

__has_feature et __has_builtin sont la méthode recommandée pour vérifier les fonctionnalités optionnelles du compilateur lors de l'utilisation de clang, elles sont documentées ici .

Notez que vous pouvez trouver une liste des macros du compilateur intégré pour gcc, llvm-gcc et clang en utilisant:

echo | clang -dM -E -

Cela prétraite une chaîne vide et crache toutes les macros définies par le compilateur.

73
Daniel Dunbar

Je ne trouve pas de réponse ici, seulement des liens vers des réponses, donc pour être complet, voici la réponse:

__clang__             // set to 1 if compiler is clang
__clang_major__       // integer: major marketing version number of clang
__clang_minor__       // integer: minor marketing version number of clang
__clang_patchlevel__  // integer: marketing patch level of clang
__clang_version__     // string: full version number

Je reçois actuellement:

__clang__=1
__clang_major__=3
__clang_minor__=2
__clang_patchlevel__=0
__clang_version__="3.2 (tags/RELEASE_32/final)"
39
Walter

Pour clang, vous ne devez pas tester son numéro de version, vous devez vérifier les fonctionnalités que vous souhaitez avec vérification des fonctionnalités des macros .

21
Chris Lattner

Extrait de InitPreprocessor.cpp :

  // Compiler version introspection macros.
  DefineBuiltinMacro(Buf, "__llvm__=1");   // LLVM Backend
  DefineBuiltinMacro(Buf, "__clang__=1");  // Clang Frontend

  // Currently claim to be compatible with GCC 4.2.1-5621.
  DefineBuiltinMacro(Buf, "__GNUC_MINOR__=2");
  DefineBuiltinMacro(Buf, "__GNUC_PATCHLEVEL__=1");
  DefineBuiltinMacro(Buf, "__GNUC__=4");
  DefineBuiltinMacro(Buf, "__GXX_ABI_VERSION=1002");
  DefineBuiltinMacro(Buf, "__VERSION__=\"4.2.1 Compatible Clang Compiler\"");

Je n'ai trouvé aucun moyen d'obtenir la version de llvm et de se faire entendre, cependant ..

10
Christoph

Jetez un œil à la page Macros de compilateur prédéfinies , sélectionnez Compilateurs-> Clang . Il existe des informations sur de nombreuses autres macros pour les normes, les compilateurs, les bibliothèques, les systèmes d'exploitation, les architectures et plus encore.

6
Matt Joiner

Je suis d'accord que le meilleur choix est d'utiliser a des macroses de fonction , pas des macroses de version. Exemple avec boost :

#include <boost/config.hpp>

#if defined(BOOST_NO_CXX11_NOEXCEPT)
 #if defined(BOOST_MSVC)
  #define MY_NOEXCEPT throw()
 #else
  #define MY_NOEXCEPT
 #endif
#else
 #define MY_NOEXCEPT noexcept
#endif

void my_noexcept_function() MY_NOEXCEPT; // it's example, use BOOST_NOEXCEPT (:

Mais de toute façon, si vous avez besoin de la version du compilateur , vous pouvez utiliser boost.predef :

#include <iostream>
#include <boost/predef.h>

int main() {
#if (BOOST_COMP_CLANG)
  std::cout << BOOST_COMP_CLANG_NAME << "-" << BOOST_COMP_CLANG << std::endl;
#else
  std::cout << "Unknown compiler" << std::endl;
#endif
  return 0;
}

Exemples de sortie:

Clang-30400000
Clang-50000000
2
user2288008

Notez que si vous utilisez llvm pour pirater le bytecode, et donc #includeing llvm include files, vous pouvez vérifier les macros dans llvm/Config/llvm-config.h. Et concrètement:

/* Major version of the LLVM API */
#define LLVM_VERSION_MAJOR 3

/* Minor version of the LLVM API */
#define LLVM_VERSION_MINOR 8

/* Patch version of the LLVM API */
#define LLVM_VERSION_PATCH 0

/* LLVM version string */
#define LLVM_VERSION_STRING "3.8.0"
1
Hugh Perkins