GCC编译动态链接库简介#
1. 编写测试文件#
- hello.c
#include <stdio.h>
void print_hello(void)
{
printf("Hello Linux!\n");
}
- test.c
void print_hello(void);
int main()
{
print_hello();
return 0;
}
- 验证程序是否能被正确编译执行
gcc test.c hello.c -o test
./test
2.编译动态链接库并测试#
- 将hello.c编译为动态链接库
gcc -fpic -shared hello.c -o libhello.so
注意:动态链接库的命名规则必须是libxxx.so,其中xxx是你的库名
参数 | 含义 |
---|---|
-fpic | 指明编译为位置无关码 |
-shared | 指明编译为动态链接库 |
- 引用动态链接库libhello.so
# 编译test.c
gcc test.c -L. -lhello -o test
注意:test.c的位置必须在参数
-L. -lhello
之前
参数 | 含义 |
---|---|
-L. | 库的搜索路径 - 告诉链接器要链接的库文件在当前目录下 |
-lhello | 库的名字 - 告诉链接器要链接的库的名字是libhello.so |
- 执行测试文件
# 执行
./test
直接执行将会出现如下错误:
./test: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
意思是说在执行test程序的时候找不到其依赖的libhello.so库文件。
这是怎么回事呢?
Linux系统在执行程序的时候,首先会到系统默认的 /lib 和 /usr/lib 目录取寻找库文件;如果找不到就通过读取 /etc/ld.so.cache 文件获得其他的可搜索路径。
而 /etc/ld.so.cache 是 ldconfig 程序读取 /etc/ld.so.conf 文件生成的,所以我们把 libhello.so 所在的路径添加到 /etc/ld.so.conf 中,再以root权限运行 ldconfig 程序,更新 /etc/ld.so.cache ,运行时,就可以找到 libhello.so。
或者直接修改环境变量 LD_LIBRARY_PATH=. 告诉Linux系统执行test程序的时候,请在当前目录寻找依赖库。
综上所述,我们有3个解决方案:
方案1:
# 首先将libhello.so添加到系统默认库搜索目录
sudo cp libhello.so /usr/lib/
# 或者
sudo cp libhello.so /lib/
# 编译test.c
gcc test.c -L. -lhello -o test
# 执行
./test
方案2:
# 打开文件
sudo vim /etc/ld.so.conf
# 然后在其末尾添加你的动态链接库路径,eg:
/path/to/your_lib_dir
# 使配置生效
sudo ldconfig
# 编译test.c
gcc test.c -L. -lhello -o test
# 执行
./test
方案3
LD_LIBRARY_PATH=. ./test
3.查看程序的依赖库#
$ ldd test
linux-vdso.so.1 (0x0000007fa0ffb000)
libhello.so => /home/pi/mydata/libhello.so (0x0000007fa0f80000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fa0e27000)
/lib/ld-linux-aarch64.so.1 (0x0000007fa0fd0000)
4.使用cmake编译动态链接库#
cmake_minimum_required(VERSION 3.10)
project(the_project VERSION 1.0.1)
add_library(hello SHARED hello.c)
# compile
mkdir build && cd build
cmake ..
make
#link
cd ..
gcc test.c -Lbuild -lhello