2025年3月28日 星期五 甲辰(龙)年 月廿七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 编译原理

区分编译器不同版本、不同操作系统的宏

时间:03-25来源:作者:点击数:68

在编写跨平台的代码时,我们往往需要用到条件编译的宏,以便让同一套代码兼容编译器不同版本、不同操作系统,下面就介绍下这些宏。

区分编译器不同版本的宏

每个编译器都会自带一些预定义宏,以下拿gcc和VC++举例:

在编译器众多的预定义宏中,肯定有一个是用于标识编译器版本的宏定义:

  • GCC编译器:__GNUC__
  • Visual C++编译器:_MSC_VER

__GNUC__是用来定义gcc编译器的版本,我们可以使用如下代码来进行条件编译:

  • /* Test for GCC > 3.2.0 */
  • #if __GNUC__ > 3 || \
  • (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
  • (__GNUC_MINOR__ == 2 && \
  • __GNUC_PATCHLEVEL__ > 0))
  • Another approach is to use the predefined macros to calculate a single number, then compare that against a threshold:
  • #define GCC_VERSION (__GNUC__ * 10000 \
  • + __GNUC_MINOR__ * 100 \
  • + __GNUC_PATCHLEVEL__)
  • /* Test for GCC > 3.2.0 */
  • #if GCC_VERSION > 30200

_MSC_VER是微软公司推出的C/C++编译器在ANSI/ISO C99标准之外扩展的宏定义,用来定义当前微软公司自己的编译器的主版本。下面是一些编译器版本的_MSC_VER值:

  • MSVC++ 14.1 _MSC_VER == 1910 (Visual Studio 2017)
  • MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
  • MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
  • MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
  • MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
  • MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
  • MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
  • MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
  • MSVC++ 7.0 _MSC_VER == 1300
  • MSVC++ 6.0 _MSC_VER == 1200
  • MSVC++ 5.0 _MSC_VER == 1100

其中MS VC++ 14.0表示Visual C++的版本为14.0,后面括号中的Visual Studio 2015,表明该VC++包含在微软开发工具Visual Studio 2015中。

  • /* Test for MSVC++ > Microsoft Visual Studio 2010 */
  • #if _MSC_VER > 1600

区分不同操作系统的宏

可以参考QtCore/qsystemdetection.h文件:

  • #ifndef QSYSTEMDETECTION_H
  • #define QSYSTEMDETECTION_H
  • /*
  • The operating system, must be one of: (Q_OS_x)
  • DARWIN - Any Darwin system
  • MAC - OS X and iOS
  • OSX - OS X
  • IOS - iOS
  • MSDOS - MS-DOS and Windows
  • OS2 - OS/2
  • OS2EMX - XFree86 on OS/2 (not PM)
  • WIN32 - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008)
  • WINCE - WinCE (Windows CE 5.0)
  • WINRT - WinRT (Windows 8 Runtime)
  • CYGWIN - Cygwin
  • SOLARIS - Sun Solaris
  • HPUX - HP-UX
  • ULTRIX - DEC Ultrix
  • LINUX - Linux [has variants]
  • FREEBSD - FreeBSD [has variants]
  • NETBSD - NetBSD
  • OPENBSD - OpenBSD
  • BSDI - BSD/OS
  • IRIX - SGI Irix
  • OSF - HP Tru64 UNIX
  • SCO - SCO OpenServer 5
  • UNIXWARE - UnixWare 7, Open UNIX 8
  • AIX - AIX
  • HURD - GNU Hurd
  • DGUX - DG/UX
  • RELIANT - Reliant UNIX
  • DYNIX - DYNIX/ptx
  • QNX - QNX [has variants]
  • QNX6 - QNX RTP 6.1
  • LYNX - LynxOS
  • BSD4 - Any BSD 4.4 system
  • UNIX - Any UNIX BSD/SYSV system
  • ANDROID - Android platform
  • HAIKU - Haiku
  • The 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 systems
  • QNX - both Q_OS_QNX and Q_OS_BLACKBERRY are defined when building for Blackberry 10
  • - only Q_OS_QNX is defined if building for other QNX targets
  • FREEBSD - 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
  • */
  • #if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
  • # define Q_OS_DARWIN
  • # define Q_OS_BSD4
  • # ifdef __LP64__
  • # define Q_OS_DARWIN64
  • # else
  • # define Q_OS_DARWIN32
  • # endif
  • #elif defined(ANDROID)
  • # define Q_OS_ANDROID
  • # define Q_OS_LINUX
  • #elif defined(__CYGWIN__)
  • # define Q_OS_CYGWIN
  • #elif !defined(SAG_COM) && (!defined(WINAPI_FAMILY) || WINAPI_FAMILY==WINAPI_FAMILY_DESKTOP_APP) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
  • # define Q_OS_WIN32
  • # define Q_OS_WIN64
  • #elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
  • # if defined(WINCE) || defined(_WIN32_WCE)
  • # define Q_OS_WINCE
  • # elif defined(WINAPI_FAMILY)
  • # if defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
  • # define Q_OS_WINPHONE
  • # define Q_OS_WINRT
  • # elif WINAPI_FAMILY==WINAPI_FAMILY_APP
  • # define Q_OS_WINRT
  • # else
  • # define Q_OS_WIN32
  • # endif
  • # else
  • # define Q_OS_WIN32
  • # endif
  • #elif defined(__sun) || defined(sun)
  • # define Q_OS_SOLARIS
  • #elif defined(hpux) || defined(__hpux)
  • # define Q_OS_HPUX
  • #elif defined(__ultrix) || defined(ultrix)
  • # define Q_OS_ULTRIX
  • #elif defined(sinix)
  • # define Q_OS_RELIANT
  • #elif defined(__native_client__)
  • # define Q_OS_NACL
  • #elif defined(__linux__) || defined(__linux)
  • # define Q_OS_LINUX
  • #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
  • # ifndef __FreeBSD_kernel__
  • # define Q_OS_FREEBSD
  • # endif
  • # define Q_OS_FREEBSD_KERNEL
  • # define Q_OS_BSD4
  • #elif defined(__NetBSD__)
  • # define Q_OS_NETBSD
  • # define Q_OS_BSD4
  • #elif defined(__OpenBSD__)
  • # define Q_OS_OPENBSD
  • # define Q_OS_BSD4
  • #elif defined(__bsdi__)
  • # define Q_OS_BSDI
  • # define Q_OS_BSD4
  • #elif defined(__sgi)
  • # define Q_OS_IRIX
  • #elif defined(__osf__)
  • # define Q_OS_OSF
  • #elif defined(_AIX)
  • # define Q_OS_AIX
  • #elif defined(__Lynx__)
  • # define Q_OS_LYNX
  • #elif defined(__GNU__)
  • # define Q_OS_HURD
  • #elif defined(__DGUX__)
  • # define Q_OS_DGUX
  • #elif defined(__QNXNTO__)
  • # define Q_OS_QNX
  • #elif defined(_SEQUENT_)
  • # define Q_OS_DYNIX
  • #elif defined(_SCO_DS) /* SCO OpenServer 5 + GCC */
  • # define Q_OS_SCO
  • #elif defined(__USLC__) /* all SCO platforms + UDK or OUDK */
  • # define Q_OS_UNIXWARE
  • #elif defined(__svr4__) && defined(i386) /* Open UNIX 8 + GCC */
  • # define Q_OS_UNIXWARE
  • #elif defined(__INTEGRITY)
  • # define Q_OS_INTEGRITY
  • #elif defined(VXWORKS) /* there is no "real" VxWorks define - this has to be set in the mkspec! */
  • # define Q_OS_VXWORKS
  • #elif defined(__HAIKU__)
  • # define Q_OS_HAIKU
  • #elif defined(__MAKEDEPEND__)
  • #else
  • # error "Qt has not been ported to this OS - see http://www.qt-project.org/"
  • #endif
  • #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
  • # define Q_OS_WIN
  • #endif
  • #if defined(Q_OS_DARWIN)
  • # define Q_OS_MAC
  • # if defined(Q_OS_DARWIN64)
  • # define Q_OS_MAC64
  • # elif defined(Q_OS_DARWIN32)
  • # define Q_OS_MAC32
  • # endif
  • # include <TargetConditionals.h>
  • # if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
  • # define Q_OS_IOS
  • # elif defined(TARGET_OS_MAC) && TARGET_OS_MAC
  • # define Q_OS_OSX
  • # define Q_OS_MACX // compatibility synonym
  • # endif
  • #endif
  • #if defined(Q_OS_WIN)
  • # undef Q_OS_UNIX
  • #elif !defined(Q_OS_UNIX)
  • # define Q_OS_UNIX
  • #endif
  • #ifdef Q_OS_DARWIN
  • # include <Availability.h>
  • # include <AvailabilityMacros.h>
  • #
  • # ifdef Q_OS_OSX
  • # if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6
  • # undef __MAC_OS_X_VERSION_MIN_REQUIRED
  • # define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_6
  • # endif
  • # if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
  • # undef MAC_OS_X_VERSION_MIN_REQUIRED
  • # define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
  • # endif
  • # endif
  • #
  • # // Numerical checks are preferred to named checks, but to be safe
  • # // we define the missing version names in case Qt uses them.
  • #
  • # if !defined(__MAC_10_7)
  • # define __MAC_10_7 1070
  • # endif
  • # if !defined(__MAC_10_8)
  • # define __MAC_10_8 1080
  • # endif
  • # if !defined(__MAC_10_9)
  • # define __MAC_10_9 1090
  • # endif
  • # if !defined(__MAC_10_10)
  • # define __MAC_10_10 101000
  • # endif
  • # if !defined(__MAC_10_11)
  • # define __MAC_10_11 101100
  • # endif
  • # if !defined(MAC_OS_X_VERSION_10_7)
  • # define MAC_OS_X_VERSION_10_7 1070
  • # endif
  • # if !defined(MAC_OS_X_VERSION_10_8)
  • # define MAC_OS_X_VERSION_10_8 1080
  • # endif
  • # if !defined(MAC_OS_X_VERSION_10_9)
  • # define MAC_OS_X_VERSION_10_9 1090
  • # endif
  • # if !defined(MAC_OS_X_VERSION_10_10)
  • # define MAC_OS_X_VERSION_10_10 101000
  • # endif
  • # if !defined(MAC_OS_X_VERSION_10_11)
  • # define MAC_OS_X_VERSION_10_11 101100
  • # endif
  • #
  • # if !defined(__IPHONE_4_3)
  • # define __IPHONE_4_3 40300
  • # endif
  • # if !defined(__IPHONE_5_0)
  • # define __IPHONE_5_0 50000
  • # endif
  • # if !defined(__IPHONE_5_1)
  • # define __IPHONE_5_1 50100
  • # endif
  • # if !defined(__IPHONE_6_0)
  • # define __IPHONE_6_0 60000
  • # endif
  • # if !defined(__IPHONE_6_1)
  • # define __IPHONE_6_1 60100
  • # endif
  • # if !defined(__IPHONE_7_0)
  • # define __IPHONE_7_0 70000
  • # endif
  • # if !defined(__IPHONE_7_1)
  • # define __IPHONE_7_1 70100
  • # endif
  • # if !defined(__IPHONE_8_0)
  • # define __IPHONE_8_0 80000
  • # endif
  • # if !defined(__IPHONE_8_1)
  • # define __IPHONE_8_1 80100
  • # endif
  • # if !defined(__IPHONE_8_2)
  • # define __IPHONE_8_2 80200
  • # endif
  • # if !defined(__IPHONE_8_3)
  • # define __IPHONE_8_3 80300
  • # endif
  • # if !defined(__IPHONE_8_4)
  • # define __IPHONE_8_4 80400
  • # endif
  • # if !defined(__IPHONE_9_0)
  • # define __IPHONE_9_0 90000
  • # endif
  • #endif
  • #ifdef __LSB_VERSION__
  • # if __LSB_VERSION__ < 40
  • # error "This version of the Linux Standard Base is unsupported"
  • # endif
  • #ifndef QT_LINUXBASE
  • # define QT_LINUXBASE
  • #endif
  • #endif
  • #endif // QSYSTEMDETECTION_H
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门