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

时间:2022-10-12 16:53:41

I need my code to do different things based on the operating system on which it gets compiled. I'm looking for something like this:

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

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

Is there a way to do this? Is there a better way to do the same thing?

有办法吗?有更好的方法来做同样的事情吗?

13 个解决方案

#1


184  

The Predefined Macros for OS site has a very complete list of checks. Here are a few of them, with links to where they're found:

OS站点的预定义宏有一个非常完整的检查列表。以下是其中的一些,链接到他们找到的地方:

Windows

_WIN32   Both 32 bit and 64 bit
_WIN64   64 bit only

_WIN32位和64位都只有win64位

Unix (Linux, *BSD, Mac OS X)

See this related question on some of the pitfalls of using this check.

请参阅有关使用此检查的一些缺陷的相关问题。

unix
__unix
__unix__

unix __unix __unix__

Mac OS X

__APPLE__
__MACH__

__APPLE__ __MACH__

Both are defined; checking for either should work.

两者都是定义;检查哪一个都可以。

Linux

__linux__
linux Obsolete (not POSIX compliant)
__linux Obsolete (not POSIX compliant)

__linux__ linux已过时(不兼容POSIX) __linux已过时(不兼容POSIX)

FreeBSD

__FreeBSD__

__FreeBSD__

#2


59  

show GCC defines on Windows:

在Windows上显示GCC定义:

gcc -dM -E - <NUL:

on Linux:

在Linux上:

gcc -dM -E - </dev/null

Predefined macros in MinGW:

MinGW预定义的宏:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

on UNIXes:

在unix系统:

unix __unix__ __unix

#3


13  

Based on nadeausoftware and Lambda Fairy's answer.

基于nadeausoftware和Lambda精灵的答案。

#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(__ANDROID__)
    #define PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#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;
}

Tested with GCC and clang on:

用GCC和clang测试:

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

#4


10  

In most cases it is better to check whether a given functionality is present or not. For example: if the function pipe() exists or not.

在大多数情况下,最好检查给定的功能是否存在。例如:如果函数管道()存在或不存在。

#5


7  

#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

#6


5  

MS compiler PreDefined Macros can be found here:

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

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

I think you are looking for:

我想你在寻找:

_WIN32
_WIN64

_WIN32 _WIN64

gcc compiler PreDefined MAcros can be found here:

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

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

I think you are looking for:

我想你在寻找:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__

Do a google for your appropriate compilers pre-defined.

为预定义的适当编译器执行谷歌。

#7


3  

There is no standard macro that is set according to C standard. Some C compilers will set one on some platforms (e.g. Apple's patched GCC sets a macro to indicate that it is compiling on an Apple system and for the Darwin platform). Your platform and/or your C compiler might set something as well, but there is no general way.

没有按照C标准设置的标准宏。一些C编译器会在某些平台上设置一个(例如,苹果修补过的GCC设置了一个宏来表明它是在苹果系统和达尔文平台上编译的)。您的平台和/或C编译器也可以设置一些东西,但是没有通用的方法。

Like hayalci said, it's best to have these macros set in your build process somehow. It is easy to define a macro with most compilers without modifying the code. You can simply pass -D MACRO to GCC, i.e.

正如hayalci所说,最好在构建过程中设置这些宏。在不修改代码的情况下,用大多数编译器定义宏是很容易的。您可以简单地将-D宏传递给GCC,即。

gcc -D Windows
gcc -D UNIX

And in your code:

和在你的代码:

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

#8


3  

On MinGW, the _WIN32 define check isn't working. Here's a solution:

在MinGW中,_WIN32定义检查不起作用。这里有一个解决方案:

#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

For more information please look: https://sourceforge.net/p/predef/wiki/OperatingSystems/

有关更多信息,请参见:https://sourceforge.net/p/predef/wiki/OperatingSystems/

#9


2  

Use #define OSsymbol and #ifdef OSsymbol where OSsymbol is a #define'able symbol identifying your target OS.

使用#define OSsymbol和#ifdef OSsymbol, OSsymbol是一个定义你的目标操作系统的符号。

Typically you would include a central header file defining the selected OS symbol and use OS-specific include and library directories to compile and build.

通常,您将包含一个定义所选OS符号的*头文件,并使用特定于OS的include和库目录进行编译和构建。

You did not specify your development environment, but I'm pretty sure your compiler provides global defines for common platforms and OSes.

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

See also http://en.wikibooks.org/wiki/C_Programming/Preprocessor

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

#10


2  

Just to sum it all up, here are a bunch of helpful links.

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

#11


2  

Sorry for the external reference, but I think it is suited to your question:

不好意思,这是外部参考,但我认为适合你的问题:

C/C++ tip: How to detect the operating system type using compiler predefined macros

C/ c++提示:如何使用编译器预定义宏检测操作系统类型

#12


1  

Some compilers will generate #defines that can help you with this. Read the compiler documentation to determine what they are. MSVC defines one that's __WIN32__, GCC has some you can see with touch foo.h; gcc -dM foo.h

一些编译器将生成可以帮助您实现这一点的#define。阅读编译器文档以确定它们是什么。MSVC定义了一个__WIN32__, GCC有一些你可以在touch foo。h中看到;gcc dm foo。

#13


0  

You can use pre-processor directives as warning or error to check at compile time you don't need to run this program at all just simply compile it .

您可以使用预处理器指令作为警告或错误,在编译时检查您根本不需要运行此程序,只需编译它即可。

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
    #error Windows_OS
#elif defined(__linux__)
    #error Linux_OS
#elif defined(__APPLE__) && defined(__MACH__)
    #error Mach_OS
#elif defined(unix) || defined(__unix__) || defined(__unix)
    #error Unix_OS
#else
    #error Unknown_OS
#endif

#include <stdio.h>
int main(void)
{
    return 0;
}

#1


184  

The Predefined Macros for OS site has a very complete list of checks. Here are a few of them, with links to where they're found:

OS站点的预定义宏有一个非常完整的检查列表。以下是其中的一些,链接到他们找到的地方:

Windows

_WIN32   Both 32 bit and 64 bit
_WIN64   64 bit only

_WIN32位和64位都只有win64位

Unix (Linux, *BSD, Mac OS X)

See this related question on some of the pitfalls of using this check.

请参阅有关使用此检查的一些缺陷的相关问题。

unix
__unix
__unix__

unix __unix __unix__

Mac OS X

__APPLE__
__MACH__

__APPLE__ __MACH__

Both are defined; checking for either should work.

两者都是定义;检查哪一个都可以。

Linux

__linux__
linux Obsolete (not POSIX compliant)
__linux Obsolete (not POSIX compliant)

__linux__ linux已过时(不兼容POSIX) __linux已过时(不兼容POSIX)

FreeBSD

__FreeBSD__

__FreeBSD__

#2


59  

show GCC defines on Windows:

在Windows上显示GCC定义:

gcc -dM -E - <NUL:

on Linux:

在Linux上:

gcc -dM -E - </dev/null

Predefined macros in MinGW:

MinGW预定义的宏:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

on UNIXes:

在unix系统:

unix __unix__ __unix

#3


13  

Based on nadeausoftware and Lambda Fairy's answer.

基于nadeausoftware和Lambda精灵的答案。

#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(__ANDROID__)
    #define PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#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;
}

Tested with GCC and clang on:

用GCC和clang测试:

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

#4


10  

In most cases it is better to check whether a given functionality is present or not. For example: if the function pipe() exists or not.

在大多数情况下,最好检查给定的功能是否存在。例如:如果函数管道()存在或不存在。

#5


7  

#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

#6


5  

MS compiler PreDefined Macros can be found here:

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

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

I think you are looking for:

我想你在寻找:

_WIN32
_WIN64

_WIN32 _WIN64

gcc compiler PreDefined MAcros can be found here:

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

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

I think you are looking for:

我想你在寻找:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__

Do a google for your appropriate compilers pre-defined.

为预定义的适当编译器执行谷歌。

#7


3  

There is no standard macro that is set according to C standard. Some C compilers will set one on some platforms (e.g. Apple's patched GCC sets a macro to indicate that it is compiling on an Apple system and for the Darwin platform). Your platform and/or your C compiler might set something as well, but there is no general way.

没有按照C标准设置的标准宏。一些C编译器会在某些平台上设置一个(例如,苹果修补过的GCC设置了一个宏来表明它是在苹果系统和达尔文平台上编译的)。您的平台和/或C编译器也可以设置一些东西,但是没有通用的方法。

Like hayalci said, it's best to have these macros set in your build process somehow. It is easy to define a macro with most compilers without modifying the code. You can simply pass -D MACRO to GCC, i.e.

正如hayalci所说,最好在构建过程中设置这些宏。在不修改代码的情况下,用大多数编译器定义宏是很容易的。您可以简单地将-D宏传递给GCC,即。

gcc -D Windows
gcc -D UNIX

And in your code:

和在你的代码:

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

#8


3  

On MinGW, the _WIN32 define check isn't working. Here's a solution:

在MinGW中,_WIN32定义检查不起作用。这里有一个解决方案:

#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

For more information please look: https://sourceforge.net/p/predef/wiki/OperatingSystems/

有关更多信息,请参见:https://sourceforge.net/p/predef/wiki/OperatingSystems/

#9


2  

Use #define OSsymbol and #ifdef OSsymbol where OSsymbol is a #define'able symbol identifying your target OS.

使用#define OSsymbol和#ifdef OSsymbol, OSsymbol是一个定义你的目标操作系统的符号。

Typically you would include a central header file defining the selected OS symbol and use OS-specific include and library directories to compile and build.

通常,您将包含一个定义所选OS符号的*头文件,并使用特定于OS的include和库目录进行编译和构建。

You did not specify your development environment, but I'm pretty sure your compiler provides global defines for common platforms and OSes.

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

See also http://en.wikibooks.org/wiki/C_Programming/Preprocessor

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

#10


2  

Just to sum it all up, here are a bunch of helpful links.

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

#11


2  

Sorry for the external reference, but I think it is suited to your question:

不好意思,这是外部参考,但我认为适合你的问题:

C/C++ tip: How to detect the operating system type using compiler predefined macros

C/ c++提示:如何使用编译器预定义宏检测操作系统类型

#12


1  

Some compilers will generate #defines that can help you with this. Read the compiler documentation to determine what they are. MSVC defines one that's __WIN32__, GCC has some you can see with touch foo.h; gcc -dM foo.h

一些编译器将生成可以帮助您实现这一点的#define。阅读编译器文档以确定它们是什么。MSVC定义了一个__WIN32__, GCC有一些你可以在touch foo。h中看到;gcc dm foo。

#13


0  

You can use pre-processor directives as warning or error to check at compile time you don't need to run this program at all just simply compile it .

您可以使用预处理器指令作为警告或错误,在编译时检查您根本不需要运行此程序,只需编译它即可。

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
    #error Windows_OS
#elif defined(__linux__)
    #error Linux_OS
#elif defined(__APPLE__) && defined(__MACH__)
    #error Mach_OS
#elif defined(unix) || defined(__unix__) || defined(__unix)
    #error Unix_OS
#else
    #error Unknown_OS
#endif

#include <stdio.h>
int main(void)
{
    return 0;
}