使用clang链接器的C档案(库)的基本用法

时间:2014-07-31 03:51:53

标签: c linker clang libraries ar

我有一个主程序:

#include <stdio.h>
extern int a;
int main (int argc, char ** argv) {
    int i;
    printf ("Hello %p, %p\n", & i, & a);
    return 0;
}

和一个单独的文件foo.c,其中包含我对变量a的定义:

int a;

如果我这样建造:

clang -c main.c foo.c
clang main.o foo.o
./a.out
一切都很好。但是,如果我执行以下操作:

ar rvs bar.a foo.o

我收到警告,我不明白

r - foo.o
warning: /<elided>/ranlib: 
warning for library: bar.a the table of contents is empty 
(no object file members in the library define global symbols)

所以我检查了我的图书馆,确保我的符号在那里

nm bar.a

bar.a(foo.o):
0000000000000004 C _a

然后我做

clang main.o bar.a

我收到以下错误

Undefined symbols for architecture x86_64:
  "_a", referenced from:
      _main in main-5121f1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我错过了什么?

1 个答案:

答案 0 :(得分:1)

我认为问题在于int a;中的foo.c是一个暂定的定义。它在C的输出中标记为nm(常用)。如果你明确初始化(为了0的一致性;为了确保测试目的而使用一些非零值),我相信你没有问题。

我并不完全相信,因为在TU结束时,暂定的定义应转换为定义:

  

ISO / IEC 9899:2011§6.9.2外部对象定义

     

¶2具有没有初始化程序的文件范围的对象的标识符声明,和   没有存储类说明符或存储类说明符静态,构成一个   暂定的定义。如果翻译单元包含一个或多个临时定义   然后,标识符和转换单元不包含该标识符的外部定义   行为就像翻译单元包含该文件范围声明一样   标识符,具有复制类型,如翻译单元的末尾,带有初始化程序   等于0。

另见How do I share a variable between source files in C?