指定动态库.so运行时/编译时的链接地址 -L, -Xlinker, -Wl,-rpath

559 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、链接的两个过程

关于linux下链接动态库.so文件时时因编译时链接跟运行时链接而出错的一些问题,经过分析得知,gcc编译链接动态库.so有两个链接过程:

  1. 编译时链接:系统会优先从-L指定的路径查找库文件,若没有则从/lib/下查找,所以如果/lib/下面有所需静态库文件,则-L可省略, 链接之后的文件会记住动态库里面相应的函数地址。
  2. 运行时链接:系统会直接在/lib/下查找所需动态库文件,若没有则运行报错,找到后将相应函数定义链接进来然后执行。所以实际上用-L指定动态库文件路径只能保证编译通过,是否能执行还是得看/lib/下面有没有该库文件

二、指定运行时链接的地址

我们如何指定运行时动态库.so的链接地址呢?若采用隐式链接编译可执行程序时,需要在编译时为可执行程序指定运行时动态库搜索地址,即利用rpath选项来告诉链接器在程序执行时到哪里去找它依赖的动态库。例子如下:-Wl,-rpath,<path/to/lib>-Wl,rpath = <path/to/lib>

sc:
	gcc -O2 -mcmodel=large -c $(CFLAGS) -I./include ./libsc.cpp -Os -D_FX_OS_=_FX_LINUX_DESKTOP_
	@-mkdir -p ./scanner/obj
	@mv *.o ./scanner/obj
	@-mkdir -p ./scanner/obj
	gcc -O2 -mcmodel=large -fPIC -shared -o ./libsc.so ./scanner/obj/*.o -L./scanner/winmage  -Xlinker "-(" -Wl,-rpath=./scanner/winmage -lwinmage -Xlinker "-)"  -lz -ldl
	rm -rf ./scanner/obj

	gcc -Wall demosc.c -ldl -o demosc
	./demosc

参考:

关于linux下链接动态库.so文件时时因编译时链接跟运行时链接而出错的一些问题,以及-L -l的意义

指定运行时动态库搜索位置:-rpath链接指令的正确用法(相对路径or绝对路径)