Erkennen von CPU-Architektur Compile-Zeit
-
02-07-2019 - |
Frage
Was ist der zuverlässigste Weg, CPU-Architektur, um herauszufinden, wenn C oder C ++ Code kompiliert? Soweit ich das beurteilen kann, verschiedene Compiler haben ihre eigene Reihe von Nicht-Standard-Prozessor-Definitionen (_M_X86
in MSVS, __i386__
, __arm__
in GCC, etc).
Gibt es eine Standard Art und Weise die Architektur Ich baue für erkennen? Wenn nicht, ist es eine Quelle für eine umfassende Liste solcher Definitionen für verschiedene Compiler, wie ein Header mit all vorformulierten #ifdef
s?
Lösung
Hier sind einige Informationen über Vordefinierte Architektur Makros und andere Arten von pre -defined Makros.
Diese Frage fragt, wo sie definiert sind im Quellcode GCC.
Andere Tipps
Es gibt keinen inter-Compiler-Standard, aber jeder Compiler neigt ziemlich konsistent. Sie können einen Header für sich selbst bauen, das ist so etwas wie folgt aus:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
Es gibt nicht viel Sinn, zu einer umfassenden Liste, weil es Tausende von Compilern sind aber nur 3-4 weit verbreitet (Microsoft C ++, GCC, Intel CC, vielleicht TenDRA?). Nur entscheiden, welche Compiler Ihre Anwendung unterstützen, ihre #defines auflisten und Ihren Kopf aktualisiert je nach Bedarf.
Wenn Sie alle verfügbaren Funktionen auf einer bestimmten Plattform entleeren möchten, könnten Sie GCC laufen wie:
gcc -march=native -dM -E - </dev/null
Es würde Dump-Makros wie #define __SSE3__ 1
, #define __AES__ 1
, etc.
Wenn Sie eine Cross-Compiler-Lösung wollen, dann benutzen Sie einfach Boost.Predef
die enthält
-
BOOST_ARCH_
für System / CPU-Architektur ein kompiliert für. -
BOOST_COMP_
für den Compiler ein verwendet. -
BOOST_LANG_
für Sprachstandards ein gegen kompiliert. -
BOOST_LIB_C_
und BOOST_LIB_STD_ für die C- und C ++ Standard-Bibliothek verwendet wird. -
BOOST_OS_
für das Betriebssystem, das wir zu kompilieren. -
BOOST_PLAT_
für Plattformen auf der Betriebssystem oder Compiler. -
BOOST_ENDIAN_
für endianness der O und Architektur-Kombination. -
BOOST_HW_
für Hardware-spezifische Funktionen. -
BOOST_HW_SIMD
für SIMD (Single Instruction Multiple Data) Detektion.
Zum Beispiel
#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
Sie können erfahren Sie mehr darüber, wie es zu benutzen hier
Es gibt nichts Standard. Brian Haken dokumentiert eine Reihe von diesen in seiner „Portable Open Source Harness“, und sogar versucht, sie in etwas kohärentes und nutzbar (ymmv in Bezug auf das) zu machen. Siehe die posh.h Header auf dieser Seite:
Beachten Sie die obigen Link können benötigen Sie eine falsche Benutzer-ID / Passwort einzugeben aufgrund einer DoS-Attacke vor einiger Zeit.
Wenn Sie ein feinkörniges Erkennung von CPU-Funktionen benötigen, ist der beste Ansatz auch ein CPUID-Programm zu versenden, die Ausgänge auf die Standardausgabe oder eine „cpu_config.h“ Datei, um den Satz von Funktionen von der CPU unterstützt. Dann integrieren Sie das Programm mit dem Build-Prozess.