【问题标题】:What #defines are set up by Xcode when compiling for iPhone为 iPhone 编译时 Xcode 设置了什么#defines
【发布时间】:2010-09-13 21:40:36
【问题描述】:

我正在编写一些半便携式代码,并希望能够检测我何时为 iPhone 编译。所以我想要#ifdef IPHONE_SDK...之类的东西。

大概是 Xcode 定义了一些东西,但我在项目属性下看不到任何东西,Google 也帮不上什么忙。

【问题讨论】:

    标签: ios xcode macos conditional-compilation


    【解决方案1】:

    它位于 SDK 文档中的“有条件地编译源代码”下

    相关定义是TARGET_OS_IPHONE(他弃用了TARGET_IPHONE_SIMULATOR),在iOS框架内的/usr/include/TargetConditionals.h中定义。在工具链的早期版本中,您必须编写:

    #include "TargetConditionals.h"
    

    但这在当前 (xCode 6/iOS8) 工具链上不再需要。

    因此,例如,如果您在为设备构建时只想编译一段代码,那么您应该这样做

    #if !(TARGET_OS_SIMULATOR)
    ...
    #endif
    

    【讨论】:

    • 包含目标条件是完全正确的,然后使用#ifdef TARGET_OS_IPHONE
    • @kritzikratzi:#ifdef 是错误的;你必须使用#if。 (当不在模拟器上时,该符号通常定义为 0;#ifdef 仍然为真。)
    • 对于那些还认为 TARGET_OS_IPHONE 是一种检测设备的方法的人来说,事实并非如此。这意味着您在 iOS 上,可以是模拟器或 iphone。 TARGET_IPHONE_SIMULATOR 是检测设备与模拟器的方法。 (我知道答案中没有暗示,但看到 IPHONE 会导致我的错误)
    • @AirsourceLtd “所以,例如,如果你想检查你是否在设备上运行”,正在运行你会让人们感到困惑,你应该说“如果你想检查是否选择模拟器作为运行环境"
    • @onmyway133 - 你能告诉我为什么“正在运行”令人困惑吗?恐怕你建议的更正没有任何意义(对我来说),所以我不能接受它目前的形式。
    【解决方案2】:

    要查看所有定义的宏,请将其添加到构建配置的“其他 C 标志”中:

    -g3 -save-temps -dD
    

    您会遇到一些构建错误,但编译器会将所有定义转储到项目根目录中的 .mi 文件中。您可以使用 grep 来查看它们,例如:

    grep define main.mi 
    

    完成后,不要忘记从构建设置中删除这些选项。

    【讨论】:

    • 在命令上执行此gcc -dM -E - < /dev/null 是为了更轻松地获取定义。 (gcc、g++、clang、clang++ 都可以)
    【解决方案3】:

    这个问题的答案并不完全正确。平台和硬件与模拟器的问题是正交的。

    不要将架构作为平台或模拟器检测的捷径!多年来,这种草率的想法已经让很多很多程序员感到胃痛和头痛。

    这是条件句的 ASCII 图表。由于历史原因,这些名称不一定有意义:

    +--------------------------------------+
    |             TARGET_OS_MAC            |
    | +---+  +---------------------------+ |
    | |   |  |      TARGET_OS_IPHONE     | |
    | |OSX|  | +-----+ +----+ +-------+  | |
    | |   |  | | IOS | | TV | | WATCH |  | |
    | |   |  | +-----+ +----+ +-------+  | |
    | +---+  +---------------------------+ |
    +--------------------------------------+
    
    Devices:      TARGET_OS_EMBEDDED
    Simulators:   TARGET_OS_SIMULATOR
    

    TARGET_OS_MAC 适用于所有 Apple 平台。


    TARGET_OS_OSX 仅适用于 macOS

    TARGET_OS_IPHONE 适用于 iOS、watchOS 和 tvOS(设备和模拟器)


    TARGET_OS_IOS 仅适用于 iOS(设备和模拟器)

    TARGET_OS_WATCH 仅适用于 watchOS(设备和模拟器)

    TARGET_OS_TV 仅适用于 tvOS(设备和模拟器)


    TARGET_OS_EMBEDDED 仅适用于 iOS/watchOS/tvOS 硬件

    TARGET_OS_SIMULATOR 仅适用于模拟器。


    我还要注意,您可以按平台条件化 xcconfig 文件中的设置:

    //macOS only
    SOME_SETTING[sdk=macosx] = ...
    
    //iOS (device & simulator)
    SOME_SETTING[sdk=iphone*] = ...
    //iOS (device)
    SOME_SETTING[sdk=iphoneos*] = ...
    //iOS (simulator)
    SOME_SETTING[sdk=iphonesimulator*] = ...
    
    //watchOS (device & simulator)
    SOME_SETTING[sdk=watch*] = ...
    //watchOS (device)
    SOME_SETTING[sdk=watchos*] = ...
    //watchOS (simulator)
    SOME_SETTING[sdk=watchsimulator*] = ...
    
    //tvOS (device & simulator)
    SOME_SETTING[sdk=appletv*] = ...
    //tvOS (device)
    SOME_SETTING[sdk=appletvos*] = ...
    //tvOS (simulator)
    SOME_SETTING[sdk=appletvsimulator*] = ...
    
    // iOS, tvOS, or watchOS Simulator
    SOME_SETTING[sdk=embeddedsimulator*] = ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      相关资源
      最近更新 更多