linux静态库和动态库

  函数库是常用公共函数的集合,分为动态库和静态库。

  静态库:程序编译时被链接到目标文件中,程序运行时就不需要此函数库的存在。(不推荐,会重复链接库)

  动态库:程序编译时不链接到目标文件中,程序运行时才链接,所以需要函数库的存在。(推荐方式)

1:静态库

  ./test/libhello/hello1.c

#include <stdio.h>
void print1()
{
        printf("hello1****
");
}

  ./test/libhello/hello2.c

#include <stdio.h>
void print2()
{
        printf("hello2****
");
}

  ./test/test.c

#include<stdio.h>
extern void print1();
extern void print2();//避免 warning: implicit declaration of function "function name"
int main(int argc,char **argv) { print1(); print2(); return 0; }

  1.1 将库文件(hello1.c,hello2.c)编译为.o文件

  ./test/libhello:

    gcc -c hello1.c hello2.c  --> hello1.o hello2.o

  -c : 只编译不链接

  1.2 用.o文件创建静态库

  静态库命名规则:lib+库名.a 比如要创建库hello,则静态库名字必须为libhello.a

  使用命令:

  ./test/libhello:

    ar -r libhello.a hello1.o hello2.o  --> libhello.a

  1.3 使用静态库

  test.c文件需要此静态库,只需要在编译test.c时gcc链接此静态库,静态库中的函数就会在目标文件中声明。

  ./test:

    gcc -o test test.c -L ./libhello -lhello  --> test

  -L:指定gcc在什么位置去链接hello库文件,不指定默认在/usr/lib中去找

  -l(库名):库名hello就对应了静态库libhello.a

  因为链接的是静态库,编译时库函数已经被链接进了目标文件test中,所以删除库文件libhello.a后test程序还是可以正常运行.

2:动态库

  2.1 用.o文件生成动态库

  动态库命名规则:lib+库名.so 比如要创建库hello,则静态库名字必须为libhello.so

  使用命令:

  ./test/libhello:

    gcc -shared -fPCI -o libhello.so hello1.o hello2.o --> libhello.so

    cp libhello.so  /usr/lib (因为动态库是运行时才链接的,链接的默认位置是‘/usr/lib’,所以将.so拷贝至/usr/lib)

  2.2 使用动态库

  ./test:

    gcc -o test test.c -L ./libhello -lhello

  *:也可以在编译的时候指定链接的动态库的位置:gcc -o test test.c -L ./libhello/ -lhello -Wl,-rpath,./libhello/

  这样就不用把库文件拷贝到/usr/lib目录下,目标程序会自动去./libhello文件下去链接

  删除库文件libhello.so执行将出错:

    error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

3:总结

  1:当静态库和动态库同名时(libhello.a和libhello.so),默认使用的是动态库

  2:当一个库文件中有两个同名函数时,应用程序默认链接最前面哪个(比如hello1.o有print(),hello2.o有print(),在制作libhello.a时,ar -f libhello.a hello1.o hello2.o 这时会使用hello1.c中的print()函数)-->(在制作动态库时会提示命名冲突multiple definition of `print')

原文地址:https://www.cnblogs.com/Flychown/p/6612030.html