2009-10-24 9 views
52

Die Frage ist ziemlich klar, denke ich. Ich versuche, einen Compiler-Erkennungsheader zu schreiben, um in der Anwendung Informationen darüber einfügen zu können, welcher Compiler verwendet wurde und welche Version.Wie erkennen LLVM und seine Version über # define-Direktiven?

Dieser Teil des Codes Ich verwende:

/* 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 

, die wie folgt verwendet werden:

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

Gibt es eine Möglichkeit LLVM und seine Version zu erkennen? Und CLANG?

+0

große Frage, kann ich keine doco an auf ihm finden alle –

+0

Sie müssen manchmal wissen, ob Clang Integrated Assembler verwendet wird, auch. Der Anwendungsfall ist ein moderner GCC, und der Compiler verwendet Clang als Assembler und nicht ein altes GAS, um AESNI, AVX, BMI usw. zu assemblieren. Sie verwenden den Integrated Assembler, weil AS und LD von Apple zu alt sind, um die von der Front produzierte Baugruppe zu verbrauchen -Ende. – jww

Antwort

64

Die Makros __llvm__ und __clang__ sind die offizielle Möglichkeit, nach einem LLVM-Compiler (llvm-gcc oder clang) bzw. nach clang zu suchen.

__has_feature und __has_builtin sind die empfohlene Möglichkeit zur Prüfung auf optionale Compiler-Funktionen bei der Verwendung von Clang, sie sind dokumentiert here.

Beachten Sie, dass Sie eine Liste der eingebauten Compiler-Makros für gcc finden, llvm-gcc und Klappern mit:

echo | clang -dM -E - 

Diese vorverarbeitet einen leeren String und spuckt alle Makros durch den Compiler definiert.

+22

Beachten Sie, dass '__GNUC__' auch für clang und llvm-gcc definiert ist. – pqnet

10

Snippet von 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\""); 

ich keine Möglichkeit gefunden, obwohl die Version von LLVM und Klirren selbst zu bekommen ..

+0

ich denke, man könnte jetzt auf die behauptete GCC versioniert für die Funktionen unterstützt, und clang/llvm für Erweiterungen –

21

Für Klirren, sollten Sie nicht die Versionsnummer prüfen , sollten Sie mit feature checking macros nach gewünschten Funktionen suchen.

+1

hm, das ist ein guter Punkt. Kannst du einen Link zu einem offiziellen Material zu diesem Thema geben? –

+1

@Matt Joiner, ich denke, Chris selbst ist ein Beamter. Zitiert von seiner Homepage http://nondot.org/sabre/: "Ich bin der Hauptautor der LLVM Compiler Infrastructure". – osgx

+2

@osgx: Trotzdem konnte er Links bereitstellen und Dokumentation hinzufügen, um die Nutzbarkeit seines Projekts zu erhöhen. –

4

Werfen Sie einen Blick auf die Pre-defined Compiler Macros page, wählen Sie Compilers->Clang. Es gibt Informationen zu vielen anderen Makros für Standards, Compiler, Bibliotheken, Betriebssysteme, Architekturen und mehr.

+0

Ehrfürchtig. Speichere einfach auch meinen Speck :) –

30

ich eine Antwort hier nicht finden kann, verbindet nur Antworten auf, so für die Vollständigkeit, hier ist die Antwort:

__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 

ich zur Zeit:

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

Ich bin damit einverstanden, dass die beste Wahl zu verwenden hat Feature Makros, nicht Version Makros. Beispiel mit 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 (: 

Aber wie auch immer, wenn Sie Version Compiler benötigen, können Sie 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; 
} 

Ausgangs Beispiele:

Clang-30400000 
Clang-50000000 
0

Beachten Sie, wenn Sie‘ Verwenden Sie llvm, um auf Bytecode zu hacken, und somit #include ing llvm Include-Dateien, Sie ca n Überprüfen Sie die Makros in llvm/Config/llvm-config.h.Und konkret:

/* 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"