Question

Quel est le moyen le plus fiable de connaître l'architecture du processeur lors de la compilation de code C ou C ++? 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? Dans le cas contraire, existe-t-il une source pour une liste complète de ces définitions pour différents compilateurs, telle qu'un en-tête avec toutes les références #ifdef s?

Était-ce utile?

La solution

Voici des informations sur les Macros d'architecture prédéfinies et d'autres types de macros définies.

Cette question demande où ils sont définis dans le code source de GCC.

Autres conseils

Il n'y a pas de standard 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’ya pas grand intérêt à une liste complète, car il existe des milliers de compilateurs mais seulement 3 ou 4 sont largement utilisés (Microsoft C ++, GCC, Intel CC, peut-être TenDRA?). Il vous suffit de choisir les compilateurs pris en charge par votre application, de répertorier leurs #défines et de mettre à jour votre en-tête si nécessaire.

Si vous souhaitez transférer toutes les fonctionnalités disponibles sur une plate-forme particulière, vous pouvez exécuter GCC comme suit:

gcc -march=native -dM -E - </dev/null

Cela produirait des macros telles que #define __SSE3__ 1 , #define __AES__ 1 , etc.

Si vous souhaitez une solution de compilation croisée, utilisez simplement Boost.Predef qui contient

  • BOOST_ARCH _ pour l'architecture système / CPU pour laquelle vous compilez.
  • BOOST_COMP _ pour le compilateur utilisé.
  • BOOST_LANG _ pour les normes de langage sur lesquelles on compile.
  • BOOST_LIB_C _ et BOOST_LIB_STD_ pour les bibliothèques standard C et C ++ utilisées.
  • BOOST_OS _ pour le système d'exploitation pour lequel nous compilons.
  • BOOST_PLAT _ pour les plates-formes situées en haut du système d'exploitation ou les compilateurs.
  • BOOST_ENDIAN _ pour la finalité de la combinaison système d'exploitation et architecture.
  • BOOST_HW _ pour les fonctionnalités spécifiques au matériel.
  • BOOST_HW_SIMD pour la détection SIMD (données multiples à instruction unique).

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é plusieurs dans son "Portable Open Source Harness" et a même essayé de les transformer en 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 à saisir un nom d'utilisateur / mot de passe factice en raison d'une attaque DOS il y a quelque temps.

Si vous avez besoin d'une détection fine des caractéristiques de la CPU, la meilleure approche consiste à expédier également un programme CPUID qui sort vers stdout ou un "cpu_config.h". classe l'ensemble des fonctionnalités supportées par la CPU. Ensuite, vous intégrez ce programme à votre processus de construction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top