c - 为什么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 上(在哪里gcc
)AppleClang
,我得到以下输出:
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.a
,nm
我会得到以下输出:
liba.a(a.o):
0000000000000004 C _A
如果我确实添加了一个虚拟函数foo
(甚至不引用A
)liba.a
并从中调用它main.c
,链接问题就会神奇地解决。就好像当且仅当 main.o
依赖于 中的符号liba.a
,那么所有liba.a
可能依赖于它们的符号都变得可用。
解决方案
推荐阅读
- ruby-on-rails - 将 ruby 中间件导出到 node.js
- sql - 带有布尔值和排序的 SQL 语句
- r - 在 R 中子集数据帧后拆分的奇怪行为
- android - OpenGL ES 2.0 圆形纹理在混合时具有可见轮廓
- javascript - 具有固定标题和可变列宽的反应虚拟化网格
- c# - 在不并行触发的情况下定义任务
- android - 如何在不手动更改谷歌帐户设置的情况下运行 AIA?
- javascript - 如何让 VS Code 智能感知识别附加到现有类的新方法
- methods - 两阶段最小二乘法
- r - 在 for 循环中的函数内部创建的图未正确存储到 R 中的列表中