What #Defines Are Set Up by Xcode When Compiling for Iphone

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

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

How do I define preprocessor macros in Xcode 4?

The build setting you need to change is called 'Preprocessor Macros' and it can be found in the 'Build Settings' tab of the Project Settings pane (use the search box to find it). Select each target in turn in the left-hand side of the Project Settings pane then modify the Preprocessor Macros setting.

The setting is specified as a space-separated list of preprocessor macros in the form 'foo' or 'foo=bar'.

Is there a specific Xcode compiler flag that gets set when compiling for iPad?

The correct API to use for run-time checking of iPad vs. iPhone/iPad Touch is:

BOOL deviceIsPad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad);

The UIDevice header filer also includes a convenient macro, UI_USER_INTERFACE_IDIOM(), which will be helpful if your deployment target is < iPhone 3.2.

#define UI_USER_INTERFACE_IDIOM() ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone)

So you could just say, negatively:

BOOL deviceIsPad = (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);

Command line compiling an iPhone Application

There's a command line tool to build Xcode projects: xcodebuild

Which conditional compile to use to switch between Mac and iPhone specific code?

You've made a mistake in your observations. :)

TARGET_OS_MAC will be 1 when building a Mac or iPhone application. You're right, it's quite useless for this sort of thing.

However, TARGET_OS_IPHONE is 0 when building a Mac application. I use TARGET_OS_IPHONE in my headers all the time for this purpose.

Like this:

#if TARGET_OS_IPHONE
// iOS code
#else
// OSX code
#endif

Here's a great chart on this:
http://sealiesoftware.com/blog/archive/2010/8/16/TargetConditionalsh.html

How to target a specific iPhone version?

You can use this #define to change what you build for each SDK...

#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_2_2
// iPhone 3.0 code here
#endif

And do this at run-time to run code for 3.0 and above:

float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 3.0)
{
// iPhone 3.0 code here
}

Conditional compilation Xcode using preprocessor macros

My problem was that the scheme was not pointing the correct target. Editing the scheme solved the issue.

xcodebuild - how to define preprocessor macro?

Cmd + I on the project to open the Info dialog. Then in the "Build" tab, find the "Preprocessor Macros" setting. Add the macros there.

... Where you can find the setting name is GCC_PREPROCESSOR_DEFINITIONS, so you could add

GCC_PREPROCESSOR_DEFINITIONS="foo=bar"

to the xcodebuild arguments.

Xcode 7: Set Preprocessor Macros per architecture

Finally I've figured it out.

Achieved result: _64BIT macro would be added during preprocessing to every (at least known for today) 64-bit environment, regardless of is it a simulator of 64-bit device or a real 64-bit device.

The solution is to manually edit .pbxproj-file as follows:

            GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
"GCC_PREPROCESSOR_DEFINITIONS[arch=arm64]" = (
"$(inherited)",
_64BIT,
);
"GCC_PREPROCESSOR_DEFINITIONS[arch=x86_64]" = (
"$(inherited)",
_64BIT,
);

So here is debug-config:

  • first section defines default macros which would be applied for all architectures;
  • 2nd and 3rd define custom macros which would be applied to specific architecture only.

Then changes that you've done manually would be visible within Preprocessor settings editor.
It really looks like bug in Xcode in the editor.

You can notice that I've already tried this approach before posting the question, but I've misinterpreted the results of my attempt. The thing is that I've tested my app on the simulator, and architectures are different on real device and corresponding simulator. I've configured macro to be included on arm64 architecture, but simulator's actual architecture was x86_64.

For further reference, this article explains where does every architecture actually take place:

  • arm7: Used in the oldest iOS 7-supporting devices
  • arm7s: As used in iPhone 5 and 5C
  • arm64: For the 64-bit ARM processor in iPhone 5S [and I believe the same is for newer iPhones]
  • i386: For the 32-bit simulator
  • x86_64: Used in 64-bit simulator

For i386 and x86_64 "bitness" of simulated device is implied here, not your Mac's.

Xcode building for iOS Simulator, but linking in an object file built for iOS, for architecture 'arm64'

Basically, you have to exclude arm64 for the simulator architecture, both from your project and the Pod project.

  • To do that, navigate to Build Settings of your project and add Any iOS Simulator SDK with value arm64 inside Excluded Architecture.

    Sample Image

OR

  • If you are using custom XCConfig files, you can simply add this line for excluding simulator architecture.

    EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64

    Then

    You have to do the same for the Pod project until all the Cocoa pod vendors are done adding following in their Podspec.

    s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
    s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }

    You can manually add the Excluded Architecture in your Pod project's Build Settings, but it will be overwritten when you
    use pod install.

    In place of this, you can add this snippet in your Podfile. It will write the necessary Build Settings every time you run pod install.

    post_install do |installer|
    installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
    end
    end


Related Topics



Leave a reply



Submit