C/C++ tip: How to detect the operating system type using compiler predefined macros
2013-11-07 11:53
1111 查看
转自:http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system#OSXiOSandDarwin
OS identification macros are predefined by all C/C++ compilers to enable
How to detect the operating system type
AIX
BSD
HP-UX
Linux
OSX, iOS, and Darwin
Solaris
Windows with Cygwin (POSIX)
Windows, Cygwin (non-POSIX), and MinGW
How to detect POSIX and UNIX
POSIX
UNIX
Other ways to detect the operating system type
Further reading
Related articles at NadeauSoftware.com
Web articles
Green text indicates recommended macros that are well-supported and useful for detecting a specific OS.
AIX
Notes:See IBM's notes on Using the GNU C/C++ compiler on AIX.
BSD
Notes:Compilers for the old BSD base for these distributions defined the
Apple's OSX for the Mac and iOS for iPhones and iPads are based in part on a fork of FreeBSD distributed as Darwin. As such, OSX and iOS also define the
HP-UX
Linux
Notes:Linux is available for a wide variety of processors, but it is primarily used on x86 and x86-64 processors. The above table's compilers are all for these processors. Some of them may not be available for other processors.
There are no predefined compiler macros indicating the specific Linux distribution. At run-time you can read
Linux is POSIX compliant and defines the standard
OSX and Darwin
iOS
Notes:For Apple's OSes, all compilers define
All OSX compilers are available from the command-line. Apple's Xcode IDE can be configured to invoke any of them from the GUI.
Mac OSX and iOS include BSD UNIX components originally from FreeBSD. The open source parts of Mac OSX and iOS are distributed as Darwin, without Apple's proprietary user interface and tools. Despite being UNIX-like, Mac OSX and iOS compilers do not define the conventional
Some on-line lists of compiler macros (like this one) list
Some lists (like this one) still include
Some forum advice and books (like this one) claim that the
OSX and iOS compilers do not define macros to distinguish between OSX and iOS. However, Apple's
Note that the above macros are not mutually exclusive:
There are no macros to distinguish at compile time between an iPhone, iPad, or other Apple devices using the same OSes.
Solaris
Notes:To conform with long-standing convention, Solaris compilers define
Oracle compilers do not define an "oracle" macro or a "solaris" macro.
Checking for
Cygwin building for POSIX
Notes:Cygwin provides a POSIX development environment for Windows, including shells, command-line tools, and compilers. Using Cygwin's libraries, POSIX applications can be built and run under Windows without any Windows-specific code.
Cygwin POSIX libraries are 32-bit-only, so 64-bit POSIX applications cannot be built. Some code found on-line references
Clang/LLVM and GCC both can build POSIX or Windows applications. The table above shows macros when building POSIX applications. See the Windows section later in this article for macros when building Windows applications. Comparing the macro set for both types of applications note that
Checking for Cygwin POSIX builds probably isn't necessarily at all. The whole point of Cygwin is to run standard POSIX applications under Windows, so checking for Cygwin explicitly shouldn't be needed.
Intel's compilers are not supported under Cygwin, but users have hacked running them from a Cygwin bash command line. However, the compilers still build Windows applications, not POSIX applications.
Portland Group's compilers for Windows come with a Cygwin install that enables the compilers to be run from a bash command-line, but they still build Windows applications, not POSIX applications.
Windows
Notes:Clang/LLVM and GCC under Windows run within the Cygwin POSIX environment or the MinGW minimal GNU environment. Both provide a bash shell and assorted command-line utilities. Cygwin also provides POSIX libraries while MinGW does not.
Based on command-line options, the Clang/LLVM and GCC compilers can build Windows applications or POSIX applications that run under Windows using POSIX compatibility libraries. Predefined macros for POSIX applications are described in the previous section of this article. The table above is strictly for compiling Windows applications.
Clang/LLVM can build Windows applications using the Windows target (e.g. "
GCC under Cygwin can build Windows applications using the "
Oddly enough, GCC under Cygwin predefines UNIX macros even when building Windows applications.
Some on-line code references
GCC under MinGW can build Windows applications using the "
While Clang/LLVM, GCC, and Portland Group compilers define a lot of WIN32 and WIN64 macros with various numbers of underscores, the only macros that matter are those that are compatible with Microsoft's Visual Studio:
Some on-line advice recommends checking for
Some lists of predefined macros (like this one) include additional macros for discontinued products, such as
The latest POSIX.1-2008 specification does not have a well-defined version number for the
{
/* POSIX.1-2008 */
}
else
{
/* Pre-POSIX.1-2008 */
}While the
UNIX (Clang/LLVM compilers)
UNIX (GCC compilers)
UNIX (Other compilers)
Notes:There is no single UNIX macro defined by all compilers on all UNIX-style OSes. An
Compilers for Apple's OSX and iOS don't define any UNIX macros. An
GCC under Cygwin defines UNIX macros even when building Windows applications. An
C/C++ tip: How to detect the compiler name and version using compiler predefined macros provides
C/C++ tip: How to detect the processor type using compiler predefined macros provides
Pre-defined C/C++ Compiler Macros at beefchunk.com has a list of OSes and predefined macros. Like the Sourceforge list, the information is a bit cluttered with obsolete OSes (DG/UX? Unicos?) and lacks discussion.
Operating System Resources at Apache.org has a good list of OSes, links to vendor documentation, and some tables of compiler predefined macros.
OS identification macros are predefined by all C/C++ compilers to enable
#if/#endifsets to wrap OS-specific code. This is often necessary in cross-platform code that must use low-level library functions for fast disk I/O, inter-process communications, or threads. While differences between Windows and other OSes are acute, even differences among UNIX-style OSes can require
#if/#endifconstructs.This article surveys common compilers and shows how to use predefined macros to detect common OSes at compile time.
Table of Contents
How to list predefined macrosHow to detect the operating system type
AIX
BSD
HP-UX
Linux
OSX, iOS, and Darwin
Solaris
Windows with Cygwin (POSIX)
Windows, Cygwin (non-POSIX), and MinGW
How to detect POSIX and UNIX
POSIX
UNIX
Other ways to detect the operating system type
Further reading
Related articles at NadeauSoftware.com
Web articles
How to list predefined macros
See How to list compiler predefined macros for instructions on getting a list of macros for the compilers referenced here.How to detect the operating system type
Throughout the following sections note:Red text indicates deprecated macros that don't start with an underscore. C++ compilers, and C compilers in standards compliance mode, do not define them.Green text indicates recommended macros that are well-supported and useful for detecting a specific OS.
AIX
Developer: | IBM |
Distributions: | AIX |
Processors: | POWER |
#if defined(_AIX) /* IBM AIX. ------------------------------------------------- */ #endif
Macro | GNU GCC/G++ | IBM XL C/C++ |
---|---|---|
_AIX | yes | yes |
__unix | yes | |
__unix__ | yes | yes |
BSD
Developer: | Open source |
Distributions: | DragonFly BSD, FreeBSD, OpenBSD, NetBSD |
Processors: | x86, x86-64, Itanium, POWER, SPARC, etc. |
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) #include <sys/param.h> #if defined(BSD) /* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD). ----------- */ #endif #endif
Macro | Clang/LLVM | GNU GCC/G++ | |||||
---|---|---|---|---|---|---|---|
DragonFly BSD | FreeBSD | NetBSD | OpenBSD | FreeBSD | NetBSD | OpenBSD | |
unix | yes | yes | yes | yes | |||
__unix | yes | yes | yes | yes | |||
__unix__ | yes | yes | yes | yes | yes | yes | yes |
__DragonFly__ | yes | ||||||
__FreeBSD__ | yes | yes | |||||
__NetBSD__ | yes | yes | |||||
__OpenBSD__ | yes | yes |
__bsdi__macro, but none of these distributions define it now. This leaves no generic "BSD" macro defined by the compiler itself, but all UNIX-style OSes provide a
<sys/param.h>file. On BSD distributions, and only on BSD distributions, this file defines a
BSDmacro that's set to the OS version. Checking for this generic macro is more robust than looking for known BSD distributions with
__DragonFly__,
__FreeBSD__,
__NetBSD__, and
__OpenBSD__macros.
Apple's OSX for the Mac and iOS for iPhones and iPads are based in part on a fork of FreeBSD distributed as Darwin. As such, OSX and iOS also define the
BSDmacro within
<sys/param.h>. However, compilers for OSX, iOS, and Darwin do not define
__unix__. To detect all BSD OSes, including OSX, iOS, and Darwin, use an
#if/#endifthat checks for
__unix__along with
__APPLE__and
__MACH__(see the later section on OSX and iOS).
HP-UX
Developer: | Hewlett-Packard |
Distributions: | HP-UX |
Processors: | Itanium |
#if defined(__hpux) /* Hewlett-Packard HP-UX. ----------------------------------- */ #endif
Macro | GNU GCC/G++ | HP C/aC++ |
---|---|---|
hpux | yes | |
__hpux | yes | yes |
unix | yes | |
__unix | yes | yes |
__unix__ | yes |
Linux
Developer: | Open source |
Distributions: | Centos, Debian, Fedora, OpenSUSE, RedHat, Ubuntu |
Processors: | x86, x86-64, POWER, etc. |
#if defined(__linux__) /* Linux. --------------------------------------------------- */ #endif
Macro | Clang/LLVM | GNU GCC/G++ | Intel ICC/ICPC | Oracle Solaris Studio | Portland PGCC/PGCPP | IBM XL C/C++ |
---|---|---|---|---|---|---|
linux | yes | yes | yes | yes | yes | |
__linux | yes | yes | yes | yes | yes | yes |
__linux__ | yes | yes | yes | yes | yes | yes |
__gnu_linux | yes | yes | yes | yes | ||
unix | yes | yes | yes | yes | yes | |
__unix | yes | yes | yes | yes | yes | yes |
__unix__ | yes | yes | yes | yes | yes | yes |
There are no predefined compiler macros indicating the specific Linux distribution. At run-time you can read
/proc/versionto get the distribution name and version, or invoke
uname -afrom a
Makefilethen set your own macro. However, writing Linux distribution-specific code is rarely necessary due to high compatibility between distributions.
Linux is POSIX compliant and defines the standard
_POSIX*macros in
<unistd.h>. While Linux is compliant with the latest POSIX.1-2008 specification, Linux distributions erroneously set
_POSIX_VERSIONto
200809L, instead of leaving it set to
200112L, as required by the POSIX specification. In practice, this is not a big issue since the existence, not value, of the
_POSIX_VERSIONmacro is sufficient to detect POSIX compliance. After that, the individual
_POSIX_*feature macros provide better information about which specific POSIX features are implemented (see later in this article for POSIX discussion).
OSX, iOS, and Darwin
Developer: | Apple and open source |
Distributions: | OSX, iOS, Darwin |
Processors: | x86, x86-64, ARM |
#if defined(__APPLE__) && defined(__MACH__) /* Apple OSX and iOS (Darwin). ------------------------------ */ #include <TargetConditionals.h> #if TARGET_IPHONE_SIMULATOR == 1 /* iOS in Xcode simulator */ #elif TARGET_OS_IPHONE == 1 /* iOS on iPhone, iPad, etc. */ #elif TARGET_OS_MAC == 1 /* OSX */ #endif #endif
Macro | Clang/LLVM | GNU GCC/G++ | Intel ICC/ICPC | Portland PGCC/PGCPP |
---|---|---|---|---|
__APPLE__ | yes | yes | yes | yes |
__MACH__ | yes | yes | yes | yes |
Macro | Clang/LLVM | GNU GCC/G++ |
---|---|---|
__APPLE__ | yes | yes |
__MACH__ | yes | yes |
__APPLE__and
__MACH__macros. The
__MACH__macro indicates the MACH kernel at the heart of OSX/iOS and partially derived from the obsoleteNeXTSTEP. For rigor, both of these macros must be defined to detect OSX/iOS. If only
__MACH__is defined, the OS is NeXTSTEP or one of the other OSes derived from the MACH kernel.
All OSX compilers are available from the command-line. Apple's Xcode IDE can be configured to invoke any of them from the GUI.
Mac OSX and iOS include BSD UNIX components originally from FreeBSD. The open source parts of Mac OSX and iOS are distributed as Darwin, without Apple's proprietary user interface and tools. Despite being UNIX-like, Mac OSX and iOS compilers do not define the conventional
__unix__,
__unix, or
unixmacros. They do define the
BSDmacro in
<sys/param.h>(see laterdiscussion about BSD).
Some on-line lists of compiler macros (like this one) list
__MACOSX__. Some forum comments (like these) claim
__OSX__exists. These are incorrect. There are no such macros predefined by OSX compilers, but they may be defined by specific project Makefiles and platform-detector scripts like GNU
autoconf.
Some lists (like this one) still include
macintoshor
Macintoshmacros. These were only available on the obsolete Mac OS 9 discontinued back in 2002.
Some forum advice and books (like this one) claim that the
__APPLE__macro is only defined by Apple's own compilers. This is incorrect. While it's true that compilers distributed by Apple define this macro, so do OSX distributions of Intel's ICC, the old IBM XL for PowerPC, and the latest direct downloads of Clang and GCC from open source web sites.
OSX and iOS compilers do not define macros to distinguish between OSX and iOS. However, Apple's
<TargetConditionals.h>in each platform's SDK provides
TARGET_*macros that indicate the OS. All of the macros exist for all platforms, but their values change between
0and
1flags as follows:
Mac OSX | iOS | iOS Simulator | |
---|---|---|---|
TARGET_OS_EMBEDDED | 0 | 1 | 0 |
TARGET_OS_IPHONE | 0 | 1 | 1 |
TARGET_OS_MAC | 1 | 1 | 1 |
TARGET_IPHONE_SIMULATOR | 0 | 0 | 1 |
TARGET_OS_MACis set to
1for all platforms, and
TARGET_OS_IPHONEis
1for iOS and the simulator. To detect OSX vs. iOS vs. the iOS simulator you have to check the macro values in a specific order (see below).
There are no macros to distinguish at compile time between an iPhone, iPad, or other Apple devices using the same OSes.
Solaris
Developer: | Oracle and open source |
Distributions: | Oracle Solaris, Open Indiana |
Processors: | x86, x86-64, SPARC |
#if defined(__sun) && defined(__SVR4) /* Solaris. ------------------------------------------------- */ #endif
Macro | Clang/LLVM | GNU GCC/G++ | Oracle Solaris Studio |
---|---|---|---|
sun | yes | yes | yes |
__sun | yes | yes | yes |
__sun__ | yes | yes | |
__SunOS | yes | ||
__svr4__ | yes | yes | |
__SVR4 | yes | yes | yes |
unix | yes | yes | yes |
__unix | yes | yes | yes |
__unix__ | yes | yes |
__sunand
sun, despite Oracle's acquisition of Sun Microsystems in 2010. Clang and GCC also define
__sun__, but Solaris Studio does not.
Oracle compilers do not define an "oracle" macro or a "solaris" macro.
Checking for
__sunis not sufficient to identify Solaris. Compilers for the obsolete BSD-based SunOS also defined
__sun(and Solaris Studio still defines
__SunOS, even on System V-based Solaris). To identify Solaris specifically, the
__sunand
__SVR4macros must be defined. Also note that you need to check for upper-case
__SVR4instead of the lower-case
__svr4that's only defined by GCC and not by Solaris Studio.
Windows with Cygwin (POSIX)
Developer: | Open source |
Distributions: | Cygwin |
Processors: | x86 |
#if defined(__CYGWIN__) && !defined(_WIN32) /* Cygwin POSIX under Microsoft Windows. -------------------- */ #endif
Macro | Clang/LLVM | GNU GCC/G++ |
---|---|---|
__CYGWIN__ | yes | yes |
__CYGWIN32__ | yes | yes |
unix | yes | yes |
__unix | yes | yes |
__unix__ | yes | yes |
Cygwin POSIX libraries are 32-bit-only, so 64-bit POSIX applications cannot be built. Some code found on-line references
__CYGWIN64__. However, there is no 64-bit Cygwin, so this macro is never defined. It exists only in forum discussions about a possible future 64-bit Cygwin.
Clang/LLVM and GCC both can build POSIX or Windows applications. The table above shows macros when building POSIX applications. See the Windows section later in this article for macros when building Windows applications. Comparing the macro set for both types of applications note that
__CYGWIN__and the standard
__unix__macros are always defined by GCC, even when building a Windows application. For this reason, detecting POSIX builds under Cygwin must use an
#if/#endifthat checks that
__CYGWIN__is defined, but
_WIN32is not.
Checking for Cygwin POSIX builds probably isn't necessarily at all. The whole point of Cygwin is to run standard POSIX applications under Windows, so checking for Cygwin explicitly shouldn't be needed.
Intel's compilers are not supported under Cygwin, but users have hacked running them from a Cygwin bash command line. However, the compilers still build Windows applications, not POSIX applications.
Portland Group's compilers for Windows come with a Cygwin install that enables the compilers to be run from a bash command-line, but they still build Windows applications, not POSIX applications.
Windows, Cygwin (non-POSIX), and MinGW
Developer: | Microsoft |
Distributions: | Windows XP, Vista, 7, 8 |
Processors: | x86, x86-64 |
#if defined(_WIN64) /* Microsoft Windows (64-bit). ------------------------------ */ #elif defined(_WIN32) /* Microsoft Windows (32-bit). ------------------------------ */ #endif
Macro | Clang/LLVM (Windows target) | Clang/LLVM (MinGW target) | GNU GCC/G++ (Windows target) | GNU GCC/G++ (MinGW target) | Intel ICC/ICPC | Portland PGCC/PGCPP | Microsoft Visual Studio | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
32-bit | 64-bit | 32-bit | 64-bit | 32-bit | 32-bit | 64-bit | 32-bit | 64-bit | 32-bit | 64-bit | 32-bit | 64-bit | |
__CYGWIN__ | yes | ||||||||||||
__CYGWIN32__ | yes | ||||||||||||
__MINGW32__ | yes | yes | yes | yes | |||||||||
__MINGW64__ | yes | yes | |||||||||||
unix | yes | ||||||||||||
__unix | yes | ||||||||||||
__unix__ | yes | ||||||||||||
WIN32 | yes | yes | yes | yes | |||||||||
_WIN32 | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
__WIN32 | yes | yes | yes | yes | yes | yes | |||||||
__WIN32__ | yes | yes | yes | yes | yes | yes | |||||||
WIN64 | yes | yes | |||||||||||
_WIN64 | yes | yes | yes | yes | yes | yes | |||||||
__WIN64 | yes | yes | yes | ||||||||||
__WIN64__ | yes | yes | yes | ||||||||||
WINNT | yes | yes | yes | yes | |||||||||
__WINNT | yes | yes | yes | ||||||||||
__WINNT__ | yes | yes | yes |
Based on command-line options, the Clang/LLVM and GCC compilers can build Windows applications or POSIX applications that run under Windows using POSIX compatibility libraries. Predefined macros for POSIX applications are described in the previous section of this article. The table above is strictly for compiling Windows applications.
Clang/LLVM can build Windows applications using the Windows target (e.g. "
-ccc-host-triple i386-pc-win32") or the MinGW target (e.g. "
-ccc-host-triple i386-pc-mingw32"). The "
-m32" option builds 32-bit applications and "
-m64" builds 64-bit.
GCC under Cygwin can build Windows applications using the "
-mwin32" command-line option. While GCC is capable of building 64-bit applications, Cygwin is 32-bit only and the version of GCC included with it only builds 32-bit applications.
Oddly enough, GCC under Cygwin predefines UNIX macros even when building Windows applications.
Some on-line code references
__CYGWIN64__. Since there is no 64-bit Cygwin, this macro is never defined. It exists only in forum discussions about a possible future 64-bit Cygwin.
GCC under MinGW can build Windows applications using the "
-mwin32" command-line option. The "
-m32" and "
-m64" options build 32-bit and 64-bit applications.
While Clang/LLVM, GCC, and Portland Group compilers define a lot of WIN32 and WIN64 macros with various numbers of underscores, the only macros that matter are those that are compatible with Microsoft's Visual Studio:
_WIN32and
_WIN64.
Some on-line advice recommends checking for
_MSC_VER. The macro is defined with the compiler version number for Clang/LLVM, ICC, and Visual Studio, but it isn't defined by GCC or Portland Group compilers.
Some lists of predefined macros (like this one) include additional macros for discontinued products, such as
__TOS_WIN__for IBM's XL compiler on Windows (XL is still available for AIX and Linux), and
__WINDOWS__for the discontinued but open sourced Watcom compiler.
How to detect POSIX and UNIX
POSIX and UNIX are not operating systems. Rather they are formal or de facto standards followed to some degree by all UNIX-style OSes.POSIX
Developer: | Standard |
Distributions: | All current UNIX-style OSes, including BSD, Linux, OSX, and Solaris |
Processors: | x86, x86-64, ARM, POWER, SPARC, etc. |
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) /* UNIX-style OS. ------------------------------------------- */ #include <unistd.h> #if defined(_POSIX_VERSION) /* POSIX compliant */ #endif #endifAll UNIX-style OSes (see also UNIX below) have
<unistd.h>that defines macros indicating the level of POSIX compliance. The
_POSIX_VERSIONmacro value indicates the version of the standard with which the OS is compliant. Known values are:
198808Lfor POSIX.1-1988
199009Lfor POSIX.1-1990
199506Lfor ISO POSIX.1-1996
200112Lfor ISO POSIX.1-2001
The latest POSIX.1-2008 specification does not have a well-defined version number for the
_POSIX_VERSIONmacro. However, some Linux distributions erroneously assign
_POSIX_VERSIONa value of
200809Linstead of leaving it at
200112L, as required by the POSIX specification.From the POSIX specification, the preferred way to detect ISO POSIX.1-2008 compliance is with a run-time check using
sysconf.if ( sysconf( _SC_VERSION ) >= 200809L )
{
/* POSIX.1-2008 */
}
else
{
/* Pre-POSIX.1-2008 */
}While the
#if/#endifand
sysconfcall above will both work to detect broad POSIX compliance, it's more useful to check for individual POSIX features flagged by macros in
<unistd.h>. The POSIX specification has a long list of these macros, but a few of the more useful ones include:
_POSIX_IPV6indicates IPv6 address support.
_POSIX_MAPPED_FILESindicates memory mapping support.
_POSIX_SEMAPHORESindicates semaphore support for multi-threading.
_POSIX_THREADSindicates pthreads support. A number of
_POSIX_THREAD* macros then indicate whether thread resource usage can be reported or thread scheduling priority controlled.
UNIX
Developer: | De facto standard |
Distributions: | All current UNIX-style OSes, including BSD, Linux, OSX, and Solaris |
Processors: | x86, x86-64, ARM, POWER, SPARC, etc. |
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) /* UNIX-style OS. ------------------------------------------- */ #endif
Macro | Cygwin (POSIX) | DragonFly BSD | FreeBSD | iOS | Linux | NetBSD | OpenBSD | OSX | Solaris |
---|---|---|---|---|---|---|---|---|---|
unix | yes | yes | yes | yes | yes | yes | |||
__unix | yes | yes | yes | yes | yes | yes | |||
__unix__ | yes | yes | yes | yes | yes | yes | yes |
Macro | AIX | Cygwin (POSIX) | FreeBSD | iOS | HP-UX | Linux | NetBSD | OpenBSD | OSX | Solaris |
---|---|---|---|---|---|---|---|---|---|---|
unix | yes | yes | yes | yes | yes | |||||
__unix | yes | yes | yes | yes | yes | |||||
__unix__ | yes | yes | yes | yes | yes | yes | yes | yes |
AIX | HP-UX | Linux | OSX | Solaris | |||||
---|---|---|---|---|---|---|---|---|---|
Macro | IBM XL C/C++ | HP C/aC++ | Intel ICC/ICPC | Oracle Solaris Studio | Portland PGCC/PGCPP | IBM XL C/C++ | Intel ICC/ICPC | Portland PGCC/PGCPP | Oracle Solaris Studio |
unix | yes | yes | yes | yes | |||||
__unix | yes | yes | yes | yes | yes | yes | yes | ||
__unix__ | yes | yes | yes | yes | yes |
#if/#endifthat checks multiple macros is required.
Compilers for Apple's OSX and iOS don't define any UNIX macros. An
#if/#endifthat checks
__APPLE__and
__MACH__is required (see the earlier section OSX and iOS).
GCC under Cygwin defines UNIX macros even when building Windows applications. An
#if/#endifthat excludes
_WIN32is required to detect UNIX builds on Cygwin (see the earlier section on Windows).
Other ways to detect the operating system type
On UNIX-style OSes a common way to detect OS features is to use GNU'sautoconf. This tool builds configuration shell scripts that automatically check for OS and compiler features, build Makefiles, and set compiler flags. For code that only targets UNIX-style OSes, this works well. But
autoconfdoesn't work for code that must compile on non-UNIX-style OSes (e.g. Windows) or within an IDE. And it's way overkill for many projects where a simple
#if/#endifset will do.From the command line there are several ways to detect the OS. On UNIX-style OSes, the
unamecommand reports the OS name. On Windows, the
verand
winvercommands report the OS name. On Linux, the
/proc/versionvirtual file reports the Linux kernel version. But using any of these to automatically configure code requires scripts and Makefiles. And those have the same problems as
autoconf.The most elegant solution is to eschew all detection scripts and simply use the above predefined macros already available on every OS and designed specifically for use in
#if/#endifsets for OS-specific code. Don't reinvent the wheel.
Further reading
Related articles at NadeauSoftware.com
C/C++ tip: How to list compiler predefined macros explains how to get a compiler's macros by using command-line options and other methods.C/C++ tip: How to detect the compiler name and version using compiler predefined macros provides
#if/#endifsets for detecting common compilers.
C/C++ tip: How to detect the processor type using compiler predefined macros provides
#if/#endifsets for detecting desktop and server processors using compiler macros.
Web articles
Operating Systems at Sourceforge.net provides a list of OSes and their compiler predefined macros. However the list is cluttered with obsolete OSes (OS/2? Palm OS?), doesn't note macros shared across many OSes (like__unix__), and doesn't include discussion.
Pre-defined C/C++ Compiler Macros at beefchunk.com has a list of OSes and predefined macros. Like the Sourceforge list, the information is a bit cluttered with obsolete OSes (DG/UX? Unicos?) and lacks discussion.
Operating System Resources at Apache.org has a good list of OSes, links to vendor documentation, and some tables of compiler predefined macros.
相关文章推荐
- C/C++ 50名优秀网站和网页清单
- 比较Java和C++的几个修饰符
- 【VC】 获取电脑USB设备VID和PID等信息。
- C与C++
- VC++6.0调试篇:远程调试
- vs2010做的vc++源程序上传的瘦身
- c++重写、重载、重定义
- hdoj-2107、2105 水~~~
- C++ 引用调用和引用返回可以大大增加程序运行效率
- 在C++中使用TinyXML2解析xml
- [转载]在Android C/C++层添加LOG调试
- [C++ Primer] 第七章的若干问题
- 【全文完】【Deep C (and C++)】深入理解C/C++(4)
- 【Deep C (and C++)】深入理解C/C++(3)
- 【Deep C (and C++)】深入理解C/C++(2)
- 【Deep C (and C++)】深入理解C/C++(1)
- C++深拷贝和浅拷贝
- C++智能指针
- C++ STL Vector
- 有关C++多态的讨论