2009-10-24 1 views
52

La domanda è abbastanza chiara, penso. Sto cercando di scrivere un'intestazione di rilevamento del compilatore per poter includere nelle informazioni dell'applicazione su quale compilatore è stato utilizzato e quale versione.Come rilevare LLVM e la sua versione tramite le direttive #define?

Questo fa parte del codice che sto utilizzando:

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

che potrebbe essere utilizzato in questo modo:

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

Esiste un modo per rilevare LLVM e la sua versione? E CLANG?

+0

grande questione, non riesco a trovare alcuna doco su di esso a tutti –

+0

A volte è necessario sapere se è in uso di Clang Assembler integrato, anche. Il caso d'uso è il GCC moderno e il compilatore usa Clang come assemblatore piuttosto che un vecchio GAS per assemblare AESNI, AVX, BMI, ecc. Si usa l'assemblatore integrato perché l'AS e il LD di Apple sono troppo vecchi per consumare l'assemblaggio prodotto dalla parte anteriore -ends. – jww

risposta

64

I macro __llvm__ e __clang__ sono il modo ufficiale per verificare rispettivamente un compilatore LLVM (llvm-gcc o clang) o clang.

__has_feature e __has_builtin sono il modo consigliato di verificare le caratteristiche del compilatore opzionale quando si utilizza clang, sono documentati here.

noti che è possibile trovare un elenco delle macro compilatore integrato per gcc, LLVM-GCC, e clang utilizzando:

echo | clang -dM -E - 

Questa preprocessa una stringa vuota e sputa fuori tutte le macro definite dal compilatore.

+22

Si noti che '__GNUC__' è definito anche per clang e llvm-gcc. – pqnet

10

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

non ho trovato un modo per ottenere la versione di LLVM e clang per sé, anche se ..

+0

Suppongo che per ora si possa fare affidamento sulla versione GCC richiesta supportata per le funzionalità e clang/llvm per le estensioni –

21

Per clang, non si dovrebbe verificare il numero di versione , dovresti controllare le funzionalità che desideri con feature checking macros.

+1

hm, questo è un buon punto. puoi fornire un link ad alcuni materiali ufficiali su questo? –

+1

@Matt Joiner, penso, Chris stesso è ufficiale. Citato dalla sua homepage http://nondot.org/sabre/: "Sono l'autore principale del LLVM Compiler Infrastructure". – osgx

+2

@osgx: Tuttavia, potrebbe fornire collegamenti e aggiungere documentazione per aumentare l'usabilità del suo progetto. –

4

Dai uno sguardo allo Pre-defined Compiler Macros page, seleziona Compilers->Clang. Vi sono informazioni su molte altre macro per standard, compilatori, librerie, SO, architetture e altro.

+0

Fantastico. Basta salvare anche il mio bacon :) –

30

non riesco a trovare una risposta qui, collega a risposte, in modo per completezza, ecco la risposta:

__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 

ottengo attualmente:

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

Sono d'accordo che la scelta migliore è per utilizzare è disponibile la macro, non le macrose di versione. Esempio con 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 (: 

Ma in ogni caso, se avete bisogno di compilatore versione, è possibile utilizzare 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; 
} 

esempi di uscita:

Clang-30400000 
Clang-50000000 
0

Nota che se si' re usando llvm per hackerare il bytecode, e quindi #include ing llm include i file, si ca n controllare i macro in llvm/Config/llvm-config.h.E concretamente:

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