Linux關於.so動態庫的那些事

在linux系統下,可以通過ldd來查看,程序運行時要鏈接的動態庫路徑,如下圖:
在這裏插入圖片描述
一、程序編譯時鏈接的動態庫
通過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;(未進行驗證)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章