首页 > 解决方案 > 为什么clang报告静态库中引用的外部变量的未定义符号

问题描述

我目睹了这个错误,它可以在中重现,AppleClang 12.0.0但在gcc 7.5.0. 问题是我extern在静态库中定义了一个变量,另一个静态库要使用该变量。链接器声明变量的符号未定义。我试图提出尽可能少的复制:

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

在 Linux 上,该程序可以毫无问题地编译、链接和运行。在 macOS 上(在哪里gccAppleClang,我得到以下输出:

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,警告是红鲱鱼。如果我向 中添加虚拟函数a.c,则不会显示警告。此外,如果我进行检查liba.anm我会得到以下输出:

liba.a(a.o):
0000000000000004 C _A

如果我确实添加了一个虚拟函数foo(甚至不引用Aliba.a 从中调用它main.c,链接问题就会神奇地解决。就好像当且仅当 main.o依赖于 中的符号liba.a那么所有liba.a可能依赖于它们的符号都变得可用。

标签: clinker-errors

解决方案


推荐阅读