Reputation: 17554
I'd like to build a portable static C library that can be linked into macOS binaries regardless of macOS version. The C library does not have any dependencies (i.e. no stdlib, no OS specific calls). The only dependency is the CPU which has to be x86_64.
When extracting the relevant compiler triplet, I get x86_64-apple-darwin16.7.0
for Sierra, and x86_64-apple-darwin17.2.0
for High Sierra. Also, when I build on High Sierra, there is a warning if I use the static library from Sierra (even when I specify --target x86_64-apple-darwin16.7.0
for clang).
How can I build a truly portable static library for macOS? If it is not possible, what is the way to go? One different version per major macOS release that is built from the same release? Some hackery by copying SDKs from outdated Xcode versions? Keep in mind, my library is completely portable and does not depend on macOS or the stdlib in any way.
Does the version part at the end of the compiler triplet matter?
Upvotes: 7
Views: 6758
Reputation: 22402
You can just create a static library directly by using macosx libtool
Here's what I just tested out on 3 different versions of Mac OS X (Sierra, High Sierra and Mavrick):
$ ls -al
⏎
total 64 drwxr-xr-x 8 masud staff 272 Dec 5 11:12 . drwxr-xr-x 7 masud staff 238 Dec 5 10:35 .. -rw-r--r-- 1 masud staff 386 Dec 5 11:11 Makefile -rwxr-xr-x 1 masud staff 8464 Dec 5 10:38 bar -rw-r--r-- 1 masud staff 69 Dec 5 11:11 bar.c -rw-r--r-- 1 masud staff 53 Dec 5 11:10 foo.c -rw-r--r-- 1 masud staff 84 Dec 5 11:11 foo.h -rw-r--r-- 1 masud staff 83 Dec 5 11:11 test.c
$ cat Makefile
⏎
LIBTOOL=libtool
STATIC=-static
LIBFOO_A=libfoo.a
SRC=foo.c bar.c
OBJ=$(SRC:.c=.o)
LIBFOOCFLAGS=-mmacosx-version-min=10.1
TESTSRC=test.c
TESTCFLAGS=-mmacosx-version-min=10.7
$(LIBFOO_A): $(OBJ)
$(LIBTOOL) $(STATIC) -o $@ $(OBJ)
%.o: %.c
$(CC) $(LIBFOOCFLAGS) -c -o $@ $<
test: $(LIBFOO_A) test.c
$(CC) $(TESTCFLAGS) -o $@ test.c -L. -lfoo
clean:
$(RM) test $(LIBFOO_A) $(OBJ)
$ cat foo.c
⏎
int foo(void) {
volatile int a = 0;
return a;
}
$ cat foo.h
⏎
#ifndef __FOO_H
#define __FOO_H
extern int foo(void);
#endif
$ cat bar.c
⏎
#include "foo.h"
int bar(int k) {
return k-1;
}
In my tests, libfoo.a could be generated on any (of the three) platform(s) and copied to any (of the three) platform(s) and be used to generate test
locally.
nm test
on all three shows library statically linked into the binary.
Hope this helps.
P.S.: macosx libtool is NOT the same as the gnu libtool except in name. Completely different usage and functionality. the macosx libtool is essentially AR + ranlib + some darwinisms.
Upvotes: 6