01-gcc的链接器在链接多个库时要注意顺序:被依赖的库应该放在依赖它的库之后
链接顺序规则为:
被依赖的库应该放在依赖它的库之后。
换种说法,越是被别人调用的越底层的库,就越放在后面;越是调用别人的越上层的库,就越放在前面。
比如我在Makefile中书写规则时,如果有库ts
和库m
需要链接,并且库ts
需要依赖于库m
,那么我需要像下面这样写:
LDFLAGS := -lts -lm
- 1
这里不作具体的原因分析,这就是gcc的一个规则和机制,死记住就行了。
02-gcc的链接器在链接库时去哪里查找库?
默认的库搜索路径
默认的库搜索路径如下:
-
标准系统库路径:
/usr/lib
/usr/local/lib
- 系统架构相关的库路径(如
/lib/x86_64-linux-gnu
或/usr/lib64
)
-
环境变量指定的路径:
- 环境变量
LD_LIBRARY_PATH
中的路径。- 例如:如果库
libts.so
位于/custom/lib
,可以通过以下命令添加路径:export LD_LIBRARY_PATH=/custom/lib:$LD_LIBRARY_PATH
- 1
- 例如:如果库
- 环境变量
-
Makefile 显式指定路径(因为包含):
说明:因为链接库的命令常常发生在Makefile文件中,所以这里以Makefile文件中的写法为例。
如果libts
不在默认路径中,可以通过-L
指定自定义路径。例如,如果库位于/opt/lib
,可以这样修改:LDFLAGS := -L/opt/lib -lts
- 1
如果库ts
放在Makefile 文件所在目录的子目录 lib 中,可以像下面这样写:
TOPDIR := $(shell pwd)
LDFLAGS := -L$(TOPDIR)/lib -lts
- 1
- 2
如何用命令查看链接器的库搜索路径
假如命令:
arm-buildroot-linux-gnueabihf-gcc -v
- 1
能正常执行,那么可以用下面这条命令可以查看对应的gcc的链接器的库搜索路径:
arm-buildroot-linux-gnueabihf-ld --verbose
- 1
运行结果截图如下:
截图中红框的内容如下:
SEARCH_DIR("=/home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/host/arm-buildroot-linux-gnueabihf/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
- 1
这说明其搜索路径如下:
/home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/host/arm-buildroot-linux-gnueabihf/lib
/usr/local/lib
/lib
/usr/lib
我们可以把我们编译好的第三方库文件放在/usr/local/lib
中,原因是从下面的三张截图中可以看出,/usr/local/lib
才应该是给用户放库的地方。
/usr/local/lib
的截图如下:
/lib
的截图如下:
/usr/lib
的截图如下:
03-如何从给gcc链接器的参数推测库的全名?
以参数 -lts 和 -lm 为例进行说明。
-lts
:表示链接名为libts
的库。这里的ts
是库的名字,GCC 会查找名为libts.so
(动态库)或libts.a
(静态库)的文件。-lm
:表示链接名为libm
的数学库。m
是数学库的名字,GCC 会查找名为libm.so
或libm.a
的文件。
库名称解释
-l
:-l
选项后跟的是库的名称,不需要包含前缀lib
或扩展名(如.so
或.a
)。例如:-lts
对应的库是libts.so
或libts.a
。-lm
对应的库是libm.so
或libm.a
。
链接过程
- 动态库:GCC 会首先寻找
.so
文件(如libts.so
或libm.so
)。 - 静态库:如果找不到动态库,GCC 会继续查找
.a
文件(如libts.a
或libm.a
)。

昊虹嵌入式技术交流群
QQ群名片


评论记录:
回复评论: