Como detectar LLVM e sua versão através #define directivas?
-
06-07-2019 - |
Pergunta
A questão é bastante claro que eu penso. Eu estou tentando escrever um cabeçalho detecção compilador para ser capaz de incluir as informações de aplicativos no qual foi utilizado compilador e qual versão.
Esta é parte do código que estou 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
O que poderia ser usado como este:
printf(" Compiled using " COMPILER "\n", COMP_VERSION);
Existe alguma maneira de detectar LLVM e sua versão? E CLANG?
Solução
Os __llvm__
e __clang__
macros são o caminho oficial para verificar se há um compilador LLVM (llvm-gcc ou clang) ou clang, respectivamente.
__has_feature
e __has_builtin
são a maneira recomendada de verificar o compilador opcional recursos quando usando clang, eles são documentados aqui .
Note que você pode encontrar uma lista de macros compilador embutido para gcc, llvm-gcc, e clang usando:
echo | clang -dM -E -
Esta preprocesses uma cadeia vazia e cospe todas as macros definidas pelo compilador.
Outras dicas
Não consigo encontrar uma resposta aqui, apenas links para respostas, então para a completude, aqui está a resposta:
__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
Eu recebo atualmente:
__clang__=1
__clang_major__=3
__clang_minor__=2
__clang_patchlevel__=0
__clang_version__="3.2 (tags/RELEASE_32/final)"
Para clang, você não deve testar seu número de versão, você deve verificar se há características que você quer com recurso de verificação de macros .
// 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\"");
Eu não havia nenhuma maneira de obter a versão do llvm ea própria clang, embora ..
Dê uma olhada no Compiler Macros página pré-definido, selecione Compilers-> Clang . Não há informações sobre muitas outras macros para padrões, compiladores, bibliotecas, OS, arquiteturas e muito mais.
Eu concordo que a melhor opção é usar tem a característica macroses, não a versão macroses. Exemplo impulso :
#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 (:
Mas de qualquer maneira, se você precisa de versão do compilador , você pode 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;
}
exemplos de saída:
Clang-30400000
Clang-50000000
Note que se você estiver usando llvm para cortar em bytecode, e #include
ing assim llvm incluir arquivos, você pode verificar as macros em 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"