有如下几个文件
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()重定义的错误。
阅读(3009) | 评论(0) | 转发(0) |