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.