How to Build For Armv6 and Armv7 Architectures With iOS 5

How to build for armv6 and armv7 architectures with iOS 5

I just built something today specifying a deployment target of iOS 4.0. With only armv7 specified in Architectures, Xcode warned me that to support anything below iOS4.2 I had to include armv6 in Architectures. Just edit that field, click the "+" button when the dialog pops up and enter the literal "armv6".

In my case, we want our app to work under iOS4 and iOS5. We had to make some modifications so it would work correctly under iOS5, but all those changes were done with iOS4-friendly code changes.

We also added some iOS5-specific capabilities in a manner that allows the app to run without crashing under iOS4. Specifically, we tested for iOS5 capabilities before trying to use them, and linked iOS5-only libraries as Optional.

So, supporting iPhone3G in an iOS5 world could just as easily mean "we want our app to run on iOS4 and above (regardless of any iOS5 feature use)" rather than "we want to make sure our app runs on an older device running iOS5". There's a difference here; think about it. :-)

Anyway, adding armv6 support back in is very easy. And I guess the point is this: At some point, when there are no more armv6 devices out there to worry about (for whatever reason) you won't have to build for it. Apple's view is everyone should upgrade to the latest hardware as soon as possible. So in that world, there is no need for the tools to default to anything but the latest and greatest too. :-) Fortunately (or not), we developers live in the real world and recognize that you have to support older stuff for a while. And I guess the Xcode dev team knows this too, which is why you can add armv6 support back in quite simply.

How to use armv6 third party libraries in an armv7 app?

The answer is to hack the armv6 library into thinking it's an armv7 library. This will get you running until the vendor supplies the library. The reason this works is because the arm spec requires all arm architectures to be able to run code generated by previous architectures. So if an armv6 library told the linker it's an armv7, the processor should still be able to run the code. Of course, you can't go the other way. Use otool -h on both libraries to see the cputype and cpusubtype. On my libraries it was 12 for both cputypes, and 6 and 9 for the subtypes, indicating armv6 and armv7.
Using a hex editor, look for the hex string 0xcefaedfe which is the marker MH_MAGIC (0xfeedface) reversed due to big/little endian.

Following that, there's a whole word with just 0xC. That's the 12 for the cputype. Next is a word for 0x6. Change that to 0x9 for all cases.
Now ld will think your library is an armv7, and act accordingly.

You're probably not done, because the armv6 may have linked in some thumbs library routines. If you get link errors (I got some for switch8 and switch16), you need to find the Darwin code that has them. Look for the file lib1funcs.asm on the web. This will probably have your missing functions. They're probably conditionaled out, so adjust the #ifdefs and make sure they're being compiled. This file tries to open some includes at the end, but since they're at the end, they don't affect anything, so just comment them out.

Yes, it is a tremendous hack, but it gets you up and running. If you get your revised library, you just have to drop it in. No code change required. If it works for you, you're still using Apple's code, and it would be the same code you'd be running if you were armv6 only.

Conditional compiling for armv6 and armv7

Well i realized my last answer in not the correct one... Apple said that is impossible but this is not really true... thanks to Jim, i search little more and i found one way to do it..

  1. Remove lib from "Build Phases"
  2. Add both architectures in "Other Linker Flags" (Build Settings) , for that you need click in + and add armv6 and armv7
  3. Add the lib in armv7.. with -l
  4. Don't forget #if defined _ARM_ARCH_7 in your code

This is like Jim answered but more detailed.

Why is armv6 a Valid Architecture for iOS 5?

$(VALID_ARCHS) defines the set of architectures that an Xcode target supports. $(ARCHS) tells Xcode what architectures to build. What actually gets built for each target is the intersection of $(VALID_ARCHS) and $(ARCHS).

$(VALID_ARCHS) is typically used to avoid building a target for some architecture that the project as a whole otherwise supports. If you don't need to do that, you can safely ignore it.

When do I need to include armv7? Can I build for iOS5 devices too using only armv6?

armv7 is for iPad, iPad 2, iPhone 3GS, iPhone 4, and iPhone 4s.

Build for armv6 architecture (target iOS 3.1.3) with iOS 6 SDK and Xcode 4.5?

With Xcode 4.5 (ie iOS 6 SDK) the lowest version you can build for is iOS 4.3. I guess it is time for your 3.1.3 customers to upgrade.

When do I need to include armv7? Can I build for iOS5 devices too using only armv6?

armv7 is for iPad, iPad 2, iPhone 3GS, iPhone 4, and iPhone 4s.

iOS 5 Devices Without armv7 Support

As I understand it - armv6 supports up to the iPhone 3G, armv7 is for all iPads and the iPhone 3G S and up.

Since iOS5 will only run on the 3G S upwards - I'd say that you can safely drop the armv6 architecture as long as you are only supporting iOS5 and upwards.

Warning: iPhone apps should include an armv6 architecture even with build config set

If using Xcode 4.2 or higher, try the following:

  1. Click your Project name (in the left column), followed by the Target:

    Sample Image

  2. Click the 'Build Settings' tab (in the right column):

    Sample Image

  3. Click the 'Release' or 'Distribution' row under 'Architectures', and choose 'Other...':

    Sample Image

  4. Double click the highlighted row named '$(ARCHS_STANDARD_32_BIT)' in the popover that appears, and replace it by typing 'armv6'. Then add a new row with the plus button in the bottom left of the popover, and type 'armv7', then click Done:

    Sample Image

Update: you should add armv7s to target the iPhone 5 as well. (And drop armv6 if building with Xcode 4.5 or higher, which no longer supports armv6.)

That's it. You should now be able to build/archive without generating errors.

If it still doesn't work, see this answer from justinxreese, which suggests adding entries for armv6 and armv7 under "Required Device Capabilities" in your info.plist file.



Related Topics



Leave a reply



Submit