Quelle est la manière la plus fiable de découvrir l'architecture CPU lors de la compilation de code C ou C++? Pour autant que je sache, différents compilateurs ont leur propre ensemble de définitions de préprocesseur non standard (_M_X86
dans MSVS, __i386__
, __arm__
dans GCC, etc.).
Existe-t-il un moyen standard de détecter l'architecture pour laquelle je construis? Sinon, existe-t-il une source pour une liste complète de ces définitions pour divers compilateurs, comme un en-tête avec tous les passe-partout #ifdef
s?
Voici quelques informations sur Macros d'architecture prédéfinies et d'autres types de macros prédéfinies.
Cette question demande où ils sont définis dans le code source de GCC.
Il n'y a pas de norme inter-compilateur, mais chaque compilateur a tendance à être assez cohérent. Vous pouvez créer un en-tête qui ressemble à ceci:
#if MSVC
#ifdef _M_X86
#define Arch_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define Arch_X86
#endif
#endif
Il n'y a pas grand chose à faire pour une liste complète, car il y a des milliers de compilateurs mais seulement 3-4 largement utilisés (Microsoft C++, GCC, Intel CC, peut-être TenDRA?). Décidez simplement des compilateurs que votre application prendra en charge, répertoriez leurs # définitions et mettez à jour votre en-tête si nécessaire.
Si vous souhaitez sauvegarder toutes les fonctionnalités disponibles sur une plate-forme particulière, vous pouvez exécuter GCC comme:
gcc -march=native -dM -E - </dev/null
Il viderait des macros comme #define __SSE3__ 1
, #define __AES__ 1
, etc.
Si vous voulez une solution de compilateur croisé, utilisez simplement Boost.Predef
qui contient
BOOST_Arch_
pour l'architecture système/CPU pour laquelle on compile.BOOST_COMP_
pour le compilateur utilisé.BOOST_LANG_
pour les normes linguistiques, on compile.BOOST_LIB_C_
et BOOST_LIB_STD_ pour la bibliothèque standard C et C++ utilisée.BOOST_OS_
pour le système d'exploitation que nous compilons.BOOST_PLAT_
pour les plates-formes au-dessus du système d'exploitation ou des compilateurs.BOOST_ENDIAN_
pour l'endianité de la combinaison os et architecture.BOOST_HW_
pour les fonctionnalités spécifiques au matériel.BOOST_HW_SIMD
pour la détection SIMD (Single Instruction Multiple Data).Par exemple
#if defined(BOOST_Arch_X86)
#if BOOST_Arch_X86_64
std::cout << "x86_64 " << BOOST_Arch_X86_64 << " \n";
#Elif BOOST_Arch_X86_32
std::cout << "x86 " << BOOST_Arch_X86_32 << " \n";
#endif
#Elif defined(BOOST_Arch_ARM)
#if _M_ARM
std::cout << "ARM " << _M_ARM << " \n";
#Elif _M_ARM64
std::cout << "ARM64 " << _M_ARM64 << " \n";
#endif
#endif
Vous pouvez en savoir plus sur son utilisation ici
Il n'y a rien de standard. Brian Hook en a documenté un tas dans son "Portable Open Source Harness", et essaie même d'en faire quelque chose de cohérent et utilisable (ymmv à ce sujet). Voir l'en-tête posh.h sur ce site:
Remarque, le lien ci-dessus peut vous obliger à entrer un faux identifiant/mot de passe en raison d'une attaque DOS il y a quelque temps.