Ale*_*x B 76 c c++ cpu-architecture detection compile-time
在编译C或C++代码时,找出CPU架构最可靠的方法是什么?据我所知,不同的编译器有自己的一套非标准预处理器定义(_M_X86
在MSVS中__i386__
,__arm__
在GCC 中等).
有没有一种标准的方法来检测我正在构建的架构?如果没有,是否有各种编译器的这种定义的综合列表的来源,例如包含所有样板#ifdef
的标题?
小智 39
享受吧,我是这个的原作者。
extern "C" {
const char *getBuild() { //Get current architecture, detectx nearly every architecture. Coded by Freak
#if defined(__x86_64__) || defined(_M_X64)
return "x86_64";
#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
return "x86_32";
#elif defined(__ARM_ARCH_2__)
return "ARM2";
#elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
return "ARM3";
#elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
return "ARM4T";
#elif defined(__ARM_ARCH_5_) || defined(__ARM_ARCH_5E_)
return "ARM5"
#elif defined(__ARM_ARCH_6T2_) || defined(__ARM_ARCH_6T2_)
return "ARM6T2";
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
return "ARM6";
#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
return "ARM7";
#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
return "ARM7A";
#elif defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
return "ARM7R";
#elif defined(__ARM_ARCH_7M__)
return "ARM7M";
#elif defined(__ARM_ARCH_7S__)
return "ARM7S";
#elif defined(__aarch64__) || defined(_M_ARM64)
return "ARM64";
#elif defined(mips) || defined(__mips__) || defined(__mips)
return "MIPS";
#elif defined(__sh__)
return "SUPERH";
#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
return "POWERPC";
#elif defined(__PPC64__) || defined(__ppc64__) || defined(_ARCH_PPC64)
return "POWERPC64";
#elif defined(__sparc__) || defined(__sparc)
return "SPARC";
#elif defined(__m68k__)
return "M68K";
#else
return "UNKNOWN";
#endif
}
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*kin 15
没有编译器间标准,但每个编译器都趋于相当一致.您可以为自己构建一个标题,如下所示:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
没有太多指向全面的列表,因为有数千个编译器,但只有3-4个被广泛使用(Microsoft C++,GCC,Intel CC,可能是TenDRA?).只需确定您的应用程序将支持哪些编译器,列出其#defines,并根据需要更新标头.
phu*_*clv 13
如果您想要一个交叉编译器解决方案,那么只需使用Boost.Predef
包含
BOOST_ARCH_
对于正在编译的系统/CPU 架构。BOOST_COMP_
对于正在使用的编译器。BOOST_LANG_
对于编译所依据的语言标准。BOOST_LIB_C_
以及BOOST_LIB_STD_
正在使用的 C 和 C++ 标准库。BOOST_OS_
对于我们正在编译的操作系统。BOOST_PLAT_
适用于操作系统或编译器之上的平台。BOOST_ENDIAN_
用于操作系统和体系结构组合的字节顺序。BOOST_HW_
对于硬件特定功能。BOOST_HW_SIMD
用于SIMD(单指令多数据)检测。请注意,虽然 Boost 通常被认为是一个 C++ 库,但Boost.Predef
它是纯头文件并且适用于 C
例如
#include <boost/predef.h>
// or just include the necessary headers
// #include <boost/predef/architecture.h>
// #include <boost/predef/other.h>
#if BOOST_ARCH_X86
#if BOOST_ARCH_X86_64
std::cout << "x86-64\n";
#elif BOOST_ARCH_X86_32
std::cout << "x86-32\n";
#else
std::cout << "x86-" << BOOST_ARCH_WORD_BITS << '\n'; // Probably x86-16
#endif
#elif BOOST_ARCH_ARM
#if BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(8, 0, 0)
#if BOOST_ARCH_WORD_BITS == 64
std::cout << "ARMv8+ Aarch64\n";
#elif BOOST_ARCH_WORD_BITS == 32
std::cout << "ARMv8+ Aarch32\n";
#else
std::cout << "Unexpected ARMv8+ " << BOOST_ARCH_WORD_BITS << "bit\n";
#endif
#elif BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(7, 0, 0)
std::cout << "ARMv7 (ARM32)\n";
#elif BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(6, 0, 0)
std::cout << "ARMv6 (ARM32)\n";
#else
std::cout << "ARMv5 or older\n";
#endif
#elif BOOST_ARCH_MIPS
#if BOOST_ARCH_WORD_BITS == 64
std::cout << "MIPS64\n";
#else
std::cout << "MIPS32\n";
#endif
#elif BOOST_ARCH_PPC_64
std::cout << "PPC64\n";
#elif BOOST_ARCH_PPC
std::cout << "PPC32\n";
#else
std::cout << "Unknown " << BOOST_ARCH_WORD_BITS << "-bit arch\n";
#endif
Run Code Online (Sandbox Code Playgroud)
您可以在此处了解有关如何使用它的更多信息
如果要在特定平台上转储所有可用功能,则可以运行GCC,如下所示:
gcc -march=native -dM -E - </dev/null
Run Code Online (Sandbox Code Playgroud)
这将转储像宏#define __SSE3__ 1
,#define __AES__ 1
等等。
没有什么标准。Brian Hook 在他的“Portable Open Source Harness”中记录了其中的一些内容,甚至尝试将它们变成连贯且可用的东西(ymmv 对此)。请参阅他的存储库中的 posh.h 标头: