Static libraries...
This shouldn't be a hard question for anybody here, but I'm at a loss... I've tried looking up tutorials for help, but every tutorial I've found seems to focus on much more advanced Xcode tricks than I'm interested in - I just want to have a static library which works both in the simulator and on hardware 
Okay, I've built up a collection of C++ and Objective-C++ classes commonly used in my iPod touch projects for university; this collection is <10KLOC but is spread over far too many files for my liking; so, I'd like to create a static library collecting all of those commonly used classes.
So, I created a test static library containing a C++ function just fprintf()'ing to stderr to prove that the function has been invoked.
(To create the test static library I created a new project using Xcode (OpenGL ES Application), added a static library target, dragged the .cpp file to the Compile Sources section of that target, and deleted the original application target.)
Building the static library using Mac OS X 10.5 as the active SDK and dropping the static library from build/Debug/ into a C++ Tool works fine.
Building the static library using iPhone OS - Device or Simulator - as the active SDK and dropping the static library from build/Debug-iphoneos/ or build/Debug-iphonesimulator/ into an iPhone OS application compiled using Device as the active SDK works fine.
But, compiling that same iPhone OS application using Simulator as the active SDK fails with a "symbol not found" compile time error.
So why is a static library compiled for Simulator/Debug - iPhone OS (i386) being correctly invoked in an application compiled for Debug - iPhone OS (armv6)?

Okay, I've built up a collection of C++ and Objective-C++ classes commonly used in my iPod touch projects for university; this collection is <10KLOC but is spread over far too many files for my liking; so, I'd like to create a static library collecting all of those commonly used classes.
So, I created a test static library containing a C++ function just fprintf()'ing to stderr to prove that the function has been invoked.
(To create the test static library I created a new project using Xcode (OpenGL ES Application), added a static library target, dragged the .cpp file to the Compile Sources section of that target, and deleted the original application target.)
Building the static library using Mac OS X 10.5 as the active SDK and dropping the static library from build/Debug/ into a C++ Tool works fine.
Building the static library using iPhone OS - Device or Simulator - as the active SDK and dropping the static library from build/Debug-iphoneos/ or build/Debug-iphonesimulator/ into an iPhone OS application compiled using Device as the active SDK works fine.
But, compiling that same iPhone OS application using Simulator as the active SDK fails with a "symbol not found" compile time error.
So why is a static library compiled for Simulator/Debug - iPhone OS (i386) being correctly invoked in an application compiled for Debug - iPhone OS (armv6)?
the_wandering_monster Wrote:I just want to have a static library which works both in the simulator and on hardware
You have to use lipo to combine the x86 lib and the arm lib. In the terminal you'd do something like:
lipo myarmlib.a my386lib.a -create -output myfatlib.a
Thanks for that AnotherJake, but it still doesn't work - I'm still getting "symbol not found" compile time errors.
I probably should've made it clearer that I can't compile an application which uses the static library for the simulator at all, whether using the static library compiled for the simulator or compiled for the device.
I probably should've made it clearer that I can't compile an application which uses the static library for the simulator at all, whether using the static library compiled for the simulator or compiled for the device.
Which symbol isn't found?
Personally, I've found it a lot easier to use make and invoke the compiler/archiver directly rather than getting Xcode to do what I want. Here's how I create a 3-way universal iPhone library:
hello.c:
To test and make sure the library was assembled properly:
test.c:
You can also use `file hello.a` to get some info on the library to make sure all of the archs you expect are there. I get this:
Personally, I've found it a lot easier to use make and invoke the compiler/archiver directly rather than getting Xcode to do what I want. Here's how I create a 3-way universal iPhone library:
Code:
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk -mmacosx-version-min=10.5 -D__IPHONE_OS_VERSION_MIN_REQUIRED=30000 -arch i386 -c -o hello_i386.o hello.c
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk -miphoneos-version-min=3.0 -arch armv6 -c -o hello_armv6.o hello.c
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk -miphoneos-version-min=3.0 -arch armv7 -c -o hello_armv7.o hello.c
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ar rc hello_i386.a hello_i386.o
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar rc hello_armv6.a hello_armv6.o
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar rc hello_armv7.a hello_armv7.o
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ranlib hello_i386.a
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib hello_armv6.a
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib hello_armv7.a
lipo -create hello.a hello_i386.a hello_armv6.a hello_armv7.ahello.c:
Code:
#include <stdio.h>
void hello() {
puts("Hello, world!");
}To test and make sure the library was assembled properly:
Code:
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk -mmacosx-version-min=10.5 -D__IPHONE_OS_VERSION_MIN_REQUIRED=30000 -arch i386 test.c hello.a
./a.outtest.c:
Code:
#include <stdlib.h>
void hello();
int main() {
hello();
return EXIT_SUCCESS;
}You can also use `file hello.a` to get some info on the library to make sure all of the archs you expect are there. I get this:
Code:
hello.a: Mach-O universal binary with 3 architectures
hello.a (for architecture i386): current ar archive random library
hello.a (for architecture armv6): current ar archive random library
hello.a (for architecture armv7): current ar archive random library
Thanks for that ThemsAllTook, but it still doesn't work, and now I've somehow broken even the little I had working yesterday; I've listed the process by which I've tried to test creating/using a static library - maybe somebody can see if there are any holes in my process?
- Created a new iPhone OS->Application->OpenGL ES Application using Xcode ("testlib")
- deleted all files from Classes, and deleted "main.m" from Other Sources
- deleted target "testlib"
- created new static library target "testlib"
- created the file "testlib.h" in Classes
Code:
#ifndef testlib_h
#define testlib_h
void InvokeTestLib( int p_int );
#endif - created the file "testlib.cpp" in Classes
Code:
#include "testlib.h"
#include <stdio.h>
void InvokeTestLib( int p_int )
{
fprintf( stderr, "I need scissors! %d!\n", p_int );
return;
} - changed active SDK to Simulator - iPhone OS 2.2; compiled
- changed active SDK to Device - iPhone OS 2.2; compiled
- closed project
- renamed libraries for easier lipo, and copied to a folder
- Code:
lipo libtestlib-iphonesimulator.a libtestlib-iphoneos.a -create -output fatlibtestlib.a - Code:
file fatlibtestlib.a
fatlibtestlib.a: Mach-O universal binary with 2 architectures
fatlibtestlib.a (for architecture i386): current ar archive random library
fatlibtestlib.a (for architecture cputype (12) cpusubtype (6)): current ar archive random library - created a new iPhone OS->Application->OpenGL ES Application using Xcode ("testapp")
- drag/dropped "testlib.h" into Classes
- drag/dropped "fatlibtestlib.a" into Classes
- changed active SDK to Device - iPhone OS 2.2; compiled
- changed active SDK to Simulator - iPhone OS 2.2; compiled
- added line #include "testlib.h" to top of "EAGLView.m"
- added line InvokeTestLib( 1 ); to top of - (void)drawView in "EAGLView.m"
- changed active SDK to Simulator - iPhone OS 2.2; compiled
Code:
compilation failed: Building target “testapp†of project “testapp†with configuration “Debug†— (1 error)
[i][lots & lots cut][/i]
"_InvokeTestLib", referenced from:
-[EAGLView drawView] in EAGLView.o
ld: symbol(s) not found
collect2: ld returned 1 exit status - changed active SDK to Device - iPhone OS 2.2; compiled; ditto
It looks like you've gotten the static library built correctly, but because your implementation file was .cpp instead of .c, InvokeTestLib will have been compiled with C++ function name mangling. I'm a little bit fuzzy on the details (it's been a while), but you'll need to add this around your function prototype in testlib.h:
...and possibly around the implementation in testlib.cpp as well. Or just compile it as C. It also might work to compile EAGLView.m as Objective-C++.
Code:
#ifdef __cplusplus
extern "C" {
#endif
// Function prototype here
#ifdef __cplusplus
}
#endif...and possibly around the implementation in testlib.cpp as well. Or just compile it as C. It also might work to compile EAGLView.m as Objective-C++.
Cheers ThemsAllTook, I thought of that maybe fifteen minutes after I posted but wasn't where I could test it
Tested it, and now I can use the static library both in simulator and device builds... although now I'm very confused as to why my original test didn't work, as the project I dropped the static library into was completely Objective-C++...
Tested it, and now I can use the static library both in simulator and device builds... although now I'm very confused as to why my original test didn't work, as the project I dropped the static library into was completely Objective-C++...
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Static Library | kendric | 9 | 2,952 |
Sep 17, 2009 11:24 AM Last Post: kendric |
|

