This time around, it was iOS 6 and the armv7s instruction set:
ld: file is universal (3 slices) but does not contain a(n) armv7s slice
What the What?
What this linker error means is that your compiled static library isn't 'fat' enough. In plain terms, it means that when it was built, it wasn't built for (one of) your specified architectures, and it can't be applied to your project. This also occurred when the armv7 was introduced.
The Good News
Now, if you're in charge of that static library, you just need to add 'armv7s' in Build Settings -> Valid Architectures and you're ready to go! If you aren't, it get a little more hazy.
Given that it's an incremental release, the armv7s is completely backwards compatible (as of speculatory writing!) and can easily run armv7-compiled code. This means that it isn't strictly necessary to go about recompiling the code, but that it won't be able to use any fixes or speed increases that may be present in the new instruction set.
The Bad News
You can't specify mixing version types. In older versions of Xcode, that was something that could be set, but it's been a while since Apple made anything that easy.
In fact, Xcode is notorious for making lives hard when it really doesn't need to be. It seems that every version of Xcode, incremental or otherwise, comes with major shifts in implementation or distributed SDK's. Anyone who has tried to run Xcode 4 on Snow Leopard will know that without me needing to tell them that it is an arm-twisting mess. Being backwards compatible, being forward compatible, you name it, if it's not 'current' in the Apple development world, you'll jump flaming hoop after flaming hoop. iOS 6 is no different.
Compiling for iOS 6 automatically adds the 'armv7s' flag to your valid architectures. For those not using 3rd party libraries, that is not an inherently bad thing, and in fact is very likely the 'right' way to go about things. Those who make 3rd-party libraries are tasked with maintaining this compatibility and from what I've seen, are timely about doing it, but what happens when you're using something... a little outdated?
The Correct Way
As you may already guess, the 'right way' of doing things is to remove armv7s from your valid architectures and go about your business. If you guessed that, you'd be right! As I mentioned before, the armv7s is backwards compatible and as-of this writing, there is nothing stating that your armv7 code won't work!
But what if you need to use iOS 6 and you aren't in a position to fall back to armv7 only? What if you're unable to re-compile the static library including that architecture? Well, here's a solution, complete with total lack of guarantees!
The Workaround
As a forewarning, this gets a little technical, but I'm going to attempt to be as straightforward as possible in delivering these instructions. They are compiled from about five different sources or so and frankensteined together to form a comprehensive solution.
Step 1: Gather Your Materials
What you'll need:
- the static library you need to use
- the latest build of Xcode (4.5)
- the latest iOS SDK (6.0)
- a hex editor (such as Hex Fiend)
- Terminal
It should go without saying that travelling this route requires, and is due to updating to, the most recent version of Xcode and the iOS 6 SDK. You'll know you have this when that linker error I put at the beginning of the article shows up when you build.
In this, I've recommended Hex Fiend as a hex editor, but really, it's whatever you want to use. You'll also need Terminal, which is in Applications -> Utilities on your Mac.
Step 2: Terminal and lipo
I mentioned earlier that your issue was your 'fat' library. To fix the 'fat', we'll need some
lipo.
First, let's check on our library to see what's supported in it. To check on the supported architectures in your library, enter the following into Terminal:
lipo -info libMYLIB.a
Note: If you didn't cd into your library's containing folder, you can navigate to it in Finder and drag-and-drop it into Terminal. Doing that will autocomplete the correct path.
Doing this will output something like the following:
Architectures in the fat file: libMYLIB.a are: armv6 armv7 i386 Here we see that armv7s is not listed. We'll fix that.
The next command you'll need is -extract.
lipo libMYLIB.a -extract armv7 -output libMYLIB7s.aIn this command, the first file is your source file (the one that is missing the armv7s). What we're saying here is that we're extracting the armv7 architecture. The -output flag specifies where to place it. Again, if you don't cd to a specific directory, you'll need to specify the path along with the file here.
We have one more thing to do before we get down to the hex editing:
lipo libMYLIB7s.a -thin armv7 -output libMYLIB7sthin.aThis will ensure that your file is stripped to the bare minimum for your architecture! Checking its info as in the first part of step 2 should result in the following:
lipo -info libMYLIB7sthin.a
input file libMYLIB7sthin.a is not a fat fileCheck to make sure your output file was created and we're ready for step 3!
Step 3: Armv7s Bluffing
I need to emphasize that this doesn't actually make the code compiled for armv7s. It is merely bluffing. Here's how we do it.
Fire up Hex Fiend (or your preferred choice) and open your extracted libMYLIB7s.a. ⌘F to get your find/replace prompt up and input the following:
CEFAEDFE 0C000000 09000000
into your 'find' and
CEFAEDFE 0C000000 0B000000
![]() |
| Let's ignore the filename here, haha! |
Save your new file (back up the previous, just in case!) and we're ready to move onto the last step!
Step 4: Repackaging the Library
Hope you still have Terminal open! This is the last line for us!
lipo -output libMYLIBfinal.a -create libMYLIB.a libMYLIB7sthin.a
And... you're done! Put that new static library into your project and you should see it compile without issues!
I'm in the process of doing this with a couple of our legacy libs, so I'll report later on if there are any caveats to this method, but so far so good! Have fun everyone!

