326

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

4

3 回答 3

564

大多数编译器都使用预定义的宏,您可以在此处找到列表。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 __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 突出显示正确的代码分区)。

于 2011-05-07T08:43:20.020 回答
35

正如 Jake 指出的那样,TARGET_IPHONE_SIMULATORTARGET_OS_IPHONE.

也是TARGET_OS_IPHONE的一个子集TARGET_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 以来已被弃用。

于 2013-09-10T21:50:58.797 回答
10

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

一个必然的答案:这个网站上的人已经花时间制作了为每个 OS/编译器对定义的宏表。

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

无论如何,我发现这些表格信息量很大,并认为我会在这里分享。

于 2017-09-12T13:21:49.183 回答