5

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.

Community
  • 1
  • 1
Albert
  • 65,406
  • 61
  • 242
  • 386
  • one question; why you don't create a XCoe Static Library Project and build you Static Library with that project? – CarlJ Jun 16 '12 at 16:03
  • @meccan: I want to have my own compile script in this case for varios reasons (mostly because for this particular project, this is much simpler now). Anyway, even if I would do it with Xcode, this question stays valid/open as I want to understand how to do it manually. – Albert Jun 16 '12 at 16:07
  • okay, and you know you can build a Xcode project from the shell? – CarlJ Jun 16 '12 at 16:07
  • Yes sure. But it would be almost impossible or at least be very annoying to have an Xcode project here (and to update/maintain it). Also, I don't really see the reason to have it in the first place. It's this project: [python-embedded](https://github.com/albertz/python-embedded/). Whereby I want to know this in any case for maybe other future use and just to understand better how it works. – Albert Jun 16 '12 at 16:09
  • 1
    http://mark.aufflick.com/blog/2010/11/18/making-a-fat-static-library-for-ios-device-and-simulator did you checked this site? – CarlJ Jun 16 '12 at 16:09
  • @meccan: That doesn't help because it needs a Xcode project and uses `xcodebuild`. – Albert Jun 16 '12 at 16:11
  • Why use Xcode? Because (a) it's the platform norm, (b) it's simpler, and (c) you wouldn't need to ask this. – Steven Fisher Jun 20 '12 at 14:55
  • @StevenFisher: My question is not necessarily even iPhone/iOS specific. Also, I still want to know, wether using Xcode or not. Also, Xcode is not an option in this case. Also, I guess I would even get the same error in Xcode. – Albert Jun 20 '12 at 15:17
  • I think it's great to know how to do things like this, but were you using Xcode you wouldn't even be using `gcc` as a compiler. It's not Xcode's standard compiler, and isn't even going to be included in the future. It's too bad using Xcode isn't an option for you, because as a result you're going to be cutting against the grain. Cutting with the grain is really important in software development. – Steven Fisher Jun 20 '12 at 15:28
  • Xcode isn't doing anything special. It's just a wrapper around GCC/Clang/libtool/ar/ld and other tools. The recent versions use Clang by default. Really, I just do the same as what Xcode would do. (I just checked. I created a static lib in Xcode and looked at the clang/libtool commands which are executed by Xcode.) Also, you are very much limiting yourself if you don't know this stuff. Also, Xcode is not an option for cross platform development. – Albert Jun 20 '12 at 15:40

2 Answers2

14

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.

Albert
  • 65,406
  • 61
  • 242
  • 386
1

If anyone gets here by searching for the dyld: vm_protect(...) runtime error but you are using XCode, the -static flag mentioned in the OP is likely the issue.

Get rid of it by switching "Enable linking with shared libraries" to "Yes" (the default) in the LLVM compiler language settings. (This removes GCC_LINK_WITH_DYNAMIC_LIBRARIES = NO from the project file).

Alex North
  • 1,189
  • 13
  • 12