Etan
Etan

Reputation: 17554

How to build a portable static C library for macOS

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).

Upvotes: 7

Views: 6758

Answers (1)

Ahmed Masud
Ahmed Masud

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.

on macosx libtool

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

Related Questions