¿Cómo detectar LLVM y su versión a través de directivas #define?

5 minutos de lectura

avatar de usuario
carla alvarez

La pregunta es bastante clara, creo. Estoy tratando de escribir un encabezado de detección del compilador para poder incluir en la aplicación información sobre qué compilador se usó y qué versión.

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 usarse así:

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

¿Hay alguna forma de detectar LLVM y su versión? ¿Y CANG?

  • gran pregunta, no puedo encontrar ningún doco en absoluto

    – Matt Carpintero

    24 de octubre de 2009 a las 13:43

  • A veces también necesita saber si se está utilizando el ensamblador integrado de Clang. El caso de uso es GCC moderno, y el compilador usa Clang como ensamblador en lugar de un GAS antiguo para ensamblar AESNI, AVX, BMI, etc. Usa el ensamblador integrado porque el AS y LD de Apple son demasiado antiguos para consumir el ensamblado producido por el frente. -Termina.

    – jww

    3 oct 2016 a las 16:59


avatar de usuario
Daniel Dunbar

los __llvm__ y __clang__ las macros 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 verificar las características opcionales del compilador cuando se usa clang, están documentadas aquí.

Tenga en cuenta que puede encontrar una lista de las macros del compilador integradas para gcc, llvm-gcc y clang usando:

echo | clang -dM -E -

Esto preprocesa una cadena vacía y escupe todas las macros definidas por el compilador.

  • Tenga en cuenta que __GNUC__ se define incluso para clang y llvm-gcc.

    – pqnet

    8 de julio de 2011 a las 10:08


  • mi respuesta especifica es #if __has_builtin(__builtin_available) github.com/firebase/firebase-ios-sdk/commit/…

    –Paul Beusterien

    18 de septiembre de 2018 a las 0:45

avatar de usuario
walter

No puedo encontrar una respuesta aquí, solo enlaces a respuestas, así 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

obtengo actualmente:

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

  • Vale la pena mencionar que esto no es confiable. Los proveedores (como Apple) lanzan sus propias versiones de clang con estos números modificados para reflejar sus propios números de versión, que no tienen relación con la versión de clang en la que se basa su compilador. Si está usando esto para tratar de determinar si algo es compatible, puede terminar con falsos positivos o falsos negativos (dependiendo de si los números de versión del proveedor son mayores o menores que los de clang).

    – nemequ

    9 de junio de 2020 a las 1:40

avatar de usuario
chris lattner

Para clang, no debe probar su número de versión, debe verificar las funciones que desea con macros de comprobación de características.

  • hm, este es un buen punto. ¿Puede proporcionar un enlace a algún material oficial sobre esto?

    – Matt Carpintero

    7 de noviembre de 2009 a las 5:36

  • @Matt Joiner, creo que el propio Chris es un oficial. Citado de su página de inicio nodot.org/sabre: “Soy el autor principal de la infraestructura del compilador LLVM”.

    – osgx

    23 de febrero de 2011 a las 9:57

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

    – Matt Carpintero

    24 de febrero de 2011 a las 1:41

  • Esto no ayuda cuando se trabaja con errores de LLVM. Como el error en el soporte de llamada rápida, que se rompió alrededor de la compilación 2335 y se corrigió en la compilación 2336.

    – rosafelix

    19 de junio de 2012 a las 17:06

  • todavía necesitarías __clang__ saber que el compilador era en realidad Clang.

    – rubenvb

    22 de marzo de 2013 a las 8:12

fragmento de InitPreprocesador.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\"");

Sin embargo, no encontré ninguna forma de obtener la versión de llvm y clang.

Echa un vistazo a la Página de macros del compilador predefinidasSeleccione Compiladores->Clang. Hay información sobre muchas otras macros para estándares, compiladores, bibliotecas, sistemas operativos, arquitecturas y más.

  • Impresionante. Solo guarda mi tocino también 🙂

    – Dirk Eddelbuettel

    27 de junio de 2012 a las 15:17

  • Gracias, esa es una gran fuente. El enlace actualizado es sourceforge.net/p/predef/wiki/Compilers

    – omajid

    25 de febrero de 2020 a las 15:47

Estoy de acuerdo en que la mejor opción es usar tiene característica macroses, no macroses de versión. Ejemplo con impulsar:

#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 necesitas versión del compiladorpuedes usar impulso.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 de salida:

Clang-30400000
Clang-50000000

  • Impresionante. Solo guarda mi tocino también 🙂

    – Dirk Eddelbuettel

    27 de junio de 2012 a las 15:17

  • Gracias, esa es una gran fuente. El enlace actualizado es sourceforge.net/p/predef/wiki/Compilers

    – omajid

    25 de febrero de 2020 a las 15:47

avatar de usuario
hugh perkins

Tenga en cuenta que si está utilizando llvm para piratear el código de bytes y, por lo tanto, #includeing llvm include files, puede verificar 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"

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad