动态库和静态库
# 动态库和静态库
- 静态库是程序在编译链接的时候把库的代码复制到可执行文件当中的,生成的可执行程序在运行的时候将不再需要静态库,因此使用静态库生成的可执行程序的大小一般比较大。
- 优点:
使用静态库生成可执行程序后,该可执行程序就可以独自运行,不再需要库了。
- 缺点:
使用静态库生成可执行程序会占用大量空间,特别是当有多个静态程序同时加载而这些静态程序使用的都是相同的库,这时在内存当中就会存在大量的重复代码。
- 动态库是程序在运行的时候才去链接相应的动态库代码的,多个程序共享使用库的代码。一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
在可执行文件开始运行前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接。动态库在多个程序间共享,节省了磁盘空间,操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
- 优点:
节省磁盘空间,且多个用到相同动态库的程序同时运行时,库文件会通过进程地址空间进行共享,内存当中不会存在重复代码。
- 缺点:
必须依赖动态库,否则无法运行。
# 打包静态库
首先,我们简单写一个案例:
- add.cpp
#include "add.h"
void add(int a, int b) {
cout << a << " + " << b << " = " << a+b;
}
1
2
3
4
5
2
3
4
5
- add.h
# pragma once
#include <iostream>
using namespace std;
extern void add(int a, int b);
1
2
3
4
5
6
7
2
3
4
5
6
7
- test.cpp
#include "add.h"
int main() {
int a = 100;
int b = 20;
add(a, b);
cout << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- Makefile
test:test.cpp
g++ -o test add.cpp test.cpp
.PHONY: clean
clean:
rm -f test
1
2
3
4
5
2
3
4
5
执行make命令,编译生成可执行文件test,执行./test,输出结果为:100 + 20 = 120
# 源文件生成目标文件
当前目录文件:
-rw-r--r-- 1 cen cen 136 Mar 20 20:25 add.cpp
-rw-r--r-- 1 cen cen 89 Mar 20 20:14 add.h
-rw-r--r-- 1 cen cen 78 Mar 20 20:26 Makefile
-rwxr-xr-x 1 cen cen 17056 Mar 20 20:27 test
-rw-r--r-- 1 cen cen 199 Mar 20 20:27 test.cpp
[cen@VM-4-9-opencloudos lesson02-动静态库]$ g++ -c add.cpp
[cen@VM-4-9-opencloudos lesson02-动静态库]$ ll
total 40
-rw-r--r-- 1 cen cen 136 Mar 20 20:25 add.cpp
-rw-r--r-- 1 cen cen 89 Mar 20 20:14 add.h
-rw-r--r-- 1 cen cen 2736 Mar 20 20:53 add.o
-rw-r--r-- 1 cen cen 78 Mar 20 20:26 Makefile
-rwxr-xr-x 1 cen cen 17056 Mar 20 20:27 test
-rw-r--r-- 1 cen cen 199 Mar 20 20:27 test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# ar命令将目标文件生成静态库
ar命令是gnu的归档工具,常用于将目标文件打包为静态库,下面我们使用ar命令的-r选项和-c选项进行打包。
- -r(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。
- -c(create):建立静态库文件。
[cen@VM-4-9-opencloudos lesson02-动静态库]$ ar -rc libcal.a add.o
[cen@VM-4-9-opencloudos lesson02-动静态库]$ ll
total 44
-rw-r--r-- 1 cen cen 136 Mar 20 20:25 add.cpp
-rw-r--r-- 1 cen cen 89 Mar 20 20:14 add.h
-rw-r--r-- 1 cen cen 2736 Mar 20 20:53 add.o
-rw-r--r-- 1 cen cen 2882 Mar 20 20:55 libcal.a
-rw-r--r-- 1 cen cen 78 Mar 20 20:26 Makefile
-rwxr-xr-x 1 cen cen 17056 Mar 20 20:27 test
-rw-r--r-- 1 cen cen 199 Mar 20 20:27 test.cpp
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 将头文件和生成的静态库组织起来
当我们把自己的库给别人用的时候,实际上需要给别人两个文件夹,一个文件夹下面放的是一堆头文件的集合,另一个文件夹下面放的是所有的库文件。
因此,在这里我们可以将add.h头文件放到一个名为include的目录下,将生成的静态库文件libcal.a放到一个名为lib的目录下,然后将这两个目录都放到mathlib下,此时就可以将mathlib给别人使用了。
[cen@VM-4-9-opencloudos lesson02-动静态库]$ mkdir -p mathlib/include
[cen@VM-4-9-opencloudos lesson02-动静态库]$ mkdir -p mathlib/lib
[cen@VM-4-9-opencloudos lesson02-动静态库]$ cp ./*.h mathlib/include
[cen@VM-4-9-opencloudos lesson02-动静态库]$ cp ./*.a mathlib/lib
[cen@VM-4-9-opencloudos lesson02-动静态库]$ tree mathlib
mathlib
├── include
│ └── add.h
└── lib
└── libcal.a
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 使用Makefile
mylib=libcal.a
CC=gcc
$(mylib):add.o
ar -rc -o $(mylib) $^
%.o:%.c
$(CC) -c $<
.PHONY: clean
clean:
rm -f $(mylib) ./*.o
.PHONY:output
output:
mkdir -p mathlib/include
mkdir -p mathlib/lib
cp ./*.h mathlib/include
cp ./*.a mathlib/lib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用静态库
[root@VM-4-9-opencloudos ~]# cp -r /home/cen/Linux/lesson02-动静态库/mathlib ./main
[root@VM-4-9-opencloudos ~]# ll
total 0
drwxr-xr-x 3 root root 21 Mar 20 21:57 main
[root@VM-4-9-opencloudos ~]# cd main
[root@VM-4-9-opencloudos main]# ll
total 0
drwxr-xr-x 4 root root 32 Mar 20 21:57 mathlib
[root@VM-4-9-opencloudos main]# touch main.cpp
[root@VM-4-9-opencloudos main]# vim main.cpp
[root@VM-4-9-opencloudos main]# ll
total 4
-rw-r--r-- 1 root root 100 Mar 20 21:58 main.cpp
drwxr-xr-x 4 root root 32 Mar 20 21:57 mathlib
[root@VM-4-9-opencloudos main]# g++ main.cpp -I./mathlib/include -L./mathlib/lib -lcal
[root@VM-4-9-opencloudos main]# ll
total 24
-rwxr-xr-x 1 root root 17056 Mar 20 21:59 a.out
-rw-r--r-- 1 root root 100 Mar 20 21:59 main.cpp
drwxr-xr-x 4 root root 32 Mar 20 21:57 mathlib
[root@VM-4-9-opencloudos main]# ./a.out
100 + 300 = 400
[root@VM-4-9-opencloudos main]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
使用root用户拷贝普通用户所写的库,进行调用。
# 打包动态库
# 源文件生成目标文件
[cen@VM-4-9-opencloudos lesson02-动静态库]$ g++ -fPIC -c add.cpp
[cen@VM-4-9-opencloudos lesson02-动静态库]$ ll
total 44
-rw-r--r-- 1 cen cen 136 Mar 20 20:25 add.cpp
-rw-r--r-- 1 cen cen 89 Mar 20 20:14 add.h
-rw-r--r-- 1 cen cen 2824 Mar 20 22:20 add.o
-rw-r--r-- 1 cen cen 2882 Mar 20 20:55 libcal.a
-rw-r--r-- 1 cen cen 247 Mar 20 21:44 Makefile
drwxr-xr-x 4 cen cen 32 Mar 20 20:58 mathlib
-rwxr-xr-x 1 cen cen 17056 Mar 20 20:27 test
-rw-r--r-- 1 cen cen 199 Mar 20 20:27 test.cpp
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# shared命令将目标文件生成动态库
[cen@VM-4-9-opencloudos lesson02-动静态库]$ g++ -shared -o libcal.so add.o
[cen@VM-4-9-opencloudos lesson02-动静态库]$ ll
total 60
-rw-r--r-- 1 cen cen 136 Mar 20 20:25 add.cpp
-rw-r--r-- 1 cen cen 89 Mar 20 20:14 add.h
-rw-r--r-- 1 cen cen 2824 Mar 20 22:20 add.o
-rw-r--r-- 1 cen cen 2882 Mar 20 20:55 libcal.a
-rwxr-xr-x 1 cen cen 16320 Mar 20 22:21 libcal.so
-rw-r--r-- 1 cen cen 247 Mar 20 21:44 Makefile
drwxr-xr-x 4 cen cen 32 Mar 20 20:58 mathlib
-rwxr-xr-x 1 cen cen 17056 Mar 20 20:27 test
-rw-r--r-- 1 cen cen 199 Mar 20 20:27 test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 将头文件和生成的静态库组织起来
mkdir -p mathlib/include
mkdir -p mathlib/lib
cp ./*.h mathlib/include
cp ./*.so mathlib/lib
1
2
3
4
2
3
4
# 使用Makefile
mylib=libcal.a
CC=gcc
$(mylib):add.o
ar -rc -o $(mylib) $^
%.o:%.c
$(CC) -fPIC -c $<
.PHONY: clean
clean:
rm -f $(mylib) ./*.o
.PHONY:output
output:
mkdir -p mathlib/include
mkdir -p mathlib/lib
cp ./*.h mathlib/include
cp ./*.so mathlib/lib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用动态库
[root@VM-4-9-opencloudos ~]# cp -r /home/cen/Linux/lesson02-动静态库/mathlib ./main
[root@VM-4-9-opencloudos ~]# ll
total 0
drwxr-xr-x 3 root root 37 Mar 21 10:31 main
[root@VM-4-9-opencloudos ~]# cd main
[root@VM-4-9-opencloudos main]# ll
total 4
-rw-r--r-- 1 root root 100 Mar 20 21:59 main.cpp
drwxr-xr-x 4 root root 32 Mar 21 10:31 mathlib
[root@VM-4-9-opencloudos main]# tree mathlib
mathlib
├── include
│ └── add.h
└── lib
└── libcal.so
2 directories, 2 files
[root@VM-4-9-opencloudos main]# g++ main.cpp -I./mathlib/include -L./mathlib/lib -lcal
[root@VM-4-9-opencloudos main]# ll
total 24
-rwxr-xr-x 1 root root 16784 Mar 21 10:32 a.out
-rw-r--r-- 1 root root 100 Mar 20 21:59 main.cpp
drwxr-xr-x 4 root root 32 Mar 21 10:31 mathlib
[root@VM-4-9-opencloudos main]# ./a.out
./a.out: error while loading shared libraries: libcal.so: cannot open shared object file: No such file or directory
[root@VM-4-9-opencloudos main]# ldd a.out
linux-vdso.so.1 (0x00007ffe3f1d9000)
libcal.so => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007ff43f400000)
libm.so.6 => /lib64/libm.so.6 (0x00007ff43f69d000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ff43f67d000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff43f20c000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff43f789000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
发现操作系统找不到动态库,因此可以将动态库拷贝到系统共享库路径下。
[root@VM-4-9-opencloudos main]# cp ./mathlib/lib/libcal.so /usr/lib64/
[root@VM-4-9-opencloudos main]# ldd a.out
linux-vdso.so.1 (0x00007ffe3f1d9000)
libcal.so => /usr/lib64/libcal.so (0x00007f0f0b0b6000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f0f0aef5000)
libm.so.6 => /lib64/libm.so.6 (0x00007f0f0adb4000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f0f0ab9d000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0f09f9b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0f0b2c8000)
[root@VM-4-9-opencloudos main]# ./a.out
100 + 300 = 400
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
上次更新: 2025/05/04, 22:48:52