静态库生成
g++ -c mylib.cpp -o mylib.o
ar rcs libmylib.a mylib.o
动态库生成
g++ -fPIC -shared mylib.cpp -o libmylib.so
-fPIC:生成位置无关代码(Position-Independent Code),对动态库必需。
库文件使用:
静态库:/home/user/libs/libmath.a
静态链接 g++ main.cpp -o app_static -L/home/user/libs -lmath
动态库:/home/user/libs/libmath.so
动态链接 g++ main.cpp -o app_shared -L/home/user/libs -lmath
# 运行前设置动态库路径
export LD_LIBRARY_PATH=/home/user/libs:$LD_LIBRARY_PATH
./app_shared
如果同时存在同名静态库(.a)和动态库(.so),链接器会优先选择动态库(除非显式指定使用静态库)。
例如:当使用 -lmylib 时,链接器会优先查找 libmylib.so,若未找到,再查找 libmylib.a。
若需强制链接静态库
g++ main.cpp -o app -L/path/to/libs -l:mylib.a # 显式指定静态库文件名
# 或
g++ main.cpp -o app /path/to/libs/libmylib.a # 直接指定静态库路径
也可通过 -static 强制所有库静态链接
g++ main.cpp -o app -static -L/path/to/libs -lmylib
链接器通过文件名后缀判断库类型:
静态库:后缀为 .a(Archive),例如 libmylib.a。
动态库:后缀为 .so(Shared Object),例如 libmylib.so
如果文件后缀错误(例如将动态库命名为 .a),链接器会尝试将其当作静态库解析,最终因格式不匹配而报错
可以混合链接
g++ main.cpp -o app \
-Wl,-Bstatic -lstatic_lib1 -lstatic_lib2 \ # 强制静态链接
-Wl,-Bdynamic -lshared_lib1 -lshared_lib2 # 切回动态链接(默认)
-Wl,<option>:将逗号后的内容传递给链接器(如 ld)。
-Bstatic:后续的 -l 库强制静态链接。
-Bdynamic:后续的 -l 库恢复动态链接(默认行为)。
假设程序依赖以下库:
libfoo.a(需静态链接)
libbar.so(需动态链接)
系统库 libm.so(动态链接)
g++ main.cpp -o app \
-Wl,-Bstatic -lfoo \ # 静态链接 libfoo.a
-Wl,-Bdynamic -lbar \ # 动态链接 libbar.so
-lm # 动态链接 libm.so(默认)
如果库文件不在标准路径,可以显式指定路径和文件名:
g++ main.cpp -o app \
/path/to/libfoo.a \ # 直接静态链接 libfoo.a
-L/path/to/shared -lbar # 动态链接 libbar.so
注意事项
1 链接器按从左到右的顺序解析依赖。如果库 A 依赖库 B,则 A 需要放在 B 的左边。例如:
g++ main.cpp -lA -lB # A 依赖 B,正确顺序
2 静态库可能内部依赖其他动态库。若静态库在编译时未正确链接其依赖,可能导致运行时错误。需确保所有依赖都被显式链接。
3 动态链接的库需在运行时能被找到。可通过以下方式指定路径:
export LD_LIBRARY_PATH=/path/to/shared_libs:$LD_LIBRARY_PATH
./app
4 符号冲突
如果静态库和动态库中存在同名符号,链接器可能优先使用静态库中的符号,导致意外行为。需确保库之间的兼容性。
5 某些系统库(如 glibc)通常不建议静态链接,可能导致兼容性问题。
命令最后使用静态库链接时,应当在命令行最后使用动态连接的命令才能正常链接
如:gcc main.cpp -L. -Wl,-Bdynamic -lmydynlib -Wl,-Bstatic -lmystclib -Wl,-Bdynamic
使用pthread库要在命令最后加上 –lpthread
动态库的搜索路径搜索的先后顺序是:
1.编译时指定
2.LD_LIBRARY_PATH指定
3./etc/ld.so.conf指定
4./lib
5./usr/lib