如何使用预处理器指令检查操作系统?

我需要我的代码根据编译的操作系统做不同的事情。 我正在寻找这样的东西:

#ifdef OSisWindows // do Windows-specific stuff #else // do Unix-specific stuff #endif 

有没有办法做到这一点? 有没有更好的方法来做同样的事情?

预定义的macros网站有一个非常完整的检查列表。 以下是其中的一些内容,包含指向它们的位置的链接:

视窗

_WIN32 32位和64位
_WIN64只有64位

Unix(Linux,* BSD,Mac OS X)

看到这个相关的问题 ,使用这个检查的一些陷阱。

unix
__unix
__unix__

Mac OS X

__APPLE__
__MACH__

两者都有定义; 检查是否应该工作。

Linux的

__linux__
linux
__linux

FreeBSD的

__FreeBSD__

有大多数编译器使用的预定义的macros,你可以在这里find列表。

否则,你必须调整构build系统,以便在编译过程中定义一个像OS_WINDOWS / OS_UNIX这样的macros,然后你必须在代码中使用ifdef来检查它。

 #ifdef OS_WINDOWS // define something for Windows #else // define it for a Unix machine #endif 

在Windows上显示GCC定义:

 gcc -dM -E - <NUL: 

在Linux上:

 gcc -dM -E - </dev/null 

MinGW中预定义的macros:

 WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386 

在UNIX上:

 unix __unix__ __unix 

在大多数情况下,最好检查给定的function是否存在。 例如:如果函数pipe()存在与否。

 #ifdef _WIN32 // do something for windows like include <windows.h> #elif defined __unix__ // do something for unix like include <unistd.h> #elif defined __APPLE__ // do something for mac #endif 

基于nadeausoftware和Lambda Fairy的答案 。

 #include <stdio.h> /** * Determination a platform of an operation system * Fully supported supported only GNU GCC/G++, partially on Clang/LLVM */ #if defined(_WIN32) #define PLATFORM_NAME "windows" // Windows #elif defined(_WIN64) #define PLATFORM_NAME "windows" // Windows #elif defined(__CYGWIN__) && !defined(_WIN32) #define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window) #elif defined(__linux__) #define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other #elif defined(__unix__) || defined(__APPLE__) && defined(__MACH__) #include <sys/param.h> #if defined(BSD) #define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD #endif #elif defined(__hpux) #define PLATFORM_NAME "hp-ux" // HP-UX #elif defined(_AIX) #define PLATFORM_NAME "aix" // IBM AIX #elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) #include <TargetConditionals.h> #if TARGET_IPHONE_SIMULATOR == 1 #define PLATFORM_NAME "ios" // Apple iOS #elif TARGET_OS_IPHONE == 1 #define PLATFORM_NAME "ios" // Apple iOS #elif TARGET_OS_MAC == 1 #define PLATFORM_NAME "osx" // Apple OSX #endif #elif defined(__sun) && defined(__SVR4) #define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana #else #define PLATFORM_NAME NULL #endif // Return a name of platform, if determined, otherwise - an empty string char * get_platform_name() { return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME; } int main(int argc, char *argv[]) { puts(get_platform_name()); return 0; } 

经GCCtesting并在下列条件下进行:

  • Debian 8
  • Windows(MinGW)
  • Windows(Cygwin)

MS编译器预定义的macros可以在这里find:

http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

我想你正在寻找:

_WIN32
_WIN64

gcc编译器预定义的macros可以在这里find:

http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

我想你正在寻找:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

做一个谷歌为您的适当的编译器预先定义。

你可能会觉得这有帮助。 它具有不同编译器在不同平台上设置的各种预定义定义的列表。

没有按照C标准设置的标准macros。 一些C编译器会在某些平台上设置一个(例如,苹果的补丁GCC设置了一个macros,表示它正在Apple系统和Darwin平台上编译)。 你的平台和/或你的C编译器可能会设置一些东西,但是没有一般的方法。

就像hayalci说的那样,最好把这些macros设置在你的构build过程中。 用大多数编译器定义一个macros而不修改代码是很容易的。 您可以简单地传递-D MACRO到GCC,即

 gcc -D Windows gcc -D UNIX 

在你的代码中:

 #if defined(Windows) // do some cool Windows stuff #elif defined(UNIX) // do some cool Unix stuff #else # error Unsupported operating system #endif 

使用#define OSsymbol#ifdef OSsymbol ,其中OSsymbol是一个#define能识别您的目标操作系统的符号。

通常,您将包含一个中央头文件,用于定义所选的OS符号,并使用特定于操作系统的包含和库目录进行编译和构build。

你没有指定你的开发环境,但我很确定你的编译器提供了通用平台和操作系统的全局定义。

另见http://en.wikibooks.org/wiki/C_Programming/Preprocessor

对不起,外部参考,但我认为这是适合你的问题:

C / C ++提示:如何使用编译器预定义的macros来检测操作系统types

一些编译器会生成#defines,可以帮助你做到这一点。 阅读编译器文档以确定它们是什么。 MSVC定义了一个是__WIN32__ , GCC有一些你可以通过touch foo.h; gcc -dM foo.h来看到touch foo.h; gcc -dM foo.h touch foo.h; gcc -dM foo.h

总结一下,这里有一些有用的链接。

  • GCC通用预定义的macros
  • SourceForge预定义的操作系统
  • MSDN预定义的macros
  • 联系在一起的Naudea软件页面
  • 维基百科!
  • SourceForge的“用于标准,编译器,操作系统和硬件体系结构的预定义编译器macros的概述”。
  • FreeBSD的“差异化操作系统”
  • 各种预定义的macros
  • libportable

在MinGW上, _WIN32定义检查不起作用。 这是一个解决scheme:

 #if defined(_WIN32) || defined(__CYGWIN__) // Windows (x86 or x64) // ... #elif defined(__linux__) // Linux // ... #elif defined(__APPLE__) && defined(__MACH__) // Mac OS // ... #elif defined(unix) || defined(__unix__) || defined(__unix) // Unix like OS // ... #else #error Unknown environment! #endif 

欲了解更多信息,请看: https : //sourceforge.net/p/predef/wiki/OperatingSystems/