What #defines are set up by Xcode when compiling for iPhone
Asked Answered
C

3

67

I'm writing some semi-portable code and want to be able to detect when I'm compiling for iPhone. So I want something like #ifdef IPHONE_SDK....

Presumably Xcode defines something, but I can't see anything under project properties, and Google isn't much help.

Concision answered 28/9, 2008 at 23:25 Comment(0)
C
116

It's in the SDK docs under "Compiling source code conditionally"

The relevant definitions are TARGET_OS_IPHONE (and he deprecated TARGET_IPHONE_SIMULATOR), which are defined in /usr/include/TargetConditionals.h within the iOS framework. On earlier versions of the toolchain, you had to write:

#include "TargetConditionals.h"

but this is no longer necessary on the current (xCode 6/iOS8) toolchain.

So, for example, if you want to only compile a block of code if you are building for the device, then you should do

#if !(TARGET_OS_SIMULATOR)
...
#endif
Concision answered 28/9, 2008 at 23:47 Comment(8)
including target conditionals is exactly the right thing, then use #ifdef TARGET_OS_IPHONEAnnates
@kritzikratzi: #ifdef is wrong; you must use #if. (The symbol is normally defined as 0 when not on the simulator; #ifdef will still be true.)Bindery
For those of you who also thought TARGET_OS_IPHONE is a way of detecting device, it's not. It means you're on iOS, can be simulator or iphone. TARGET_IPHONE_SIMULATOR is the way to detect device vs. simulator. (I know it's not implied in the answer but seeing IPHONE there lead to my mistake)Figureground
@AirsourceLtd "So, for example, if you want to check that you are running on device", by are running you make people confused, you should say "if you want to check that are are select Simulator as running environment"Choi
@Choi - Could you tell me why "are running" is confusing? I'm afraid your suggested correction doesn't make any sense (to me), so I can't accept it in its current form.Concision
@Choi - ah I see. Hopefully the reword I just posted is clearer?Concision
I still had to include TargetConditionals.h in Xcode 6.4.Melo
instead of if !(TARGET_OS_SIMULATOR) you can use if TARGET_OS_EMBEDDEDSchleswig
S
24

To look at all the defined macros, add this to the "Other C Flags" of your build config:

-g3 -save-temps -dD

You will get some build errors, but the compiler will dump all the defines into .mi files in your project's root directory. You can use grep to look at them, for example:

grep define main.mi 

When you're done, don't forget to remove these options from the build setting.

Sitting answered 6/10, 2008 at 6:1 Comment(1)
doing this gcc -dM -E - < /dev/null on the command lies for an easier way to get the defines. (gcc, g++, clang, clang++ all work)Abed
S
2

The answers to this question aren't quite correct. The question of the platform and hardware vs Simulator is orthogonal.

Do not use architecture as a shortcut for platform or simulator detection! This kind of sloppy thinking has caused many, many programmers a great deal of heartburn and headache over the years.

Here is an ASCII chart of the conditionals. The names don't necessarily make sense for historical reasons:

+--------------------------------------+
|             TARGET_OS_MAC            |
| +---+  +---------------------------+ |
| |   |  |      TARGET_OS_IPHONE     | |
| |OSX|  | +-----+ +----+ +-------+  | |
| |   |  | | IOS | | TV | | WATCH |  | |
| |   |  | +-----+ +----+ +-------+  | |
| +---+  +---------------------------+ |
+--------------------------------------+

Devices:      TARGET_OS_EMBEDDED
Simulators:   TARGET_OS_SIMULATOR

TARGET_OS_MAC is true for all Apple platforms.


TARGET_OS_OSX is true only for macOS

TARGET_OS_IPHONE is true for iOS, watchOS, and tvOS (devices & simulators)


TARGET_OS_IOS is true only for iOS (devices & simulators)

TARGET_OS_WATCH is true only for watchOS (devices & simulators)

TARGET_OS_TV is true only for tvOS (devices & simulators)


TARGET_OS_EMBEDDED is true only for iOS/watchOS/tvOS hardware

TARGET_OS_SIMULATOR is true only for the Simulator.


I'll also note that you can conditionalize settings in xcconfig files by platform:

//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*] = ...
Sherbrooke answered 14/9, 2017 at 20:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.