Xcode: Conditional Build Settings based on architecture (Device (ARM) vs Simulator (i386))

17,973

Solution 1

I had this problem when integrating Adobe Omniture's "AppMeasurement" library, which currently comes compiled for 3 architectures: libAppMeasurement-iOSSimulator.a, libAppMeasurement-iOSDevice.a, and libAppMeasurement-iOSDevice-armv7.a.

While the other answers here are substantially correct, I ended up having to go elsewhere to truly understand and then fix the problem.

Step 1. Understanding the issues

This blog post does a great job of explaining the overall issue. It gives start-to-finish instructions for solving the problem in Xcode 3. See below for Xcode 4.

Note: You might try skipping the bit where he says to add the static libraries and then delete them. The next time I do this, I'll probably just add the header file(s), then skip straight to editing Other Linker Flags.

Step 2. Conditional Build Settings in Xcode 4

This StackOverflow page explains the new way to set conditional build settings in Xcode 4. Tip: The text fields on the Build Settings tab are drag-&-drop enabled; once you have your conditional build setting ready for editing under Other Linker Flags, you can just drag the static library file right onto the text field and Xcode will automatically enter a (hopefully relative) path.

Here's a screenshot of my Other Linker Flags once I got the "missing required architecture i386" warning to go away with no build errors:

enter image description here __

Solution 2

You have 3 options:

  1. If you control click on the name of build setting inside the Inspect Window (where you can change compiler settings, etc) it will bring an option to conditionalize that setting. Just go to the linker flags you want to change, and conditionalize them by SDK, then enter the specific library for each SDK.

  2. Alternatively you can take the library and install it at the same path in each SDKs root ("/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/lib/" and "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/usr/lib"). Since SDK relative library search paths are used the appropriate version will be pulled in for either build.

  3. You can lipo together two libraries into one fat library. That is probably a bad idea, but if you want to do it checkout the manpage.

Solution 3

For someone comes across the warning like "[lib_for_sim_or_device] not not built for the architecture ...", the warning arises when dragging the 3rd party library folder into the project.

Behind the scene the XCode automatically add the library files into 'target setting -> Build Phrases -> Link Binary with Libraries' sections, which causes linking with both libraries.

To fix that, remove those entries from 'Link Binary with Libraries', and then follow the guide above on conditional building setting for sim/device'

Hope it helps!

Solution 4

The recommended way to do this is to not add the library to your project and target, but instead to set the Other Linker Flags to include separate, direct references to the link library per configuration.

For Debug:

  OTHER_LINKER_FLAGS = -l/Path/To/My/Debug/Library.dylib

For Release

  OTHER_LINKER_FLAGS = -l/Path/To/My/Release/Library.dylib

You can of course use references to other build settings to make these paths relative to something durable, or use a Source Tree to an external source tree.

Solution 5

For option 1 (see Louis Gerbarg answer) in Xcode 3.2.1 select the "Other Linker Flags" and then select "Add Build Setting Condition" from the dropdown menu at the lower left of the build setting window. See cdespinosa answer for "Other Linker Flags" syntax)

Or you can also "Add Build Setting Condition" to "Library Search Paths" if you have the device/simulator libraries in separate directories.

Share:
17,973

Related videos on Youtube

noamtm
Author by

noamtm

Senior Software Engineer. Tech Lead at Kaltura.

Updated on March 20, 2020

Comments

  • noamtm
    noamtm about 4 years

    I'm building an iPhone app that has to run on both the simulator and the device. However I'm using an externally compiled library that has one version for the simulator and one for the device (different CPU).

    How can I do it? I'm coming from Visual C++ so I'm new to Xcode, and I can't find the way to do it.

    EDIT, March 2016: this question was asked on July 2009, almost 6 years ago. Much has changed in Xcode since, but I guess some stuff still holds. The now-accepted answer, for example, wasn't an option in Xcode v3.

  • zaph
    zaph over 14 years
    This does not answer the question. The question was about device/simulator, not debug/release. We frequently get two libraries based on the target device/simulator.
  • NewtoProgramming
    NewtoProgramming over 14 years
    To be fair, Build Setting Conditions didn't exist in July 2009 when I posted my reply, and using Configurations was the only way to do it.
  • DouglasHeriot
    DouglasHeriot over 12 years
    Dragging it into the 'Other Linker Flags' worked for me. (Make sure you double click it first, so you can drag it into the popover, if you’ve already got settings in the row.)
  • Brian King
    Brian King about 12 years
    Wow, that's great, didn't see that. Any idea how that's represented in .xcconfig files? I need to include -lgcov in gcc and -lrt_profile in llvm!
  • Brian King
    Brian King about 12 years
    I found this post: cocoabuilder.com/archive/xcode/… Here's the meat of it: 1) Create a custom build setting GCC_VERSION_0310 = 4.2 2) Create a custom build setting GCC_VERSION_0320 = com.apple.compilers.llvmgcc42 3) Define GCC_VERSION to be $(GCC_VERSION_$(XCODE_VERSION_MINOR))
  • chown
    chown about 12 years
    lipo'ing into a fat lib is not necessarily a bad idea b/c any unused architectures are removed. It is essentially the same as just linking against the skinny lib. The only drawback I can see is the extra few seconds it may take to extract the current arch from the universal fat lib. I personally use several custom lipo'd fat libs in my projects as it reduces the amount of files Xcode needs to index and the total number of files I have to think about ). Good answer though!
  • Nathan F.
    Nathan F. almost 6 years
    When trying to do this i see this: i.imgur.com/nwp6t8D.png Where are the archs?
  • CyberMew
    CyberMew over 5 years
    @NathanFiscaletti On Xcode 10 it is under Any iOS Simulator SDK for simulators and Any iOS SDK for 'devices' (the 'archs').