【QT】Qt Compiler Detection(编译)
生活随笔
收集整理的這篇文章主要介紹了
【QT】Qt Compiler Detection(编译)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、Compiler&GNU
Qt是跨平臺的,從下面的編譯配置選項(宏)中可以看出Qt支持的編譯環境。
// qcompilerdetection.h /*The compiler, must be one of: (Q_CC_x)SYM - Digital Mars C/C++ (used to be Symantec C++)MSVC - Microsoft Visual C/C++, Intel C++ for WindowsBOR - Borland/Turbo C++WAT - Watcom C++GNU - GNU C++COMEAU - Comeau C++EDG - Edison Design Group C++OC - CenterLine C++SUN - Forte Developer, or Sun Studio C++MIPS - MIPSpro C++DEC - DEC C++HPACC - HP aC++USLC - SCO OUDK and UDKCDS - Reliant C++KAI - KAI C++INTEL - Intel C++ for Linux, Intel C++ for WindowsHIGHC - MetaWare High C/C++PGI - Portland Group C++GHS - Green Hills Optimizing C++ CompilersRVCT - ARM Realview Compiler SuiteCLANG - C++ front-end for the LLVM compilerShould be sorted most to least authoritative. */或者如下所示的Qt支持的OS。
// qsystemdetection.h /*The operating system, must be one of: (Q_OS_x)DARWIN - Any Darwin system (macOS, iOS, watchOS, tvOS)MACOS - macOSIOS - iOSWATCHOS - watchOSTVOS - tvOSMSDOS - MS-DOS and WindowsOS2 - OS/2OS2EMX - XFree86 on OS/2 (not PM)WIN32 - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008)WINRT - WinRT (Windows 8 Runtime)CYGWIN - CygwinSOLARIS - Sun SolarisHPUX - HP-UXULTRIX - DEC UltrixLINUX - Linux [has variants]FREEBSD - FreeBSD [has variants]NETBSD - NetBSDOPENBSD - OpenBSDBSDI - BSD/OSINTERIX - InterixIRIX - SGI IrixOSF - HP Tru64 UNIXSCO - SCO OpenServer 5UNIXWARE - UnixWare 7, Open UNIX 8AIX - AIXHURD - GNU HurdDGUX - DG/UXRELIANT - Reliant UNIXDYNIX - DYNIX/ptxQNX - QNX [has variants]QNX6 - QNX RTP 6.1LYNX - LynxOSBSD4 - Any BSD 4.4 systemUNIX - Any UNIX BSD/SYSV systemANDROID - Android platformHAIKU - HaikuThe following operating systems have variants:LINUX - both Q_OS_LINUX and Q_OS_ANDROID are defined when building for Android- only Q_OS_LINUX is defined if building for other Linux systemsFREEBSD - Q_OS_FREEBSD is defined only when building for FreeBSD with a BSD userland- Q_OS_FREEBSD_KERNEL is always defined on FreeBSD, even if the userland is from GNU */以GNU為例,我們來看看Qt通過gcc的特性定義了那些東西,如常見的__attribute__。
// qcompilerdetection.h // ... other compilers #elif defined(__GNUC__) # define Q_CC_GNU (__GNUC__ * 100 + __GNUC_MINOR__) // gnu # if defined(__MINGW32__) # define Q_CC_MINGW // mingw # endif # if defined(__INTEL_COMPILER) # define Q_CC_INTEL (__INTEL_COMPILER) // intel // ... intel compiler # else /* Plain GCC */ # if Q_CC_GNU >= 405 // version # define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable() # define Q_UNREACHABLE_IMPL() __builtin_unreachable() # define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) # endif # endif# ifdef Q_OS_WIN // win # define Q_DECL_EXPORT __declspec(dllexport) # define Q_DECL_IMPORT __declspec(dllimport) # elif defined(QT_VISIBILITY_AVAILABLE) // linux # define Q_DECL_EXPORT __attribute__((visibility("default"))) # define Q_DECL_IMPORT __attribute__((visibility("default"))) # define Q_DECL_HIDDEN __attribute__((visibility("hidden"))) # endif# define Q_FUNC_INFO __PRETTY_FUNCTION__ # define Q_ALIGNOF(type) __alignof__(type) # define Q_TYPEOF(expr) __typeof__(expr) # define Q_DECL_DEPRECATED __attribute__ ((__deprecated__)) # define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) # define Q_DECL_UNUSED __attribute__((__unused__)) # define Q_LIKELY(expr) __builtin_expect(!!(expr), true) # define Q_UNLIKELY(expr) __builtin_expect(!!(expr), false) # define Q_NORETURN __attribute__((__noreturn__)) # define Q_REQUIRED_RESULT __attribute__ ((__warn_unused_result__)) # define Q_DECL_PURE_FUNCTION __attribute__((pure)) # define Q_DECL_CONST_FUNCTION __attribute__((const)) # if !defined(QT_MOC_CPP) // no moc # define Q_PACKED __attribute__ ((__packed__)) # ifndef __ARM_EABI__ // no arm eabi # define QT_NO_ARM_EABI # endif # endif # if Q_CC_GNU >= 403 && !defined(Q_CC_CLANG) // version && non-clang # define Q_ALLOC_SIZE(x) __attribute__((alloc_size(x))) # endif2、C++11&GNU
下面是gcc各版本對C++11的支持所涉及的宏。
// qcompilerdetection.h #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG) # define Q_COMPILER_RESTRICTED_VLA # define Q_COMPILER_THREADSAFE_STATICS # if Q_CC_GNU >= 403 // GCC supports binary literals in C, C++98 and C++11 modes # define Q_COMPILER_BINARY_LITERALS # endif # if !defined(__STRICT_ANSI__) || defined(__GXX_EXPERIMENTAL_CXX0X__) \|| (defined(__cplusplus) && (__cplusplus >= 201103L)) \|| (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))// Variadic macros are supported for gnu++98, c++11, C99 ... since forever (gcc 2.97) # define Q_COMPILER_VARIADIC_MACROS # endif # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L # if Q_CC_GNU >= 403/* C++11 features supported in GCC 4.3: */ # define Q_COMPILER_DECLTYPE # define Q_COMPILER_RVALUE_REFS # define Q_COMPILER_STATIC_ASSERT # endif # if Q_CC_GNU >= 404/* C++11 features supported in GCC 4.4: */ # define Q_COMPILER_AUTO_FUNCTION # define Q_COMPILER_AUTO_TYPE # define Q_COMPILER_EXTERN_TEMPLATES # define Q_COMPILER_UNIFORM_INIT # define Q_COMPILER_UNICODE_STRINGS # define Q_COMPILER_VARIADIC_TEMPLATES # endif # if Q_CC_GNU >= 405/* C++11 features supported in GCC 4.5: */ # define Q_COMPILER_EXPLICIT_CONVERSIONS/* GCC 4.4 implements initializer_list but does not define typedefs required* by the standard. */ # define Q_COMPILER_INITIALIZER_LISTS # define Q_COMPILER_LAMBDA # define Q_COMPILER_RAW_STRINGS # define Q_COMPILER_CLASS_ENUM # endif # if Q_CC_GNU >= 406/* Pre-4.6 compilers implement a non-final snapshot of N2346, hence default and delete* functions are supported only if they are public. Starting from 4.6, GCC handles* final version - the access modifier is not relevant. */ # define Q_COMPILER_DEFAULT_MEMBERS # define Q_COMPILER_DELETE_MEMBERS/* C++11 features supported in GCC 4.6: */ # define Q_COMPILER_CONSTEXPR # define Q_COMPILER_NULLPTR # define Q_COMPILER_UNRESTRICTED_UNIONS # define Q_COMPILER_RANGE_FOR # endif # if Q_CC_GNU >= 407/* GCC 4.4 implemented <atomic> and std::atomic using its old intrinsics.* However, the implementation is incomplete for most platforms until GCC 4.7:* instead, std::atomic would use an external lock. Since we need an std::atomic* that is behavior-compatible with QBasicAtomic, we only enable it here */ # define Q_COMPILER_ATOMICS/* GCC 4.6.x has problems dealing with noexcept expressions,* so turn the feature on for 4.7 and above, only */ # define Q_COMPILER_NOEXCEPT/* C++11 features supported in GCC 4.7: */ # define Q_COMPILER_NONSTATIC_MEMBER_INIT # define Q_COMPILER_DELEGATING_CONSTRUCTORS # define Q_COMPILER_EXPLICIT_OVERRIDES # define Q_COMPILER_TEMPLATE_ALIAS # define Q_COMPILER_UDL # endif # if Q_CC_GNU >= 408 # define Q_COMPILER_ATTRIBUTES # define Q_COMPILER_ALIGNAS # define Q_COMPILER_ALIGNOF # define Q_COMPILER_INHERITING_CONSTRUCTORS # define Q_COMPILER_THREAD_LOCAL # if Q_CC_GNU > 408 || __GNUC_PATCHLEVEL__ >= 1 # define Q_COMPILER_REF_QUALIFIERS # endif # endif/* C++11 features are complete as of GCC 4.8.1 */ # endif # if __cplusplus > 201103L # if Q_CC_GNU >= 409/* C++1y features in GCC 4.9 - deprecated, do not update this list */ //# define Q_COMPILER_BINARY_LITERALS // already supported since GCC 4.3 as an extension # define Q_COMPILER_LAMBDA_CAPTURES # define Q_COMPILER_RETURN_TYPE_DEDUCTION # endif # endif #endif3、C++11 keywords
下面是與C++11各關鍵字相關的宏,如常見的= default、= delete。
// qcompilerdetection.h /** C++11 keywords and expressions*/ #ifdef Q_COMPILER_NULLPTR # define Q_NULLPTR nullptr #else # define Q_NULLPTR NULL #endif#ifdef Q_COMPILER_DEFAULT_MEMBERS # define Q_DECL_EQ_DEFAULT = default #else # define Q_DECL_EQ_DEFAULT #endif#ifdef Q_COMPILER_DELETE_MEMBERS # define Q_DECL_EQ_DELETE = delete #else # define Q_DECL_EQ_DELETE #endif// Don't break code that is already using Q_COMPILER_DEFAULT_DELETE_MEMBERS #if defined(Q_COMPILER_DEFAULT_MEMBERS) && defined(Q_COMPILER_DELETE_MEMBERS) # define Q_COMPILER_DEFAULT_DELETE_MEMBERS #endif#if defined Q_COMPILER_CONSTEXPR # if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304 # define Q_DECL_CONSTEXPR constexpr # define Q_DECL_RELAXED_CONSTEXPR constexpr # define Q_CONSTEXPR constexpr # define Q_RELAXED_CONSTEXPR constexpr # else # define Q_DECL_CONSTEXPR constexpr # define Q_DECL_RELAXED_CONSTEXPR # define Q_CONSTEXPR constexpr # define Q_RELAXED_CONSTEXPR const # endif #else # define Q_DECL_CONSTEXPR # define Q_DECL_RELAXED_CONSTEXPR # define Q_CONSTEXPR const # define Q_RELAXED_CONSTEXPR const #endif#ifdef Q_COMPILER_EXPLICIT_OVERRIDES # define Q_DECL_OVERRIDE override # define Q_DECL_FINAL final #else # ifndef Q_DECL_OVERRIDE # define Q_DECL_OVERRIDE # endif # ifndef Q_DECL_FINAL # define Q_DECL_FINAL # endif #endif#ifdef Q_COMPILER_NOEXCEPT # define Q_DECL_NOEXCEPT noexcept # define Q_DECL_NOEXCEPT_EXPR(x) noexcept(x) # ifdef Q_DECL_NOTHROW # undef Q_DECL_NOTHROW /* override with C++11 noexcept if available */ # endif #else # define Q_DECL_NOEXCEPT # define Q_DECL_NOEXCEPT_EXPR(x) #endif #ifndef Q_DECL_NOTHROW # define Q_DECL_NOTHROW Q_DECL_NOEXCEPT #endif#if defined(Q_COMPILER_ALIGNOF) # undef Q_ALIGNOF # define Q_ALIGNOF(x) alignof(x) #endif#if defined(Q_COMPILER_ALIGNAS) # undef Q_DECL_ALIGN # define Q_DECL_ALIGN(n) alignas(n) #endif4、C++ standard
C++標準參考:https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
下面是sg10-sd6給出的一些C++特性。
5、Warning handling
在編譯代碼時,常會看到一些Warning,這些Warning可以通過技術手段規避,如下的一些宏定義,將會產生警告的代碼置于push與pop之間,或者直接disable或ignored會產生警告的編譯規則。
// qcompilerdetection.h #define QT_DO_PRAGMA(text) _Pragma(#text) // ... other compilers #elif defined(Q_CC_MSVC) && _MSC_VER >= 1500 && !defined(Q_CC_CLANG) # undef QT_DO_PRAGMA /* not needed */ # define QT_WARNING_PUSH __pragma(warning(push)) # define QT_WARNING_POP __pragma(warning(pop)) # define QT_WARNING_DISABLE_MSVC(number) __pragma(warning(disable: number)) # define QT_WARNING_DISABLE_INTEL(number) # define QT_WARNING_DISABLE_CLANG(text) # define QT_WARNING_DISABLE_GCC(text) # define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_MSVC(4996) #elif defined(Q_CC_GNU) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) # define QT_WARNING_PUSH QT_DO_PRAGMA(GCC diagnostic push) # define QT_WARNING_POP QT_DO_PRAGMA(GCC diagnostic pop) # define QT_WARNING_DISABLE_GCC(text) QT_DO_PRAGMA(GCC diagnostic ignored text) # define QT_WARNING_DISABLE_CLANG(text) # define QT_WARNING_DISABLE_INTEL(number) # define QT_WARNING_DISABLE_MSVC(number) # define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") #else // All other compilers, GCC < 4.6 and MSVC < 2008 # define QT_WARNING_DISABLE_GCC(text) # define QT_WARNING_PUSH # define QT_WARNING_POP # define QT_WARNING_DISABLE_INTEL(number) # define QT_WARNING_DISABLE_MSVC(number) # define QT_WARNING_DISABLE_CLANG(text) # define QT_WARNING_DISABLE_GCC(text) # define QT_WARNING_DISABLE_DEPRECATED #endif6、arch processor
下面是Qt支持的處理器類型(ARCH_PROCESSOR),如常見的i386、x86_64等。
// archdetect.cpp // main part: processor type #if defined(Q_PROCESSOR_ALPHA) # define ARCH_PROCESSOR "alpha" #elif defined(Q_PROCESSOR_ARM_32) # define ARCH_PROCESSOR "arm" #elif defined(Q_PROCESSOR_ARM_64) # define ARCH_PROCESSOR "arm64" #elif defined(Q_PROCESSOR_AVR32) # define ARCH_PROCESSOR "avr32" #elif defined(Q_PROCESSOR_BLACKFIN) # define ARCH_PROCESSOR "bfin" #elif defined(Q_PROCESSOR_X86_32) # define ARCH_PROCESSOR "i386" #elif defined(Q_PROCESSOR_X86_64) # define ARCH_PROCESSOR "x86_64" #elif defined(Q_PROCESSOR_IA64) # define ARCH_PROCESSOR "ia64" #elif defined(Q_PROCESSOR_MIPS_64) # define ARCH_PROCESSOR "mips64" #elif defined(Q_PROCESSOR_MIPS) # define ARCH_PROCESSOR "mips" #elif defined(Q_PROCESSOR_POWER_32) # define ARCH_PROCESSOR "power" #elif defined(Q_PROCESSOR_POWER_64) # define ARCH_PROCESSOR "power64" #elif defined(Q_PROCESSOR_S390_X) # define ARCH_PROCESSOR "s390x" #elif defined(Q_PROCESSOR_S390) # define ARCH_PROCESSOR "s390" #elif defined(Q_PROCESSOR_SH) # define ARCH_PROCESSOR "sh" #elif defined(Q_PROCESSORS_SPARC_64) # define ARCH_PROCESSOR "sparc64" #elif defined(Q_PROCESSOR_SPARC_V9) # define ARCH_PROCESSOR "sparcv9" #elif defined(Q_PROCESSOR_SPARC) # define ARCH_PROCESSOR "sparc" #else # define ARCH_PROCESSOR "unknown" #endif處理器對應的宏有固定的格式,如下所示。
// qprocessordetection.h Q_PROCESSOR_{FAMILY}Q_PROCESSOR_{FAMILY}_{VARIANT}Q_PROCESSOR_{FAMILY}_{REVISION}// qprocessordetection.h // ... other arches /* ARM family, known revisions: V5, V6, V7, V8 ARM is bi-endian, detect using __ARMEL__ or __ARMEB__X86 family, known variants: 32- and 64-bit X86 is little-endian /* #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) # define Q_PROCESSOR_X86_32 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # define Q_PROCESSOR_WORDSIZE 4 # if defined(_M_IX86) # define Q_PROCESSOR_X86 (_M_IX86/100) # elif defined(__i686__) || defined(__athlon__) || defined(__SSE__) || defined(__pentiumpro__) # define Q_PROCESSOR_X86 6 # elif defined(__i586__) || defined(__k6__) || defined(__pentium__) # define Q_PROCESSOR_X86 5 # elif defined(__i486__) || defined(__80486__) # define Q_PROCESSOR_X86 4 # else # define Q_PROCESSOR_X86 3 # endif #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) # define Q_PROCESSOR_X86 6 # define Q_PROCESSOR_X86_64 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # define Q_PROCESSOR_WORDSIZE 8 // ... other arches7、arch endian
大小端字節序(ARCH_ENDIANNESS)定義如下所示。
// archdetect.cpp // endianness #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN # define ARCH_ENDIANNESS "little_endian" #elif Q_BYTE_ORDER == Q_BIG_ENDIAN # define ARCH_ENDIANNESS "big_endian" #endif// qprocessordetection.h /* Machine byte-order, reuse preprocessor provided macros when available */ #if defined(__ORDER_BIG_ENDIAN__) # define Q_BIG_ENDIAN __ORDER_BIG_ENDIAN__ #else # define Q_BIG_ENDIAN 4321 #endif #if defined(__ORDER_LITTLE_ENDIAN__) # define Q_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ #else # define Q_LITTLE_ENDIAN 1234 #endif// qprocessordetection.h /*NOTE:GCC 4.6 added __BYTE_ORDER__, __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__and __ORDER_PDP_ENDIAN__ in SVN r165881. If you are using GCC 4.6 or newer,this code will properly detect your target byte order; if you are not, andthe __LITTLE_ENDIAN__ or __BIG_ENDIAN__ macros are not defined, then thiscode will fail to detect the target byte order. */ // Some processors support either endian format, try to detect which we are using. #if !defined(Q_BYTE_ORDER) # if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN) // Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults # define Q_BYTE_ORDER __BYTE_ORDER__ # elif defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN) # define Q_BYTE_ORDER Q_BIG_ENDIAN # elif defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) \|| defined(WINAPI_FAMILY) // WinRT is always little-endian according to MSDN. # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # else # error "Unable to determine byte order!" # endif #endif8、arch pointer
指針大小(ARCH_POINTER)定義如下所示。
// archdetect.cpp // pointer type #if defined(Q_OS_WIN64) || (defined(Q_OS_WINRT) && defined(_M_X64)) # define ARCH_POINTER "llp64" #elif defined(__LP64__) || QT_POINTER_SIZE - 0 == 8 # define ARCH_POINTER "lp64" #else # define ARCH_POINTER "ilp32" #endif// qprocessordetection.h /*Size of a pointer and the machine register size. We detect a 64-bit system by:* GCC and compatible compilers (Clang, ICC on OS X and Windows) always define__SIZEOF_POINTER__. This catches all known cases of ILP32 builds on 64-bitprocessors.* Most other Unix compilers define __LP64__ or _LP64 on 64-bit mode(Long and Pointer 64-bit)* If Q_PROCESSOR_WORDSIZE was defined above, it's assumed to match the pointersize.Otherwise, we assume to be 32-bit and then check in qglobal.cpp that it is right. */#if defined __SIZEOF_POINTER__ # define QT_POINTER_SIZE __SIZEOF_POINTER__ #elif defined(__LP64__) || defined(_LP64) # define QT_POINTER_SIZE 8 #elif defined(Q_PROCESSOR_WORDSIZE) # define QT_POINTER_SIZE Q_PROCESSOR_WORDSIZE #else # define QT_POINTER_SIZE 4 #endif9、arch coordinate
浮點數精度(ARCH_COORD_TYPE)定義如下所示。
// archdetect.cpp // qreal type, if not double (includes the dash) #ifdef QT_COORD_TYPE_STRING # define ARCH_COORD_TYPE "-qreal_" QT_COORD_TYPE_STRING #else # define ARCH_COORD_TYPE "" #endif10、arch abi
程序二進制接口相關的軟、硬浮點(ARCH_ABI)定義如下所示。
// archdetect.cpp // secondary: ABI string (includes the dash) #if defined(__ARM_EABI__) || defined(__mips_eabi) # define ARCH_ABI1 "-eabi" #elif defined(_MIPS_SIM) # if _MIPS_SIM == _ABIO32 # define ARCH_ABI1 "-o32" # elif _MIPS_SIM == _ABIN32 # define ARCH_ABI1 "-n32" # elif _MIPS_SIM == _ABI64 # define ARCH_ABI1 "-n64" # elif _MIPS_SIM == _ABIO64 # define ARCH_ABI1 "-o64" # endif #else # define ARCH_ABI1 "" #endif #if defined(__ARM_PCS_VFP) || defined(__mips_hard_float) // Use "-hardfloat" for platforms that usually have no FPUs // (and for the platforms which had "-hardfloat" before we established the rule) # define ARCH_ABI2 "-hardfloat" #elif defined(_SOFT_FLOAT) // Use "-softfloat" for architectures that usually have FPUs # define ARCH_ABI2 "-softfloat" #else # define ARCH_ABI2 "" #endif#define ARCH_ABI ARCH_ABI1 ARCH_ABI2總結
以上是生活随笔為你收集整理的【QT】Qt Compiler Detection(编译)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [SugerTangYL] 简易电子时钟
- 下一篇: C/C++ 木材加工