linux之动态库和静态库编译

Linux 中 动态库和静态库编译和使用

为了更好的表述,这里写了一个简单的示例代码 示例代码 源代码链接

代码目录结构为:

.
├── hello          # 写的一个hello示例库
│   ├── hello.c
│   ├── include
│   │   └── hello.h
│   └── makefile
├── main.c         # 使用main函数去使用上面的库
└── makefile

其中 hello.c内容:

#include "include/hello.h"
void say_hello(char * name){
    printf("Hello, %s!\n", name);
}

其中 hello.h内容:

#include
void say_hello(char *name);

其中 main.h内容:

#include
int main(){
    say_hello("Tom");
}

静态库编译

切换目的到hello, 执行一下命令可生成静态库

gcc -c -o hello.o hello.c -fpic # 编译源文件hello.c 到目标文件hello.o 
ar -rc  libhello.a hello.o  # ar 打包成一个静态库  

其中gcc的 -fpic 标志含义是:生成使用相对地址无关的目标代码

注意: 静态库要以lib开头,和.a结束 的方式命名

动态库的编译

切换目的到hello, 执行一下命令可生成动态库

gcc -c -o hello.o hello.c -fpic # 编译源文件hello.c 到目标文件hello.o 
gcc -shared -fpic -o libhello.so hello.o   # 生成动态库  

注意: 动态库要以lib开头,和.so结束 的方式命名

如果你下载我提供的代码,也可以直接使用make编译

静态库的使用

切换目录回到主目录, 编译main.c 并使用刚才编译好的静态库

gcc -c -o main.o main.c -Ihello/include # 这里-Ihello/include 指定头文件查找目录为相对路径hello/include 
                        # 这一定要指定头文件查找目录的,不然找不到main.c中使用的hello.h 
gcc -o main_a  main.o -Lhello -lhello -static 
# 这里 -Lhello 指定库查找目录为相对路径hello
# -lhello 指定需要链接的库为hello, 优先链接libhello.so,如何找不到就链接libhello.a  
# -static 指定要链接静态库, 因为hello目录中同时存在静态库和动态库,所以需要特别指定

最后生成 main_a , 可以直接通过 ./main_a 运行

动态库的使用

切换目录回到主目录, 编译main.c 并使用刚才编译好的动态库

gcc -c -o main.o main.c -Ihello/include 
gcc -o main_so main.o  -Lhello -lhello -Wl,-rpath=./hello 

相比使用静态库,使用动态库需要指定的查找目录 -Wl,-rpath=./hello
这里指定的目录,是编译完成的程序运行的时候,去找依赖的动态库的路径,如果你没有指定,程序会
到系统默认的路径去找,如果没有找到会报错(如下)

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

最后生成 main_so , 可以直接通过 ./main_so 运行

动态库和静态库的区别

  1. 链接时不同
    静态库链接的时候,会把静态库中自己需要的代码复制到自己的程序里面去。
    动态库链接的时候,只会检查一下动态库只是否有自己程序需要的代码,不会复制。
  2. 运行时不同
    静态库因为链接时已经把相关代码复制进程序了,所以运行时不再依赖静态库。
    相反,使用动态的程序在运行时需要去找依赖的动态库,如果找不到会导致无法运行。

静态库优点

  • 运行效率高些,无需依赖,简单方便。

动态库的优点

  • 节约内存(主要体现在:因为动态库可多个程序共享一份,当多个程序都在使用这个动态库时,内存中只加载一份)
  • 节约时间(如果库修改代码,只需要重新编译动态库,然后替换掉原先的库。相反静态库需要编译所有使用这个库的程序)


你可能感兴趣的:(linux之动态库和静态库编译)