GCC静态库与动态库链接顺序的深坑

ops/2024/10/24 18:42:35/

有三个工程文件,A为SDL2动态库,B为基于A的静态库,C为基于A和B的主程序EXE,现在发现这个问题:

在C程序链接器命令的时候,通常像这种写法-lSDL2 -lLibB,此时就会报B报错找不到A中的函数,但是如果交换顺序-lLibB -lSDL2就正常了,这是为何?

这是由于链接器的工作方式导致的,主要涉及到静态库和动态库之间的依赖顺序问题。

链接器的解析顺序

链接器在解析库时是 从左到右 的顺序工作的。当它遇到一个库时,它会试图从这个库中解析之前遇到但未解析的符号。这意味着,如果某个库需要依赖另一个库中的符号,这两个库在链接命令中的顺序至关重要。

链接顺序问题的解释

当你使用 -lSDL2 -lLibB 时:

链接器首先遇到 -lSDL2,但此时没有未解析的符号需要解析。

接下来遇到 -lLibB,其中包含了对 SDL2 库的函数调用,但由于链接器已经经过了 SDL2 库,且没有记录下来这些未解析的符号,所以此时 LibB 无法解析这些函数,导致报错。

当你使用 -lLibB -lSDL2 时:

链接器首先遇到 -lLibB,其中包含了对 SDL2 中函数的调用,但这些符号尚未解析,链接器将它们标记为待解析。

接下来遇到 -lSDL2,此时链接器可以解析之前 LibB 中未解析的 SDL2 函数,从而解决所有符号的依赖,链接成功。

关键点

从左到右解析:链接器在处理库时是从左到右的,所以当它遇到一个库时,只会解析已经遇到的未解析符号。如果某个库依赖另一个库中的符号,那个被依赖的库必须在依赖库之后列出。

静态库与动态库:静态库(LibB)中未解析的符号需要动态库(SDL2)提供,而链接器只会在遇到这些未解析符号后继续寻找它们的定义。因此,SDL2 必须在 LibB 之后列出,以确保 LibB 中的未解析符号能够被 SDL2 解析。

解决方法

保持 -lLibB -lSDL2 的顺序,确保静态库 LibB 依赖的 SDL2 动态库在其之后进行链接。

总结

链接器从左到右依次处理库,因此需要将被依赖的库(如 SDL2)放在依赖库(如 LibB)的后面,以确保符号能够被正确解析。这就是为什么 -lLibB -lSDL2 正常,而 -lSDL2 -lLibB 会导致 LibB 无法找到 SDL2 中的符号的原因。


http://www.ppmy.cn/ops/128126.html

相关文章

Centos编写mysql备份脚本

1. 编写 MySQL 备份脚本 创建一个名为 backup.sh 的脚本,定期备份 fuint-food 数据库。 #!/bin/bash # 获取当前时间戳 TIMESTAMP$(date "%F-%H%M") # 备份存储路径 BACKUP_DIR"/path/to/backup/$TIMESTAMP" # MySQL 相关信息 MYSQL_USER&quo…

Linux运维篇-误操作已经做了pv的磁盘导致pv异常

目录 故障场景排错过程小结 故障场景 在对/dev/vdb1创建了pv并扩容至vg(klas)之后,不小心对/dev/vdb进行了parted操作,删除了/dev/vdb1导致pvs查看显示异常。具体过程如下所示: 正常创建pv 将创建好的pv添加到系统现有的卷组中 不小心又对…

怎么提取pdf的某一页?批量提取pdf的某一页的简单方法

怎么提取pdf的某一页?在日常工作与学习中,我们经常会遇到各式各样的PDF文件,它们以其良好的兼容性和稳定性,成为了信息传输和存储的首选格式。然而,在浩瀚的文档海洋中,有时某个PDF文件中的某一页内容尤为重…

RHCE的练习(5)

虚拟目录 第一步: 关闭防火墙(因为要与外部连接访问) [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0第二步: 创建新IP地址(用于区分) [rootlocalhost ~]# nmcli connecti…

京东商品详情API全攻略:返回值字段一网打尽

京东商品详情API是京东开放平台提供的一个重要接口,它允许开发者获取京东平台上商品的详细信息。这些信息对于电商从业者、数据分析师以及需要进行商品信息监控和比价的开发者来说非常有价值。下面是一份京东商品详情API的全攻略,包括返回值字段的详细解…

C++基础

C 进一步扩充和完善了 C 语言&#xff0c;像Java一样它也是一种面向对象的程序设计语言。 上一篇&#xff1a;C语言基础 1. 程序结构 让我们逐帧分析 #include <iostream> using namespace std;// main() 是程序开始执行的地方int main() {cout << "Hello …

2024软考-《软件设计师》-易混淆知识点总结(1~6章)

一、计算机组成与体系结构 1.1、原码、反码、补码、移码的运算 原码&#xff1a;最高位表示符号位&#xff0c;其余低位表示数值的绝对值&#xff08;0表示正数&#xff0c;1表示负数&#xff09; 反码&#xff1a;正数的反码与原码相同&#xff0c;负数的反码是其绝对值按位…

24.10.20(换根哈希)

星期一&#xff1a; 阴间场 cf渡劫成功&#xff0c;拿下三题&#xff0c;终于上蓝&#x1f973;&#x1f973;&#x1f973; 贴 cf round978 div2 C cf传送门 答案取到n1但初始化没到n1&#xff0c;wa了一发&#xff0c;很烦&#x1f63f;…