lib.c:
#includeint 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:
#includeint c() { printf("in %s\\n", __func__); return 0; }
c.h:
#ifndef _C_H_ #define _C_H_ int c(); #endif
t.c:
#include "t.h" #includeint 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()重定义的错误。