Better llvm-ld support for frameworks on Mac OS X

[ resending after subscribing ]

I would like to be able to compile and link the following two program into native executables. These are a vastly reduced testcase, so ignore for a moment the fact that the native compiler driver might have default -L/-F search paths and -lSystem by default.

$ cat test1.c
extern char *zlibVersion(void);
extern int puts(char *);

int main(int argc, char *argv) {
    puts(zlibVersion());
    return 0;
}
$ clang test1.c -emit-llvm | llvm-as | llvm-ld - -native -L/usr/lib -lSystem -lz -v
Generating Bitcode To a.out.bc
Generating Assembly With:
'/Volumes/HD/ltmp/ssen/src/llvm/Debug/bin/llc' '-f' '-o' 'a.out.s' 'a.out.bc'
Generating Native Executable With:
'/usr/bin/gcc' '-fno-strict-aliasing' '-O3' '-o' 'a.out' 'a.out.s' '-L' '/usr/lib' '-lSystem' '-lz'
ld: in /usr/lib, can't map file, errno=22
collect2: ld returned 1 exit status
llvm-ld:
$ cat test2.c
extern void *kCFRunLoopCommonModes;
extern void CFShow(void *);
int main(int argc, char *argv) {
    CFShow(kCFRunLoopCommonModes);
    return 0;
}
$ clang test2.c -emit-llvm | llvm-as | llvm-ld - -native -F/System/Library/Frameworks -framework CoreFoundation -L/usr/lib -lSystem -v
llvm-ld: Unknown command line argument '-F/System/Library/Frameworks'. Try: 'llvm-ld --help'
llvm-ld: Unknown command line argument '-framework'. Try: 'llvm-ld --help'

There are a few issues preventing this from working. For one thing, although llvm-ld and the native gcc parse "-L foo" with an optional space, the native ld(1) linker on Mac OS X does not accept an intervening space, and so considers /usr/lib as an input file.

-F and -framework are not currently parsed by llvm-ld when creating native binaries.

The attached patch implements this functionality. Now:

$ clang test1.c -emit-llvm | llvm-as | llvm-ld - -native -L/usr/lib -lSystem -lz -v
Generating Bitcode To a.out.bc
Generating Assembly With:
'/Volumes/HD/ltmp/ssen/src/llvm/Debug/bin/llc' '-f' '-o' 'a.out.s' 'a.out.bc'
Generating Native Executable With:
'/usr/bin/gcc' '-fno-strict-aliasing' '-O3' '-o' 'a.out' 'a.out.s' '-L/usr/lib' '-lSystem' '-lz'
$ ./a.out
1.2.3
$ clang test2.c -emit-llvm | llvm-as | llvm-ld - -native -F/System/Library/Frameworks -framework CoreFoundation -L/usr/lib -lSystem -v
Generating Bitcode To a.out.bc
Generating Assembly With:
'/Volumes/HD/ltmp/ssen/src/llvm/Debug/bin/llc' '-f' '-o' 'a.out.s' 'a.out.bc'
Generating Native Executable With:
'/usr/bin/gcc' '-fno-strict-aliasing' '-O3' '-o' 'a.out' 'a.out.s' '-L/usr/lib' '-F/System/Library/Frameworks' '-lSystem' '-framework' 'CoreFoundation'
$ ./a.out
kCFRunLoopCommonModes

llvm-ld.framework-support.patch (2.36 KB)

Looks great, applied:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080121/057631.html

Thanks Shantonu!

-Chris