Xcode编译iPhone应用时设置了哪些#define?

67

我正在编写一些半可移植的代码,想要能够检测是否正在为iPhone编译。因此,我需要类似于#ifdef IPHONE_SDK...的东西。

大概Xcode会定义一些东西,但我在项目属性下并没有看到任何内容,而且谷歌也没有什么帮助。

3个回答

116

这在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
3
@kritzikratzi:#ifdef是错误的;你必须使用#if。(当不在模拟器上时,该符号通常被定义为0;#ifdef仍将为真。) - Andrew
2
对于那些也认为TARGET_OS_IPHONE是一种检测设备的方式的人,它并不是。它意味着你在iOS上,可以是模拟器或iPhone。TARGET_IPHONE_SIMULATOR是检测设备与模拟器的方法。(我知道答案中没有暗示,但看到IPHONE这个词导致了我的错误) - Ege Akpinar
1
@AirsourceLtd “例如,如果您想要检查您是否正在设备上运行”,由于“are running”这个词组容易让人感到困惑,您应该说“如果您想要检查您是否选择了模拟器作为运行环境”。 - onmyway133
在Xcode 6.4中,我仍需要包含TargetConditionals.h - Sebastian
显示剩余3条评论

24

想查看所有已定义的宏,请将以下内容添加到您的构建配置的“其他C标志”中:

-g3 -save-temps -dD

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

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

grep define main.mi 

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


2
在命令行中执行 gcc -dM -E - < /dev/null 可以更轻松地获取定义,适用于 gcc、g++、clang 和 clang++。 - Urkle

2
这个问题的答案并不完全正确。平台和硬件与模拟器的问题是正交的。 不要将架构用作平台或模拟器检测的快捷方式!多年来,这种粗心思考已经给许多程序员带来了很多困扰和头痛。
下面是条件语句的ASCII图表。名称可能由于历史原因而没有意义:
+--------------------------------------+
|             TARGET_OS_MAC            |
| +---+  +---------------------------+ |
| |   |  |      TARGET_OS_IPHONE     | |
| |OSX|  | +-----+ +----+ +-------+  | |
| |   |  | | IOS | | TV | | WATCH |  | |
| |   |  | +-----+ +----+ +-------+  | |
| +---+  +---------------------------+ |
+--------------------------------------+

Devices:      TARGET_OS_EMBEDDED
Simulators:   TARGET_OS_SIMULATOR

TARGET_OS_MAC适用于所有苹果平台。


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*] = ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接