iPhone: how to make a fat library containing armv7s support? - iphone

I have external libraries for armv6, armv7, i386 and armv7s. When I try to put all together using lipo, I got an error message like so, saying armv7s isn't supported:
lipo: known architecture flags are: any little big ppc64 x86_64 ppc970-64 ppc i386 m68k hppa sparc m88k i860 veo arm ppc601 ppc603 ppc603e ppc603ev ppc604 ppc604e ppc750 ppc7400 ppc7450 ppc970 i486 i486SX pentium i586 pentpro i686 pentIIm3 pentIIm5 pentium4 m68030 m68040 hppa7100LC veo1 veo2 veo3 veo4 armv4t armv5 xscale armv6 armv7 armv7f armv7k
How to solve this problem?

You are possibly trying to use an older version of lipo that does not support armv7s. You should try that with the lipo version bundled with Xcode 4.5.

You would need the sources and compile it with armv7s support. Also, armv7 should work just fine on the armv7s devices too.

Related

iOS simulator on mac is running i386 architecture, not armv7?

I've got some static libraries I've built for use on armv7 architectures. When I try to use them in a iOS project which I testrun on the iphone 5.0 simulator, I get errors telling me about undefined symbols for architecture i386 in my static libraries.
So I guess this means the iphone simulator wants libraries compiled for i386? What is the point of the simulator then - why dosn't it emulate armv7 architecture as well?
So the only way I can test my static libraries is to connect a physical iOS device and run it?
Or did I get it wrong?
So I guess this means the iphone simulator wants libraries compiled
for i386? What is the point of the simulator then - why dosn't it
emulate armv7 architecture as well?
You've answered your own question. It's a simulator, not an emulator. Therefore it is a Mac OSX program, running on i386 architecture. If you compile your static libraries for i386 as well you will be able to use them on the simulator.
I am not very sure but i386 is for Simulator and armv7 is for Devices that you have connected to your Machine.
You can actually compile the app through Xcode command line tool using i386 architecture (there is also a way to run it in Xcode UI by modifying the build settings).
xcodebuild -sdk iphonesimulator6.1 -arch i386 VALID_ARCHS="i386 armv7 armv7s" clean install
Run this command in the directory that you have the projectName.xcodeproj file.
Here's a break down of the script:
-sdk iphonesimulator6.1 // Build the app on iPhone simulator 6.1
-arch i386 // Build your app using i386 architecture
VALID_ARCHS="i386 armv7 armv7s" // Specify these architectures are valid
clean install // Clean all the builds then re-build and install
If you want to try simulators with i386 just go for =< iPhone 5.

boost armv7 build

I tried this to build armv7 boost libs:
./bjam toolset=darwin cflags="-fvisibility=default" architecture=arm target-os=iphone macosx-version=iphone-4.1 link=static threading=multi define=_LITTLE_ENDIAN include=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk/usr/include/c++/4.2.1/armv7-apple-darwin10 --with-thread --with-date_time
But the lipo -info command told me that the compiled library is armv6, not armv7 lib!
Could anyone please tell me a boost command line to create a libs with armv7
Pass the "-arch armv7" flag to the compiler. In your example, setting architecture=armv7 should probably do the trick.
In any case, armv6 executables can always be run (to the extent of my knowledge) on armv7 CPUs.

No architectures to compile for core plot iphone

I'm trying out a core plot iphone example and I get:
No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=i386, VALID_ARCHS=armv6 armv7).
Under project settings -> architecture, the only options are standard, optimized, and native arch.
Any ideas?
Thank you.
Add i386 to Valid Architectures
I was getting the same error while trying to run some older sample code... It turns out that the project build settings get changed (by the iOS 4.1 SDK?). Anyway, changing these settings back worked for me:
ORIG PROJECT "BUILD" SETTINGS:
Architecture: $(NATIVE_ARCH)
and
Valid Architectures: i386
NEW SETTINGS:
Architectures: armv6 armv7
and
Valid Architectures: armv6 armv7 i386
Just like magic...
~Paul

Compile C lib for iPhone

I'm trying to compile ZeroMQ C binding in order to be able to use it on iPhone, here is my configure options:
./configure --host=arm-apple-darwin --enable-static=yes --enable-shared=no CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-gcc-4.2.1 CFLAGS="-pipe -std=c99 -Wno-trigraphs -fpascal-strings -O0 -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=3.1.2 -gdwarf-2 -mthumb -I/Library/iPhone/include -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk -mdynamic-no-pic" CPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp AR=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar AS=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as LIBTOOL=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool STRIP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip RANLIB=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib
It actually configures and compiles fine, but when I add it to Xcode Frameworks section, I get warning: ld: warning: in /path/to/app/libzmq.a, file was built for unsupported file format which is not the architecture being linked (armv7) and a lot of symbol not found errors.
If I change current active architecture from armv6 to armv7, warning message will change it to armv6.
What am I doing wrong ?
Thanks,
Dan
It sounds like you're building a universal armv6/armv7 binary for the iPhone (this is the default, so that makes sense). That means that you need to build a universal library to link against. Build both libraries, and then use lipo to combine the two.
For example, build the armv6 one and place it at armv6/libfoo.a, and the armv7 one at armv7/libfoo.a. Then run
lipo -arch armv6 armv6/libfoo.a -arch armv7 armv7/libfoo.a -output libfoo.a -create
to create the universal library libfoo.a.
Given the warning message from ld, my guess is you're not compiling the library for the correct platform. And given you're using configure, my guess is you're trying to compile the library outside of Xcode and then bring it into Xcode later to link it in.
Perhaps you could try running configure to set up your headers, but do the actual compilation step inside Xcode?
There are lots of related questions here on SO about compiling third-party (external) C or C++ libraries for use in iPhone projects.
Creating static library for iPhone
TiMidity: need help compiling this library for the iPhone

How do i compile a static library (fat) for armv6, armv7 and i386

I know this question has been posed several times, but my goal is slightly different with regard to what I have found searching the web. Specifically, I am already able to build a static library for iPhone, but the final fat file I am able to build only contains arm and i386 architectures (and I am not sure to what arm refers: is v6 or v7?). I am not able to compile specifically for armv6 and armv7 and them merge both architectures using lipo. The lipo tool complains that the same architecture (arm, not armv6 or armv7) is present in both the armv6 and armv7 libraries.
Can someone explain exactly how to build for armv6 and armv7, and them merge these libraries into a fat file using lipo?
EDIT: I need to build not using Xcode but compiling directly a traditional unix library.
Here is a good solution I found: Static Libs With Support to iOS 5 and Arm64
Edited:
The solution is to build different architectures separated then bind them using lipo, by using command line (or Rakefile).
First build the binary with arm using xcodebuild:
xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphoneos7.0' clean build ARCHS='armv7 armv7s' IPHONEOS_DEPLOYMENT_TARGET='5.0' TARGET_BUILD_DIR='./build-arm' BUILT_PRODUCTS_DIR='./build-arm'
Note that you must set IPHONEOS_DEPLOYMENT_TARGET='5.0' and ARCHS='armv7 armv7s', it’s recommended to set build and product dirs to make the things more clear, take a look at Build Setting Reference for more details what this flags means.
Next build for arm64:
xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphoneos7.0' clean build ARCHS='arm64' IPHONEOS_DEPLOYMENT_TARGET='7.0' TARGET_BUILD_DIR='./build-arm64' BUILT_PRODUCTS_DIR='./build-arm64'
Note the difference on ARCHS and IPHONEOS_DEPLOYMENT_TARGET. We also need to build for simulator, in this case we have to change the sdk to iphonesimulator7.0 and build in two steps first for i386:
xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphonesimulator7.0' clean build ARCHS='i386' IPHONEOS_DEPLOYMENT_TARGET='5.0' TARGET_BUILD_DIR='./build-i386' BUILT_PRODUCTS_DIR='./build-i386'
Now the tricky part! If you just change the ARCHS to x86_86 depending on your Xcode setting you will got an error like: “x86_64 is not a valid arch”. To avoid this just add VALID_ARCHS='x86_64':
xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphonesimulator7.0' clean build ARCHS='x86_64' VALID_ARCHS='x86_64' IPHONEOS_DEPLOYMENT_TARGET='7.0' TARGET_BUILD_DIR='./build-x86_64' BUILT_PRODUCTS_DIR='./build-x86_64'
Finally we just have to create a fat binary with all the 5 architectures:
lipo -create './build-arm/libStaticLibDemo.a' './build-arm64/libStaticLibDemo.a' './build-i386/libStaticLibDemo.a' './build-x86_64/libStaticLibDemo.a' -output 'libStaticLibDemo.a'
The author created a working example of this, you can get it: https://github.com/diogot/StaticLibDemo
Here is the Link to the post: Static Libs With Support to iOS 5 and Arm64
All credits go to Diogo Tridapalli.
Just use libtool to link the two arm6 and arm7 versions together - its what XCode does. However you will have problems if you try to combine these static libraries into a new super-library. If you need to do that then read this.
If you are doing this already, that would be why lipo is complaining that your "armv6" library contains both armv6 and armv7. My post has a fix that will probably be easier for you since you don't use XCode, but basically you use lipo -extract to make sure you have a thin armv6 library and a thin armv7 library before you go any further.
There doesn't seem to be a need to extract from the fat library before rejoining any more (as described in jamie's answer). I'm using the final 4.0 SDK from apple, which appear to create the fat armv6/armv7 libraries by default.
I was previously specifying the architecture for the input lib like so:
$DEVROOT/usr/bin/lipo -arch arm $PROJECT_DIR/buildlib/Release-iphoneos/lib.a -arch i386 $PROJECT_DIR/buildlib/Release-iphonesimulator/lib.a -create -output $PROJECT_DIR/buildlib/lib.a
This fails on the later SDKs, but removing the architecture from the (now fat) arm lib works fine:
$DEVROOT/usr/bin/lipo $PROJECT_DIR/buildlib/Release-iphoneos/lib.a -arch i386 $PROJECT_DIR/buildlib/Release-iphonesimulator/lib.a -create -output $PROJECT_DIR/buildlib/lib.a
Lipo must now be able to detect the architectures in the fat libraries.
Make sure to have your build settings set to Valid Architectures: armv6 armv7 and Architectures: Optimized (armv6 armv7). This should result in a binary optimized for both v6 & v7. If you're not sure it worked out, just set the Architectures: Standard (armv6) and compare the file sizes. Optimized should produce double the size (when I remember rightly).
You also always can use lipo -info on your binary to see all the included architecures.
Running it on a distribution build of my app gives me:
ullrich ~/Code/.../build/Distribution-iphoneos/My.app (streaming)$ lipo -info My
Architectures in the fat file: My are: armv6 armv7