Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to link a static library for iOS

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 aris 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/clangbut 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.

like image 464
Albert Avatar asked Jun 16 '12 15:06

Albert


People also ask

How do I link a static library?

Static libraries are created by copying all necessary library modules used in a program into the final executable image. The linker links static libraries as a last step in the compilation process. An executable is created by resolving external references, combining the library routines with program code.

What is static library in iOS?

Static library - a unit of code linked at compile time, which does not change. However, iOS static libraries are not allowed to contain images/assets (only code). You can get around this challenge by using a media bundle though.

How do I import a static library?

Link Static Library to your AppRight-click on your libStaticLibrary. a choose Show in Finder, copy files and put them to a created new folder which the name “lib” in the root folder of your project. Create new single view application or open your project where you want to use your library.


1 Answers

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.

like image 142
Albert Avatar answered Oct 18 '22 16:10

Albert