I witnessed this error which is reproducible in AppleClang 12.0.0
but not with gcc 7.5.0
. The issue is that I have an extern
variable defined in a static library which a different static library wants to use. The linker states that the symbol for the variable is undefined. I tried to come up with an as minimal as possible repro:
externs.h
extern int A;
a.c
int A;
b.h
void bar();
b.c
#include "externs.h"
#include <stdio.h>
void bar()
{
A = 100;
printf("%d\n", A);
}
main.c
#include "b.h"
int main()
{
bar();
}
makefile
liba.a: a.c
gcc -c a.c -o a.o
ar crs liba.a a.o
libb.a: b.c
gcc -c b.c -o b.o
ar crs libb.a b.o
program: main.c liba.a libb.a
gcc main.c -L. -lb -la -o program
On Linux, this program compiles, links and runs without issue. On macOS (where gcc
is AppleClang
) I get the following output :
gcc -c a.c -o a.o
ar crs liba.a a.o
warning: /Library/Developer/CommandLineTools/usr/bin/ranlib: archive library: liba.a the table of contents is empty (no object file members in the library define global symbols)
gcc -c b.c -o b.o
ar crs libb.a b.o
gcc main.c -L. -lb -la -o program
Undefined symbols for architecture x86_64:
"_A", referenced from:
_bar in libb.a(b.o)
ld: symbol(s) not found for architecture x86_64
AFAICT, the warning is a red herring. If I add a dummy function to a.c
, the warning doesn't show. Further, if I inspect liba.a
with nm
I get the following output:
liba.a(a.o):
0000000000000004 C _A
If I do add a dummy function foo
(which doesn't even refer to A
) to liba.a
and invoke it from main.c
, the linking issue gets magically resolved. It's as if if and only if main.o
is dependent on a symbol in liba.a
, then all the symbols of liba.a
become available to anything that may be dependent on them.