C归档文件(库)与Clang链接程序的基本用法 [英] basic use of C archives (libraries) with clang linker

查看:119
本文介绍了C归档文件(库)与Clang链接程序的基本用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主程序:

  #include< stdio.h>外部intint main(int argc,char ** argv){我printf("Hello%p,%p \ n",& i,& a);返回0;} 

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

  int a; 

如果我这样建造:

  clang -c main.c foo.clang main.o foo.o./a.out 

一切都很好.但是,如果我执行以下操作:

  ar rvs bar.a foo.o 

我收到我不明白的警告

  r-foo.o警告:/< elided>/ranlib:库警告:bar.a目录为空(库中没有目标文件成员定义全局符号) 

所以我检查我的书架,确保其中有我的符号

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

然后我

  clang main.o bar.a 

我收到以下错误

 体系结构x86_64的未定义符号:"_a",引用自:_main在main-5121f1.o中ld:找不到架构x86_64的符号clang:错误:链接器命令失败,退出代码为1(使用-v查看调用) 

我想念什么?

我认为麻烦是 foo.c 中的 int a; 是一个暂定的定义.在 nm 的输出中将其标记为 C (常见).如果您明确初始化(为保持一致性,将代码初始化为 0 ;将其初始化为某个非零值以确保用于测试目的),我相信您不会有任何问题.

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

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

¶2 具有文件作用域的对象的标识符声明,没有初始值设定项,以及如果没有存储类说明符或静态存储类说明符,则构成一个暂定的定义.如果翻译单元包含一个或多个临时定义,标识符,并且转换单元不包含该标识符的外部定义,然后该行为与翻译单元中包含的文件作用域声明完全相同标识符,具有转换单元末尾的复合类型,并带有初始化程序等于0.

另请参见

and a separate file, foo.c, which contains my definition for the variable a:

int a;

If I build like this:

clang -c main.c foo.c
clang main.o foo.o
./a.out

all is well. But, if I do the following:

ar rvs bar.a foo.o

I get a warning that I don't understand

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)

so I check my library, ensuring that my symbol is in there

nm bar.a

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

and then I do

clang main.o bar.a

I get the following error

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)

what did I miss?

I think the trouble is that the int a; in foo.c is a tentative definition. It is marked C (common) in the output from nm. If you explicitly initialized (to 0 for consistency; to some non-zero value to make sure for testing purposes), I believe you'd have no problem.

I'm not completely convinced because at the end of a TU, tentative definitions should be converted to definitions:

ISO/IEC 9899:2011 §6.9.2 External Object Definitions

¶2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

See also How do I share a variable between source files in C?

这篇关于C归档文件(库)与Clang链接程序的基本用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆