当前位置: 首页 > news >正文

Linux动态库静态库总结

静态库生成
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
 

相关文章:

  • 运行Spark程序-在shell中运行1
  • 如何通过外卖系统源码打造本地O2O外卖配送生态?全链路技术解析
  • Java练习题:String
  • python文件打包成exe文件
  • SQLMesh信号机制详解:如何精准控制模型评估时机
  • 笔记项目 day02
  • 【日撸 Java 300行】Day 14(栈)
  • Pytorch学习笔记(二十二)Audio - Audio I/O
  • 数据工具:数据同步工具、数据血缘工具全解析
  • 最终一致性和强一致性
  • 大模型—— FastGPT 知识库无缝集成到 n8n 工作流 (基于 MCP 协议)
  • 论文《Collaboration-Aware Graph Convolutional Network for Recommender Systems》阅读
  • NY182NY183美光固态颗粒NY186NY188
  • 推荐几个常用免费的文本转语音工具
  • 王炸组合!STL-VMD二次分解 + Informer-LSTM 并行预测模型
  • 物理:从人体组成角度能否说明基本粒子的差异性以及组织结构的可预设性?
  • 传输层协议UDP
  • Logisim实验--华科计算机组成原理(保姆级教程) 头歌-存储系统设计实验(汉字库存储芯片扩展实验、MIPS寄存器文件设计)
  • 编译docker版openresty
  • huggingface transformers中Dataset是一种什么数据类型
  • 日本前卫艺术先驱群展上海:当具体派相遇古树古宅
  • 持续8年仍难终了的纠纷:败诉方因拒执罪被立案,胜诉方银行账户遭冻结
  • 央行等印发《关于金融支持广州南沙深化面向世界的粤港澳全面合作的意见》
  • 外交部:中方期待印巴巩固和延续停火势头,避免冲突再起
  • 江西省司法厅厅长张强已任江西省委政法委分管日常工作副书记
  • 面对非专业人士,科学家该如何提供建议