how to link a static library for iOS

build, gcc, ios, ld, static-libraries

Solution

It all works now. Basically, the answer is:

Just compile every `*.c` file as usual to `*.o` files. The only real difference is the different GCC/Clang, the `-arch armv7`, the different SDK / include dirs.

Use `libtool -static -o libfoo.a *.o` to build the static library.

That's it. The other problems in my question were just wrongly headed tries.

Problem

I have create a bunch of `.o` files (via `gcc -c $file.c $someotherops -o $file.o`). Now I want to link them into a static library. I'm not exactly sure wether I am supposed to use `ld` or `gcc` for this. In the `ld` manual, it is said that I'm not supposed to use it directly. However, I cannot figure out the gcc parameters to create a static library. I tried `ld *.o -static -o libfoo.a` but it complains about a lot of missing symbols (I think all from libc). I don't understand why it complains because it is supposed to be a static library. I thought it would check for the symbols once I link that static library to some other thing. Another thing: I use `/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld` here (my target is iOS). It complains with the warning `ld: warning: using ld_classic`. What is this about? Then I thought, maybe it needs to have the dynamic libraries specified. So I added `-lc` to link against libc. But it complains with `can't locate file for: -lc`. I added `-L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/lib` and there is a `libc.dylib`. Any ideas? About the `-lc` error: It got away after I specified `-arch armv6`. Then it complained about a wrong `libcache.dylib` (which must be linked from `libc.dylib` I guess because it didn't specified it). Adding `-L.../usr/lib/system` helped. Now, for each single `.o` file, I get the warning `ld: warning: CPU_SUBTYPE_ARM_ALL subtype is deprecated`. What is this about? And I still have a bunch of missing symbols, esp: ``` Undefined symbols for architecture armv6: "start", referenced from: -u command line option (maybe you meant: _PyThread_start_new_thread) "___udivsi3", referenced from: _get_len_of_range in bltinmodule.o _quorem in dtoa.o _array_resize in arraymodule.o _newarrayobject in arraymodule.o _array_fromfile in arraymodule.o _get_len_of_range in rangeobject.o _inplace_divrem1 in longobject.o ... "___unorddf2", referenced from: _builtin_round in bltinmodule.o ... ``` I checked some of those symbols, e.g. `___udivsi3` in `get_len_of_range`. This function uses C arithmetic only, no external call. So this seems to be translated to use some external functions like `___udivsi3`. But what libraries is this in? `-lgcc_s.1` fixed most of the `___udivsi3` and related missing symbols. The `start` symbol is still missing. What does `-u command line option` mean? From here, I got the feeling that maybe `ld` isn't the right tool after all. There, a simple call to `ar`is used. And this seem to make more sense. I will check if that does work and transform this into an answer then. While playing more around, `ar` throw some warnings at me when building a fat static library. It gave me the hint to use `libtool` instead. That is what I'm doing now, i.e. `libtool -static -o libfoo.a *.o`. Also I switched the compiler to `/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang`but not sure if that matters. Now, at compiling some test application which links to this static library, I get these warnings: ``` ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in __PyBuiltin_Init from /Users/az/Programmierung/python-embedded/libpython.a(bltinmodule.o). To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie ld: warning: 32-bit absolute address out of range (0x1001B70C4 max is 4GB): from _usedpools + 0x00000004 (0x001B70CC) to 0x1001B70C4 ld: warning: 32-bit absolute address out of range (0x1001B70C4 max is 4GB): from _usedpools + 0x00000000 (0x001B70CC) to 0x1001B70C4 ``` What are they about? I don't use `-mdynamic-no-pic`. I also don't really see in `_PyBuiltin_Init` how I use absolute addressing there. Also, what are these absolute addresses out of range about? Edit: These were some really huge allocations. I just removed this code for now (this was `WITH_PYMALLOC`, if anyone is interested in these specific Python internals). When I start it on my iPhone, I get the abort: `dyld: vm_protect(0x00001000, 0x00173000, false, 0x07) failed, result=2 for segment __TEXT in /var/mobile/Applications/C15D9525-E7DC-4463-B05B-D39C9CA24319/...` When I use `-no_pie` for linking, it doesn't even link. It fails with: `Illegal text-relocation to ___stderrp in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/libSystem.dylib from _read_object in /Users/az/Programmierung/python-embedded/libpython.a(marshal.o) for architecture armv7` I solved the PIE disabled, Absolute addressing error. I had a `-static` in my command line Clang. Once I removed that, the warning got away, as well as the dyld/vm_protect error. It was the first time it actually run some code. Until I hit another strange error about integer comparison. Whereby this looks more like a bug in their Clang build.

Original source

Related problems