¿Cómo detectar LLVM y su versión a través de las directivas #define?
-
06-07-2019 - |
Pregunta
La pregunta es bastante clara, creo. Estoy intentando escribir un encabezado de detección del compilador para poder incluir en la información de la aplicación en qué compilador se usó y en 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 ser usado de esta manera:
printf(" Compiled using " COMPILER "\n", COMP_VERSION);
¿Hay alguna forma de detectar LLVM y su versión? Y CLANG?
Solución
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 verificar las características del compilador opcionales cuando se usa el clang, están documentadas here .
Tenga en cuenta que puede encontrar una lista de las macros del compilador incorporado para gcc, llvm-gcc y clang usando:
echo | clang -dM -E -
Esto procesa previamente una cadena vacía y escupe todas las macros definidas por el compilador.
Otros consejos
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
Me sale actualmente:
__clang__=1
__clang_major__=3
__clang_minor__=2
__clang_patchlevel__=0
__clang_version__="3.2 (tags/RELEASE_32/final)"
Para el Clang, no debe probar su número de versión, debe verificar las características que desea con macros de comprobación de características .
Fragmento 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\"");
Sin embargo, no encontré ninguna forma de obtener la versión de llvm y el propio Clang ...
Eche un vistazo a la página de macros de compilador predefinidas , seleccione Compiladores - > Clang . Hay información sobre muchas otras macros para estándares, compiladores, bibliotecas, sistemas operativos, arquitecturas y más.
Estoy de acuerdo en que la mejor opción es utilizar las macros tiene la función , no las macros de la 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 versión del compilador , puede usar 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 de salida:
Clang-30400000
Clang-50000000
Tenga en cuenta que si está utilizando llvm para piratear el bytecode y, por lo tanto, #include
ing llvm incluye archivos, 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"