如何在 C 预处理器中可靠地检测 Mac OS X、iOS、Linux、Windows?

发布于 2024-11-05 18:47:18 字数 79 浏览 2 评论 0原文

如果有一些跨平台 C/C++ 代码需要在 Mac OS X、iOS、Linux、Windows 上编译,我如何在预处理器过程中可靠地检测到它们?

If there's some cross-platform C/C++ code that should be compiled on Mac OS X, iOS, Linux, Windows, how can I detect them reliably during preprocessor process?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

长途伴 2024-11-12 18:47:18

大多数编译器都使用预定义的宏,您可以在此处找到列表。 GCC 编译器预定义宏可以在此处找到。
以下是 gcc 的示例:

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
   //define something for Windows (32-bit and 64-bit, this part is common)
   #ifdef _WIN64
      //define something for Windows (64-bit only)
   #else
      //define something for Windows (32-bit only)
   #endif
#elif __APPLE__
    #include <TargetConditionals.h>
    #if TARGET_IPHONE_SIMULATOR
         // iOS, tvOS, or watchOS Simulator
    #elif TARGET_OS_MACCATALYST
         // Mac's Catalyst (ports iOS API into Mac, like UIKit).
    #elif TARGET_OS_IPHONE
        // iOS, tvOS, or watchOS device
    #elif TARGET_OS_MAC
        // Other kinds of Apple platforms
    #else
    #   error "Unknown Apple platform"
    #endif
#elif __ANDROID__
    // Below __linux__ check should be enough to handle Android,
    // but something may be unique to Android.
#elif __linux__
    // linux
#elif __unix__ // all unices not caught above
    // Unix
#elif defined(_POSIX_VERSION)
    // POSIX
#else
#   error "Unknown compiler"
#endif

定义的宏取决于您要使用的编译器。

_WIN64 #ifdef 可以嵌套到 _WIN32 #ifdef 中,因为 _WIN32 是甚至在针对 Windows x64 版本时定义。如果某些标头包含对于两者都是通用的,这可以防止代码重复
(也不带下划线的 WIN32 允许 IDE 突出显示代码的右侧分区)。

There are predefined macros that are used by most compilers, you can find the list here. GCC compiler predefined macros can be found here.
Here is an example for gcc:

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
   //define something for Windows (32-bit and 64-bit, this part is common)
   #ifdef _WIN64
      //define something for Windows (64-bit only)
   #else
      //define something for Windows (32-bit only)
   #endif
#elif __APPLE__
    #include <TargetConditionals.h>
    #if TARGET_IPHONE_SIMULATOR
         // iOS, tvOS, or watchOS Simulator
    #elif TARGET_OS_MACCATALYST
         // Mac's Catalyst (ports iOS API into Mac, like UIKit).
    #elif TARGET_OS_IPHONE
        // iOS, tvOS, or watchOS device
    #elif TARGET_OS_MAC
        // Other kinds of Apple platforms
    #else
    #   error "Unknown Apple platform"
    #endif
#elif __ANDROID__
    // Below __linux__ check should be enough to handle Android,
    // but something may be unique to Android.
#elif __linux__
    // linux
#elif __unix__ // all unices not caught above
    // Unix
#elif defined(_POSIX_VERSION)
    // POSIX
#else
#   error "Unknown compiler"
#endif

The defined macros depend on the compiler that you are going to use.

The _WIN64 #ifdef can be nested into the _WIN32 #ifdef because _WIN32 is even defined when targeting the Windows x64 version. This prevents code duplication if some header includes are common to both
(also WIN32 without underscore allows IDE to highlight the right partition of code).

朕就是辣么酷 2024-11-12 18:47:18

正如 Jake 指出的,TARGET_IPHONE_SIMULATORTARGET_OS_IPHONE 的子集。

此外,TARGET_OS_IPHONETARGET_OS_MAC 的子集。

因此更好的方法可能是:

#ifdef _WIN64
   //define something for Windows (64-bit)
#elif _WIN32
   //define something for Windows (32-bit)
#elif __APPLE__
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR
        // define something for simulator
        // (although, checking for TARGET_OS_IPHONE should not be required).
    #elif TARGET_OS_IPHONE && TARGET_OS_MACCATALYST
        // define something for Mac's Catalyst
    #elif TARGET_OS_IPHONE
        // define something for iphone  
    #else
        #define TARGET_OS_OSX 1
        // define something for OSX
    #endif
#elif __linux
    // linux
#elif __unix // all unices not caught above
    // Unix
#elif __posix
    // POSIX
#endif

注意,上面检查了 TARGET_OS_SIMULATOR 宏,因为 TARGET_IPHONE_SIMULATOR 宏自 iOS 14 起已被弃用。

As Jake points out, TARGET_IPHONE_SIMULATOR is a subset of TARGET_OS_IPHONE.

Also, TARGET_OS_IPHONE is a subset of TARGET_OS_MAC.

So a better approach might be:

#ifdef _WIN64
   //define something for Windows (64-bit)
#elif _WIN32
   //define something for Windows (32-bit)
#elif __APPLE__
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR
        // define something for simulator
        // (although, checking for TARGET_OS_IPHONE should not be required).
    #elif TARGET_OS_IPHONE && TARGET_OS_MACCATALYST
        // define something for Mac's Catalyst
    #elif TARGET_OS_IPHONE
        // define something for iphone  
    #else
        #define TARGET_OS_OSX 1
        // define something for OSX
    #endif
#elif __linux
    // linux
#elif __unix // all unices not caught above
    // Unix
#elif __posix
    // POSIX
#endif

Note that above checks TARGET_OS_SIMULATOR macro because TARGET_IPHONE_SIMULATOR macro got deprecated since iOS 14.

梦毁影碎の 2024-11-12 18:47:18

2021 年 1 月 5 日:感谢 @Sadap 的评论,链接更新。

一种必然的答案: 上的人这个网站花了时间来制作定义的宏表每个操作系统/编译器对。

例如,您可以看到 _WIN32 并未在使用 Cygwin (POSIX) 的 Windows 上定义,但它是为在 Windows、Cygwin(非 POSIX)和 MinGW 上使用每个可用编译器 (Clang) 进行编译而定义的。 、GNU、英特尔等)。

不管怎样,我发现这些表格内容非常丰富,我想在这里分享一下。

5 Jan 2021: link update thanks to @Sadap's comment.

Kind of a corollary answer: the people on this site have taken the time to make tables of macros defined for every OS/compiler pair.

For example, you can see that _WIN32 is NOT defined on Windows with Cygwin (POSIX), while it IS defined for compilation on Windows, Cygwin (non-POSIX), and MinGW with every available compiler (Clang, GNU, Intel, etc.).

Anyway, I found the tables quite informative and thought I'd share here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文