动态库和静态库
链接分为两种:静态链接、动态链接
静态链接: 由链接器在链接时将库的内容加入到可执行程序中
优点:
缺点:
动态链接: 连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序。
优点:
缺点:
前面我们编写的应用程序大量用到了标准库函数,系统默认采用动态链接的方式进行编译程序,若想采用静态编译,加入-static参数
以下是分别采用动态编译、静态编译时文件对比
测试程序(test.c)如下:
#include
int main(void)
{
printf("he11o world n");
return 0;
}
编译:
# 动态库
deng@itcast:-/test$ gcc test.c -o test share
# 静态库
deng@itcast:-/test$ gcc -static test.c -o test_static
所谓“程序库”,简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其他执行程序的一部分来完成模型功能。
库的存在可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。
程序库可分入静态库(static library)和共享库(shared library)。
定义add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int x, int y);
#endif /*__ADD_H__*/
定义add.c
#include "add.h"
int add(int x, int y) {
return x + y;
}
定义sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int x, int y);
#endif /*__SUB_H__*/
sub.c
#include "sub.h"
int sub(int x, int y) {
return x - y;
}
定义测试程序test.c
#include
#include "add.h"
#include "sub.h"
int main(void)
{
int x = 15;
int y = 5;
printf("x + y = %d\n", add(x, y));
printf("x - y = %d\n", sub(x, y));
return 0;
}
编译运行
### 编译
```bash
gcc add.c sub.c test.c
# 或者
gcc *.c
执行
./a.out
静态库可以认为是一些目标代码的集合,是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分。按照习惯一般以”.a”做为文件后缀名。静态库的命名一般分为三个部分:
deng@itcast:-/test/3static_lib$ gcc -c add.c -o add.o
deng@itcast:-/test/3static_lib$ gcc -c sub.c -o sub.o
deng@itcast:-/test/3static_lib$ gcc -c mul.c -o mul.o
deng@itcast:-/test/3static_lib$ gcc -c div.c -o div.o
deng@itcast:-/test/3static lib$ ar -rcs libtest.a add.o sub.o mulo div.o
在使用ar工具是时候需要添加参数: rcs
静态库制作完成之后,需要将.a文件和头文件一起发布给用户。
假设测试文件为main.c,静态库文件为libtest.a头文件为head.h编译命令:
deng@itcast:-/test/4static$ gcc test.c -I./ -L./ -ltest -o test
参数说明:
共享库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规辟了空间浪费问题
动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署和发布也会带来麻烦。用户只需要更新动态库,增量更新。
按照习惯,一般以“.so”做为文件后缀名。共享库的命名般分为三个部分
gcc -fPIC -c add.c
gcc -fPIC -c sub.c
参数: -fPIC 创建与地址无关的编译程序 (pic,position independent code) ,是为了能够在多个应用程序间共享。
gcc -shared add.o sub.o -o libtest.so
root@sony-HP-Notebook:/usr/local/cpp_demo/library# nm libtest.so | grep add
00000000000010f9 T add
gcc test.c -I./ -L./ -ltest
$# ldd a.out
linux-vdso.so.1 (0x00007ffc2eb32000)
libtest.so (0x00007ff241178000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff240f71000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff241184000)
nm libtest.so | grep add
拷贝目录,拷贝自己制作的共享库到/lib或者/usr/lib(不能是/lib64目录)
临时设置LD_LIBRARY_PATH:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径
永久设置1,把export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
:库路径,设置到~/.bashrc或者/etc/profile
文件中
# 编辑.bashrc最后一行添加如下内容:
deng@itcast:-/share/3rd/2share test$ vim ~/.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cpp_test/library/test
# 或者执行文件夹
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cpp_test/library/
# 使环境变量生效
source ~/.bashrc
/etc/ld.so.conf
文件中sudo vim /etc/ld.so.conf
# 文件最后添加动态库路径(绝对路径)
/usr/local/cpp_test/library/test
# 使生效
sudo ldconfig -v
sudo ln -s /usr/local/cpp_demo/library/libtest.so /lib/libtest.so