5.15 vs2019 静态编译_链接过程中静态库先后顺序的影响分析

问题描述

项目中准备引入redis,采用acl的c++库对redis进行访问。acl的示例代码如下所示

#include 

对示例代码进行编译链接

`

报了许多链接的错误

(aio_listen_stream.o

问题分析

acl和acl_cpp均为静态库,acl是最基础的库,以C语言实现,其它库均依赖于该库; acl_cpp库用C++封装了acl库,提供给C++程序调用。

链接错误集中表现为acl_cpp库引用了acl库中的函数但未能找到其定义。

问题解决

在编译命令的参数中已给出了acl库的路径和名称,不应该找不到。尝试把acl_cpp库在命令行中的顺序放在acl库之前

`

顺利编译通过。

原理探究

创建一个示例工程,包含main.c、comp1_func1.c、comp1_func2.c、comp2_func1.c四个文件,其函数调用关系如下所示:

e330b228d4dac450c6e1472b3d933562.png
  • 编译main.c
0000000000000000         *UND*  

main.o中有两个未定义的符号:comp1_func1和comp2_func1

  • 编译静态库
0000000000000000 g     F .text  000000000000000e comp1_func1

comp1_func2.o:     文件格式 elf64-x86-64

libcomp2.a中有一个未定义的符号comp1_func2

  • 增量链接 将main.o和libcomp1.a先进行链接
0000000000000000 l    df *ABS*  

链接器并不是把静态库文件看做一个整体,而是将打包在其中的目标文件(.o)作为链接单元。在链接过程中,如果某个目标文件中的符号被用到了,那么这个目标文件会单独从库文件中提取出来并入可执行程序,而其余的目标文件则会被丢弃。

main.o中引用了libcomp1.a中comp1_func1.o的comp1_func1函数,因此将comp1_func1.o并入,而comp1_func2.o中的comp1_func2函数未被引用,因此被丢弃。

  • 全量链接 将main.o和libcomp1.a、libcomp2.a进行链接
0000000000000000         *UND*  

libcomp2.a中引用的comp1_func2函数虽然已在libcomp1.a中定义,但由于comp1_func2.o被丢弃,导致该函数找不到定义

0000000000000021 g     F .text  000000000000000e comp1_func1

整个分析的过程可参考下图:

5c8167937a3e1a84047f7abff35e55a9.png

将静态库的顺序调换后,所有符号都找到了定义。所以在链接静态库的时候,应该将被依赖的库放在最右边。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值