在编译C或C ++代码时,找出CPU架构最可靠的方法是什么?据我所知,不同的编译器有自己的一套非标准预处理器定义(MSVS中为_M_X86
,GCC中为__i386__
,__arm__
等。)
是否有标准方法来检测我正在构建的架构?如果没有,是否有各种编译器的此类定义的综合列表的来源,例如包含所有样板#ifdef
的标题?
答案 0 :(得分:73)
以下是有关Pre-defined Architecture Macros和其他类型的预定义宏的一些信息。
GCC源代码中的这个问题asks where they are defined。
答案 1 :(得分:14)
没有编译器间标准,但每个编译器都趋于一致。您可以为自己构建一个标题,如下所示:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
没有太多指向全面的列表,因为有数千个编译器,但只有3-4个被广泛使用(Microsoft C ++,GCC,Intel CC,可能是TenDRA?)。只需确定您的应用程序将支持哪些编译器,列出他们的#defines,并根据需要更新您的标头。
答案 2 :(得分:5)
如果要在特定平台上转储所有可用功能,可以运行GCC,如:
gcc -march=native -dM -E - </dev/null
它会转储像#define __SSE3__ 1
,#define __AES__ 1
等
答案 3 :(得分:4)
如果您要使用交叉编译器解决方案,则只需使用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(单指令多数据)检测。例如
#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
您可以找到有关如何使用它的更多信息here
答案 4 :(得分:3)
没有什么标准。 Brian Hook在他的“便携式开源线束”中记录了其中的一些,甚至试图将它们变成连贯可用的东西(ymmv就此而言)。请参阅本网站上的posh.h标题:
注意,上面的链接可能要求您在一段时间之前因DOS攻击而输入一些伪造的用户ID /密码。
答案 5 :(得分:2)
享受吧,我是本文的原作者。
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
}
}
答案 6 :(得分:-2)
如果您需要对CPU功能进行细粒度检测,最好的方法是发送一个CPUID程序,该程序将输出到stdout或某些“cpu_config.h”文件的CPU支持的功能集。然后,将该程序与构建过程集成。