2009-10-24 13 views
52

Pytanie jest całkiem jasne, myślę. Próbuję napisać nagłówek wykrywania kompilatora, aby móc uwzględnić w informacjach o aplikacji, który kompilator był używany i która wersja.Jak wykryć LLVM i jego wersję za pomocą dyrektyw #define?

Jest to część kodu używam:

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

które mogłyby zostać wykorzystane tak:

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

Czy istnieje jakiś sposób, aby wykryć LLVM i jego wersję? I CLANG?

+0

wielkie pytanie, nie mogę znaleźć żadnego DOCO na nim w ogóle –

+0

Czasem trzeba wiedzieć, jeśli dzyń Integrated Assembler jest używany, zbyt. Przypadkiem użycia jest nowoczesny GCC, a kompilator wykorzystuje Clang jako asembler zamiast starego GAS do montażu AESNI, AVX, BMI itp. Używasz zintegrowanego asemblera, ponieważ AS i Apple są zbyt stare, by zużywać zespół produkowany przez front -kończy się. – jww

Odpowiedz

64

Makra to oficjalna metoda sprawdzania kompilatora LLVM (llvm-gcc lub clang) lub języka.

__has_feature i __has_builtin są zalecanym sposobem sprawdzania opcjonalnych funkcji kompilatora podczas używania klanga, są one dokumentowane here.

pamiętać, że można znaleźć listę wbudowanych makr kompilator GCC, LLVM-gcc i brzękiem używając:

echo | clang -dM -E - 

Ten preprocesses pusty ciąg i wypluwa wszystkie makra zdefiniowane przez kompilator.

+22

Należy zauważyć, że '__GNUC__' jest zdefiniowany nawet dla clang i llvm-gcc. – pqnet

10

Fragment z 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\""); 

Nie mogę znaleźć żadnego sposobu, aby uzyskać wersji LLVM i samą brzękiem, chociaż ..

+0

Zgaduję, że można na razie polegać na twierdzeniu GCC o obsługiwanej wersji dla funkcji i clang/llvm dla rozszerzeń –

21

Dla brzękiem, nie należy sprawdzić jego numer wersji , powinieneś sprawdzić funkcje, które chcesz z feature checking macros.

+1

hm, to jest dobra uwaga. Czy możesz podać link do oficjalnego materiału na ten temat? –

+1

@Matt Joiner, myślę, że sam Chris jest pewnym urzędnikiem. Cytowany z jego strony głównej http://nondot.org/sabre/: "Jestem głównym autorem infrastruktury LLVM Compiler". – osgx

+2

@osgx: Mimo to mógł podać linki i dodać dokumentację, aby zwiększyć użyteczność swojego projektu. –

4

Spójrz na Pre-defined Compiler Macros page, wybierz Compilers->Clang. Zawiera informacje o wielu innych makrach dla standardów, kompilatorów, bibliotek, systemów operacyjnych, architektur i nie tylko.

+0

Awesome. Po prostu uratuj mój bekon też :) –

30

nie mogę znaleźć odpowiedzi tutaj linki tylko do odpowiedzi, tak pod względem kompletności, oto odpowiedź:

__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 

mam obecnie:

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

zgadzam się, że najlepszym wyborem jest do korzystania z funkcji ma makroinstrukcje, a nie makra wersji. Przykład z 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 (: 

Ale tak czy inaczej, jeśli trzeba kompilatora wersji, można użyć 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; 
} 

przykłady wyjściowe:

Clang-30400000 
Clang-50000000 
0

Zauważ, że jeśli” ponowne używanie llvm do hackowania na bajtode, a tym samym #include ing llvm include files, you ca n sprawdź makra w llvm/Config/llvm-config.h.A konkretnie:

/* 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" 
Powiązane problemy