2009-10-24 13 views
52

La pregunta es bastante clara, creo. Intento escribir un encabezado de detección de compilador para poder incluir en la información de la aplicación en qué compilador se utilizó y qué versión.Cómo detectar LLVM y su versión a través de las directivas #define?

Esto es parte del código que estoy usando:

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

que podría ser utilizado como esto:

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

¿Hay alguna manera de detectar LLVM y su versión? Y CLANG?

+0

gran pregunta, no puedo encontrar ninguna mana en él en absoluto –

+0

A veces se necesita saber si se está utilizando de Sonido metálico integrado ensamblador, también. El caso de uso es el GCC moderno, y el compilador usa Clang como ensamblador en lugar de un GAS antiguo para ensamblar AESNI, AVX, BMI, etc. Usas el ensamblador integrado porque el AS y el LD de Apple son demasiado viejos para consumir el ensamblaje producido por el frente -fines – jww

Respuesta

64

Las macros __llvm__ y __clang__ son la forma oficial de buscar un compilador LLVM (llvm-gcc o clang) o clang, respectivamente.

__has_feature y __has_builtin son la forma recomendada de comprobar las características opcionales del compilador al usar clang, están documentadas here.

Tenga en cuenta que usted puede encontrar una lista de las macros incorporadas compilador gcc para, llvm-gcc y sonido metálico usando:

echo | clang -dM -E - 

Esta pre procesa una cadena vacía y escupe todas las macros definidas por el compilador.

+22

Tenga en cuenta que '__GNUC__' se define incluso para clang y llvm-gcc. – pqnet

10

de fragmentos 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\""); 

no he encontrado ninguna manera de obtener la versión de llvm y sonido metálico en sí, aunque ..

+0

supongo que uno podría confiar ahora en la versión de GCC reclamada compatible con las características, y clang/llvm para las extensiones –

21

Para sonido metálico, que no debe probar su número de versión , debe verificar las características que desea con feature checking macros.

+1

hm, este es un buen punto. ¿Puedes proporcionar un enlace a algún material oficial con respecto a esto? –

+1

@Matt Joiner, creo, Chris mismo es un oficial. Citado de su página de inicio http://nondot.org/sabre/: "Soy el principal autor de la Infraestructura del compilador LLVM". – osgx

+2

@osgx: Sin embargo, podría proporcionar enlaces y agregar documentación para aumentar la usabilidad de su proyecto. –

4

Eche un vistazo a Pre-defined Compiler Macros page, seleccione Compilers->Clang. Hay información sobre muchas otras macros para estándares, compiladores, bibliotecas, sistema operativo, arquitecturas y más.

+0

Impresionante. Solo guarde mi tocino también :) –

30

no puedo encontrar una respuesta aquí, sólo enlaza a las respuestas, por lo que para completar, aquí está la respuesta:

__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 

me sale actualmente:

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

Estoy de acuerdo que la mejor opción es para usar tiene macros de, no macros de versión. Ejemplo 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 (: 

Pero de todos modos, si necesita compilador versión, puede utilizar 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; 
} 

ejemplos salida:

Clang-30400000 
Clang-50000000 
0

Tenga en cuenta que si' re usando llvm para hackear bytecode, y por lo tanto #include ing llvm include files, ca n compruebe las macros en llvm/Config/llvm-config.h.Y 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" 
Cuestiones relacionadas