gcc 生成共享库
一般是创建共享库的命令如下
gcc -fPIC -c foo.c -o foo.o
gcc -fPIC -c bar.c -o bar.o
gcc -shared foo.o bar.o -o libz.so
gcc main.c -lz -L. -o main
这样生成的共享库还差点意思,完整格式应该同时设置共享库的soname
:
gcc -shared -Wl,-soname,libname.so.x lib foo.o bar.o -o libz.so.x.y.z
SONAME
的作用
linux
下通过共享库实现多程序共享代码;共享库的存放路径以及共享库的版本管理由ldconfig
命令及相关例程负责,其中soname
是实现版本管控的一环。
如果不设置soname,它默认会如何处理?
设置了soname
,在生成的so文件里有[SONAME]
字段。
$ gcc -shared -Wl,-soname,libz2.so.1 -o libz2.so.1.2.0
$ readelf -a libz2.so.1.2.0 | grep -i so
l (large), p (processor specific)
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libz2.so.1]
36: 0000000000200e00 0 OBJECT LOCAL DEFAULT 17 __dso_handle
000000: Version: 1 File: libc.so.6 Cnt: 1
不使用 -Wl,-soname,生成的共享库里面没有[SONAME]
字段。
$ gcc bar.o -shared -o libz.so.1.2.0
$ readelf -a libz.so.1.2.0 | grep -i so
l (large), p (processor specific)
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
39: 0000000000200e10 0 OBJECT LOCAL DEFAULT 19 __dso_handle
000000: Version: 1 File: libc.so.6 Cnt: 1
gcc 编译、链接静态库
gcc -c foo.c -o foo.o
gcc -c bar.c -o bar.o
ar rcs libz.a file1.o file2.o
gcc main.c -lz -L. -o main
是否需要 -fPIC 选项?
Linux 共享库版本控制
gcc -fPIC -g -c -Wall a.c
gcc -fPIC -g -c -Wall b.c
gcc -shared -Wl,-soname,libz.so.1 \
-o libz.so.1.0.1 a.o b.o -lc
为了方便调试,又不想更改环境变量,可以把动态库所在目录的绝对路径(或相对路径)写死在可执行文件中-Wl,-rpath,<DEFAULT_LIB_INSTALL_PATH>
:gcc -Wl,rpath,. main.c -lz -L. -o main
。这样生成的可执行程序,当其运行时,会直接从编译时设置的DEFAULT_LIB_INSTALL_PATH
路径下搜索共享库。
小结
生成最终可执行文件时,对于静态库,需要指定库的名字和库的搜索路径。
对于动态库,编译时指定动态库和库所在的路径;运行时也需要动态库路径,指定方式有
- 使用一般方法,ld.so
- 在连接时,
Program Library HOWTO
鸟哥的Linux私房菜 第二十一章、软体安装:原始码与 Tarball
LINUX下动态库及版本号控制