Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165537
  • 博文数量: 30
  • 博客积分: 296
  • 博客等级: 二等列兵
  • 技术积分: 407
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-16 21:37
个人简介

a

文章分类

全部博文(30)

文章存档

2016年(1)

2015年(8)

2014年(1)

2013年(11)

2012年(6)

2011年(1)

2010年(2)

分类: C/C++

2013-01-27 17:01:56

有如下几个文件
lib.c:
#include 

int a()
{
    printf("lib in %s\\n", __func__);
    return 0;
} 

int b()
{
    printf("lib in %s\\n", __func__);
    return 0;
} 

int c()
{
    printf("lib in %s\\n", __func__);
    return 0;
} 

lib.h:

#ifndef _LIB_H_
#define _LIB_H_

int a();
int b();
int c();

#endif


c.c:

#include 

int c()
{
    printf("in %s\\n", __func__);
    return 0;
} 

c.h:

#ifndef _C_H_
#define _C_H_

int c();

#endif


t.c:

#include "t.h"
#include 

int t()
{
    printf("in %s start.\\n", __func__);
    printf("in %s end.\\n", __func__);
    return 0;
} 


t.h:
#ifndef _O_H_
#define _O_H_

int t();

#endif


main.c:

#include 
#include 
#include 

int main(int argc, char *argv[ ])  
{
    c();
    t();
    //a();
    return 0; 
} 

c.c文件和lib.c文件中都有函数c()。

下面是Makefile的内容。
SRCS=t.c c.c main.c 
OBJS=$(SRCS:.c=.o) 

.c.o:
    gcc -I. -c $<

m:$(OBJS) liblib.a 
    gcc -o $@ -I. -L. $(OBJS) -llib 

liblib.a:lib.o
    ar -cr liblib.a lib.o

clean:
    -rm $(OBJS) lib.o liblib.a m


如果main函数中没有调用liblib.a中的函数a(),则根据Makefile可以正常进行编译链接。
如下所示:
lzj@lzj-Inspiron-560s:~/study/test/test_lib$ make
gcc -I. -c t.c
gcc -I. -c c.c
gcc -I. -c main.c
gcc -I. -c lib.c
ar -cr liblib.a lib.o
gcc -o m -I. -L. t.o c.o main.o -llib 

如果将main函数中对函数a()的调用的屏蔽去掉,则链接时就会出现函数c()重复定义的错误。
如下所示:
lzj@lzj-Inspiron-560s:~/study/test/test_lib$ make
gcc -I. -c t.c
gcc -I. -c c.c
gcc -I. -c main.c
gcc -I. -c lib.c
ar -cr liblib.a lib.o
gcc -o m -I. -L. t.o c.o main.o  -llib 
./liblib.a(lib.o): In function `c':
lib.c:(.text+0x44): multiple definition of `c'
c.o:c.c:(.text+0x0): first defined here
collect2: ld 返回 1
make: *** [m] 错误 1

由以上结果可以知道,链接器在链接时是优先查找目标文件中的函数,目标文件中
不存在时才会去静态库中查找。
既使调用的函数在目标文件和静态库中同时存在,只要没有调用只在静态库中存在的函数,
那么也会优先链接目标文件中的函数,而不会报函数重定义的错误。
另外,上面的结果与链接时的顺序也没有关系(静态库在目标文件的前面或后面)。
gcc -o $@ -I. -L. $(OBJS) -llib 和 gcc -o $@ -I. -L. -llib $(OBJS)

的执行结果是一样的。


另外,如果函数a()在另一个目标文件(比如a.o)中,并且这个文件与lib.o不在同一目录,

由a.o和lib.o生成静态库liblib.a,这样即使在main函数中调用函数a(),链接也能正常进行而不会报

函数c()重定义的错误。


阅读(2961) | 评论(0) | 转发(0) |
0

上一篇:isdigit的使用

下一篇:Makefile备忘

给主人留下些什么吧!~~