Linux关于.so动态库的那些事

在linux系统下,可以通过ldd来查看,程序运行时要链接的动态库路径,如下图:
Linux关于.so动态库的那些事_第1张图片
一、程序编译时链接的动态库
通过gcc的-L参数指定库的路径

LDFLAGS     := -L/usr/local/ffmpeg_build/x264/lib -L/usr/local/ffmpeg_build/ffmpeg/lib  \
                   -lx264 \
                   -lavcodec \
                   -lavdevice \
                   -lavfilter \
                   -lavformat \
                   -lavutil \
                   -lswscale \
                   -lswresample \
                   -lpostproc \

二、程序运行时链接的动态库
关于运行时链接动态库的路径查找顺序
1、验证一:
a、Makeflie如下:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ cat Makefile 
# Makefile for sample program
.PHONY			: all clean

# the program to build
NAME			:=ffmpeg_toh264

# Build tools and flags
CXX			:= gcc
LD			:= gcc

OBJS        := ffmpeg_toh264.o

CPPFLAGS    := -I/usr/local/ffmpeg_build/ffmpeg/include
LDFLAGS     := -L/usr/local/ffmpeg_build/x264/lib -L/usr/local/ffmpeg_build/ffmpeg/lib  \
                   -lx264 \
                   -lavcodec \
                   -lavdevice \
                   -lavfilter \
                   -lavformat \
                   -lavutil \
                   -lswscale \
                   -lswresample \
                   -lpostproc \
               -Wl,-rpath=/home/muyangren/ffmpeg/lib


all			: $(NAME)

$(NAME)		: $(OBJS)
	$(LD) -o $@ $^ $(CPPFLAGS) $(LDFLAGS)
	$(RM)  *.o

%.o		    : ./%.c
	$(CXX) $(CPPFLAGS) -c -o $@ $<

clean	    :
	$(RM) *.o $(NAME)

Makefile中使用了-Wl,-rpath=/…来指定链接动态库时的查找路径。

b、.bashrc中设置如下:

export LD_LIBRARY_PATH=/home/muyangren/catkin_ws/devel/lib:/opt/ros/kinetic/lib:/opt/ros/kinetic/lib/x86_64-linux-gnu:/usr/local/cuda-8.0/lib64:/usr/local/cuda-8.0/extras/CUPTI/lib64:/usr/local/ffmpeg_build/ffmpeg/lib

终端查看环境变量如下:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ env | grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=/home/muyangren/catkin_ws/devel/lib:/opt/ros/kinetic/lib:/opt/ros/kinetic/lib/x86_64-linux-gnu:/usr/local/cuda-8.0/lib64:/usr/local/cuda-8.0/extras/CUPTI/lib64:/usr/local/ffmpeg_build/ffmpeg/lib

c、/etc/ld.so.conf.d/ffmpeg.conf文件如下并已执行ldconfig:

muyangren@muyangren-N85-87HP6:~$ cat /etc/ld.so.conf.d/ffmpeg.conf 
#home/muyangren/ffmpeg/lib
/usr/local/ffmpeg_build/ffmpeg/lib
/usr/local/ffmpeg_build/x264/lib

执行make后,使用ldd查看,结果:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ ldd ffmpeg_toh264
	linux-vdso.so.1 =>  (0x00007f1f445e7000)
	libavcodec.so.58 => /home/muyangren/ffmpeg/lib/libavcodec.so.58 (0x00007f1f42f18000)
	libavdevice.so.58 => /home/muyangren/ffmpeg/lib/libavdevice.so.58 (0x00007f1f42d07000)
	libavformat.so.58 => /home/muyangren/ffmpeg/lib/libavformat.so.58 (0x00007f1f428b4000)
	libavutil.so.56 => /home/muyangren/ffmpeg/lib/libavutil.so.56 (0x00007f1f4263e000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1f4222b000)
	libswresample.so.3 => /home/muyangren/ffmpeg/lib/libswresample.so.3 (0x00007f1f4200d000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1f41d04000)
	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f1f41ae2000)
	libz.so.1 => /usr/local/lib/libz.so.1 (0x00007f1f418c5000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1f416a8000)
	libavfilter.so.7 => /home/muyangren/ffmpeg/lib/libavfilter.so.7 (0x00007f1f4120f000)
	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f1f40fec000)
	libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f1f40de8000)
	libxcb-shape.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shape.so.0 (0x00007f1f40be4000)
	libxcb-xfixes.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0 (0x00007f1f409db000)
	libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f1f407cb000)
	/lib64/ld-linux-x86-64.so.2 (0x0000559610707000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1f405c6000)
	libswscale.so.5 => /home/muyangren/ffmpeg/lib/libswscale.so.5 (0x00007f1f4033b000)
	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f1f40137000)
	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f1f3ff30000)

说明-Wl, -rpath指定的路径要比LD_LIBRARY_PATH中的路径优先级高。
2、验证二:
a、将Makefile中的-Wl, -rpath参数去掉
b、.bashrc修改如下:

export LD_LIBRARY_PATH=/home/muyangren/catkin_ws/devel/lib:/opt/ros/kinetic/lib:/opt/ros/kinetic/lib/x86_64-linux-gnu:/usr/local/cuda-8.0/lib64:/usr/local/cuda-8.0/extras/CUPTI/lib64:/home/muyangren/ffmpeg/lib

终端查看环境变量如下:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ env | grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=/home/muyangren/catkin_ws/devel/lib:/opt/ros/kinetic/lib:/opt/ros/kinetic/lib/x86_64-linux-gnu:/usr/local/cuda-8.0/lib64:/usr/local/cuda-8.0/extras/CUPTI/lib64:/home/muyangren/ffmpeg/lib

c、/etc/ld.so.conf.d/ffmpeg.conf文件不做修改
执行make后,使用ldd查看,结果:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ ldd ffmpeg_toh264
	linux-vdso.so.1 =>  (0x00007fff3b31d000)
	libavcodec.so.58 => /home/muyangren/ffmpeg/lib/libavcodec.so.58 (0x00007f6ed4957000)
	libavdevice.so.58 => /home/muyangren/ffmpeg/lib/libavdevice.so.58 (0x00007f6ed4746000)
	libavformat.so.58 => /home/muyangren/ffmpeg/lib/libavformat.so.58 (0x00007f6ed42f3000)
	libavutil.so.56 => /home/muyangren/ffmpeg/lib/libavutil.so.56 (0x00007f6ed407d000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6ed3c6a000)
	libswresample.so.3 => /home/muyangren/ffmpeg/lib/libswresample.so.3 (0x00007f6ed3a4c000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6ed3743000)
	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f6ed3521000)
	libz.so.1 => /usr/local/lib/libz.so.1 (0x00007f6ed3304000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6ed30e7000)
	libavfilter.so.7 => /home/muyangren/ffmpeg/lib/libavfilter.so.7 (0x00007f6ed2c4e000)
	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f6ed2a2b000)
	libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f6ed2827000)
	libxcb-shape.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shape.so.0 (0x00007f6ed2623000)
	libxcb-xfixes.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0 (0x00007f6ed241a000)
	libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f6ed220a000)
	/lib64/ld-linux-x86-64.so.2 (0x0000556909fb3000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6ed2005000)
	libswscale.so.5 => /home/muyangren/ffmpeg/lib/libswscale.so.5 (0x00007f6ed1d7a000)
	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f6ed1b76000)
	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f6ed196f000)

d、再将.bashrc改回如下:

export LD_LIBRARY_PATH=/home/muyangren/catkin_ws/devel/lib:/opt/ros/kinetic/lib:/opt/ros/kinetic/lib/x86_64-linux-gnu:/usr/local/cuda-8.0/lib64:/usr/local/cuda-8.0/extras/CUPTI/lib64:/usr/local/ffmpeg_build/ffmpeg/lib

终端下查看环境变量:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ env | grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=/home/muyangren/catkin_ws/devel/lib:/opt/ros/kinetic/lib:/opt/ros/kinetic/lib/x86_64-linux-gnu:/usr/local/cuda-8.0/lib64:/usr/local/cuda-8.0/extras/CUPTI/lib64:/usr/local/ffmpeg_build/ffmpeg/lib

执行make后,使用ldd查看,结果:

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ ldd ffmpeg_toh264
	linux-vdso.so.1 =>  (0x00007ffdbc78c000)
	libavcodec.so.58 => /usr/local/ffmpeg_build/ffmpeg/lib/libavcodec.so.58 (0x00007f82bfa1a000)
	libavdevice.so.58 => /usr/local/ffmpeg_build/ffmpeg/lib/libavdevice.so.58 (0x00007f82bf809000)
	libavformat.so.58 => /usr/local/ffmpeg_build/ffmpeg/lib/libavformat.so.58 (0x00007f82bf3b6000)
	libavutil.so.56 => /usr/local/ffmpeg_build/ffmpeg/lib/libavutil.so.56 (0x00007f82bf140000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f82bed2d000)
	libswresample.so.3 => /usr/local/ffmpeg_build/ffmpeg/lib/libswresample.so.3 (0x00007f82beb0f000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f82be806000)
	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f82be5e4000)
	libz.so.1 => /usr/local/lib/libz.so.1 (0x00007f82be3c7000)
	libx264.so.157 => /usr/local/ffmpeg_build/x264/lib/libx264.so.157 (0x00007f82bde97000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f82bdc7a000)
	libavfilter.so.7 => /usr/local/ffmpeg_build/ffmpeg/lib/libavfilter.so.7 (0x00007f82bd793000)
	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f82bd571000)
	libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f82bd36d000)
	libxcb-shape.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shape.so.0 (0x00007f82bd168000)
	libxcb-xfixes.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0 (0x00007f82bcf60000)
	libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f82bcd50000)
	/lib64/ld-linux-x86-64.so.2 (0x000056094bcb0000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f82bcb4b000)
	libswscale.so.5 => /usr/local/ffmpeg_build/ffmpeg/lib/libswscale.so.5 (0x00007f82bc8c0000)
	libpostproc.so.55 => /usr/local/ffmpeg_build/ffmpeg/lib/libpostproc.so.55 (0x00007f82bc6a3000)
	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f82bc49f000)
	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f82bc299000)

根据以上验证,运行时动态库的搜索路径的先后顺序是:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib和/usr/lib;(未进行验证)

你可能感兴趣的:(linux操作系统)