gcc生成静态库、动态库


0. 静态库.a和动态库.so的区别:

静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。

1. 生成静态库:

假设有这样一个cpp程序hello.c

#include "hello.h"
void sayhello()
{
  printf("hello,world ");
}
  1. 生成目标文件hello.o:
gcc -o hello.o -c hello.c
  1. 使用ar(archive)将hello.o打包成libhello.a静态库
ar -rc libhello.a hello.o

解释一下ar后带的参数:
?? -r :表示将.o文件插入到.a中
?? -c : 表示创建一个静态库文件
?? -d : 表示删除这个静态库文件
?? -t : 表示列出.a文件中所有成员

  1. 编译main.c文件并链接libhello.a
gcc -o app_static -c main.c libhello.a

2. 生成动态库:

  1. 生成目标文件hello.o:
gcc -fPIC -o hello.o -c hello.c //-fPIC 表示编译为位置独立(地址无关)的代码,不用此选项的话,编译后的代码是位置相关的,所以动态载入时,是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
  1. 生成动态库文件hello.so
gcc -shared -o hello.so hello.o  //-shared 指定生成动态连接库

1和2可以连在一起写

ar -shared -fPIC -o hello.so hello.c
  1. 编译main.c文件并链接libhello.so
gcc -o app_shared main.c -L. -lhello
//或者直接写出动态库路径
gcc -o main main.c ./libhello.so 

解释一下动态库链接时后的参数:
?? -L : 指定编译器在搜索动态库时搜索的路径,"."意思是当前路径
?? -l (小写l) :一般加库文件名,即hello,如果在—L的路径下找不到,就去LD_LIBRARY_PATH等环境变量的路径下去查找
?? -I (大写i) : 指定路径为首要路径进去搜索头文件,-I/home/include/就表示搜索头文件从:/home/include/
--> /usr/include --> /usr/local/include

  1. 提一嘴:修改linux下动态库的环境变量: LIBRARY_PATHLD_LIBPARY_PATH
    LIBRARY_PATH:gcc编译时查找动态库的指定存放路径
    LD_LIBPARY_PATH:程序运行加载时要查找动态库的指定存放路径
export LIBRARY_PATH=/home/other/test/lib:$LIBRARY_PATH
export LD_LIBPARY_PATH=/home/other/test/lib:$LD_LIBPARY_PATH

如果不希望退出终端,这个添加路径就失效,永久添加方法:
修改 ~/.bashrc或者系统下的/etc/profile
添加例如export LD_LIBRARY_PATH=/home/other/test/lib:$LD_LIBRARY_PATH
保存,./bashrc