ubuntu---记录.动态库默认路径的踩坑

发现这个问题,还是经过一个报错问题卡了好多天,然后请求好多人的支援,最后个人的疑问:为什么明明指明了路径,生成 .SO 没有问题,在调用.SO 就有问题,报错各种找不到函数或者未定义,然后把缺的 *.so 都一顿拷贝至 /lib  或者 /usr/lib 中 有时又可以解决问题,但不是每次都好用 ?   --- linux动态链接库的加载顺序。

linux动态链接库的加载顺序:
它有5个地方会查找,
1. 编译时指定的run path
2. LD_LIBRARY_PATH 指定的地方
3. ldconfig 指定的地方
4. /lib
5. /usr/lib

其它说明:    pos1 通过readelf -d test 可以看到(RPATH) Library rpath: [pos1]    pos2 需要用LD_LIBRARY_PATH 说明。此例为: export LD_LIBRARY_PATH=./pos2    pos3 需要在/etc/ld.so.conf 中指明,此例为:/home/hjj/MyTest/temp/pos3         然后ldconfig 生成缓存使设置生效。    pos4 系统目录/lib    pos5 系统目录/usr/lib 

原文链接:https://blog.csdn.net/hejinjing_tom_com/article/details/52454478

问题报错,示例:

# Path
DARKNET_PATH ?= ../darknet
MOT_DEEPSORT_PATH ?= ../tracker
# OPENCV_PATH ?= ../../../opencv-4.0.1
OPENCV_PATH ?= /usr/local/opencv3.4.7  #@WP

# Common definitions
GCC ?= g++ -g
NVCC ?= $(CUDA_PATH)/bin/nvcc

CCFLAGS := -fPIC -std=c++11 -lstdc++fs -Wall -O0 -Wunused-function -Wunused-variable
NVCCFLAGS := --compiler-options "-fPIC -Wall -O0 -std=c++11 -mavx -mavx2" -std=c++11 -lstdc++fs

# Common includes and paths
INCLUDES += -I$(DARKNET_PATH)/include
INCLUDES += -I$(MOT_DEEPSORT_PATH)/include
INCLUDES += -I/usr/local/opencv3.4.7/include/opencv       #@WP
INCLUDES += -I/usr/local/opencv3.4.7/include/opencv2      #@WP
INCLUDES += -I/usr/local/opencv3.4.7/include/opencv2/core #@WP
#INCLUDES += -I/usr/local/opencv3.4.7/lib       #@WP

# Link applications against stub libraries provided in the SDKs.
LDFLAGS += -L$(MOT_DEEPSORT_PATH) -ldeepsort
LDFLAGS += -Wl,-rpath="/usr/local/lib"
LDFLAGS += -lopencv_objdetect -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio  #@WP
#LDFLAGS += -L/usr/local/opencv3.4.7/lib -lopencv_objdetect -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio  #@WP
LDFLAGS += -L$(DARKNET_PATH) -ldarknet
LDFLAGS += -Wl,-rpath="$(DARKNET_PATH)"
LDFLAGS += -Wl,-rpath="$(MOT_DEEPSORT_PATH)"

#这里需要根据自己在linux上配置的opencv路径修改
#INCLUDES = -I/usr/local/opencv3.4.2/include/opencv -I.
#LIBS = -L/usr/local/opencv3.4.2/lib -lopencv_objdetect -lopencv_highgui -lopencv_imgcodecs -lopencv_core -lopencv_videoio -lopencv_imgproc

#
EXE_NAME ?= my_demo

all: $(EXE_NAME)

%.o: %.cpp
    $(GCC) $(CCFLAGS) $(INCLUDES) -c $<

%.o: $(CLIENT_SERVER_PROTO)/%.cpp
    $(GCC) $(CCFLAGS) $(INCLUDES) -c $<

%.o: $(CLIENT_SERVER_PROTO)/%.cc
    $(GCC) $(CCFLAGS) $(INCLUDES) -c $<

$(EXE_NAME): my_demo.o
    $(GCC) $(CCFLAGS) $(INCLUDES) -o [email protected] $^ $(LDFLAGS)

clean:
    rm -rf *.o $(EXE_NAME)

解决:

[email protected]:~/sort/DeepSort_yoloV3-HOG_feature$ sudo gedit /etc/ld.so.conf
[sudo] u 的密码:
在/etc/ld.so.conf加入内容:
/usr/local/opencv3.4.7/lib
/usr/local/opencv3.4.7/include

[email protected]:~/sort/DeepSort_yoloV3-HOG_feature$ source /etc/ld.so.conf
include:未找到命令
bash: /usr/local/opencv3.4.7/lib: 是一个目录
bash: /usr/local/opencv3.4.7/include: 是一个目录
[email protected]:~/sort/DeepSort_yoloV3-HOG_feature$ ldconfig
^Z
[1]+  已停止               ldconfig
[email protected]:~/sort/DeepSort_yoloV3-HOG_feature$ sudo ldconfig
[email protected]:~/sort/DeepSort_yoloV3-HOG_feature$ 

解决问题的过程中,学会几个命令:

grep -R <一个想要找的关键字>

移动文件之后,需要:sudo ldconfig  一下,使修改生效

参考:

一、 Linux 动态库选择顺序指:

1.  编译程序时用到动态库,该从那些地方查找,按照怎么样的顺序查找?

2.  运行程序时需要动态库,该从那些地方查找,按照怎么样的顺序查找?
二、gcc 编译程序时查找SO顺序如下:

1.  gcc 编译时参数-L指定的路径

2.  环境变量 LIBRARY_PATH

3.  系统默认库位置 /lib    /usr/lib
三、Linux 程序运行时查找SO顺序如下:

1.  gcc 编译时指定的运行时库路径 -Wl,-rpath

2.  环境变量 LD_LIBRARY_PATH

3.  ldconfig 缓存 /etc/ld.so.cache

4  系统默认库位置 /lib    /usr/lib
四、LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别

LIBRARY_PATH和LD_LIBRARY_PATH是Linux下的两个环境变量,二者的含义和作用分别如下:

LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径,例如,指定gcc编译需要用到的动态链接库的目录。设置方法如下(其中,LIBDIR1和LIBDIR2为两个库目录):

export LIBRARY_PATH=LIBDIR1:LIBDIR2:$LIBRARY_PATH

LD_LIBRARY_PATH环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径,注意,LD_LIBRARY_PATH中指定的路径会在系统默认路径之前进行查找。设置方法如下(其中,LIBDIR1和LIBDIR2为两个库目录):

export LD_LIBRARY_PATH=LIBDIR1:LIBDIR2:$LD_LIBRARY_PATH

举个例子,我们开发一个程序,经常会需要使用某个或某些动态链接库,为了保证程序的可移植性,可以先将这些编译好的动态链接库放在自己指定的目录下,然后按照上述方式将这些目录加入到LD_LIBRARY_PATH环境变量中,这样自己的程序就可以动态链接后加载库文件运行了。

区别与使用:

开发时,设置LIBRARY_PATH,以便gcc能够找到编译时需要的动态链接库。

发布时,设置LD_LIBRARY_PATH,以便程序加载运行时能够自动找到需要的动态链接库。

注意:新设置变量 LD_LIBRARY_PATH ,下次开机,一切设置将不复存在;如何把这个值持续写到 LD_LIBRARY_PATH 里呢?

我们就会想有不有什么一劳永逸地方法,使得设置之后就不用再去设置了?答案是肯定的。有两种:

1、在~/目录下打开.bash_profile文件,设置环境变量如下:

    LD_LIBRARY_PATH=dir:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH

LD_LIBRARY_PATH  这个环境变量是大家最为熟悉的,它告诉loader:在哪些目录中可以找到共享库。可以设置多个搜索目录,这些目录之间用冒号分隔开。

2、在linux下,还 提供了另外一种方式来完成同样的功能,你可以把这些目录加到/etc/ld.so.conf中,然后调用ldconfig。
五、链接选项-I,-l,-L,-Wl:rpath

-I,添加包含路径

-I 在编译时用,告诉编译器去哪个路径下找文件

如:-I /home/hello/include

表示将/home/hello/include目录作为第一个寻找头文件的目录。

编译器的寻找顺序是:/home/hello/include-->/usr/include-->/usr/local/include。如果在/home/hello/include中有个文件hello.h,则在程序中用#include<hello.h>就能引用到这个文件。

可以加多个包含路径,编译器的寻找顺序为添加的顺序。

-l,添加引用链接库

-l 在链接时用到,它的作用是告诉链接器,要用到哪个库。
如:-l pthread

告诉链接器(linker),程序需要链接pthread这个库,这里的pthread是库名不是文件名,具体来说文件句是libpthread.so。

-L,添加链接库路径
-L 后跟路径,告诉链接器从哪找库(.so文件),只有在链接时会用到。

如:-L /home/hello/lib

表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找顺序是:/home/hello/lib-->/usr/lib-->/usr/local/lib。

可以加多个包含路径,链接器的寻找顺序为添加的顺序。

-Wl:rpath,添加运行时库路径

-Wl:rpath 后面也是路径,运行的时候用。这条编译指令会在编译时记录到target文件中,所以编译之后的target文件在执行时会按这里给出的路径去找库文件。

如:-Wl:rpath=/home/hello/lib

表示将/home/hello/lib目录作为程序运行时第一个寻找库文件的目录,程序寻找顺序是:/home/hello/lib-->/usr/lib-->/usr/local/lib。

可以加多个包含路径,程序在运行时的寻找顺序为添加的顺序。

参考:

https://blog.csdn.net/hejinjing_tom_com/article/details/52454478

原文地址:https://www.cnblogs.com/carle-09/p/11725682.html

时间: 2024-08-29 21:02:36

ubuntu---记录.动态库默认路径的踩坑的相关文章

linux动态库默认搜索路径设置的三种方法

众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函 数,以及该动态库的其它资源了.在 Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定. 方法一:在配置文件 /etc/ld.so.conf 中指定动态库搜索路径.每次编辑

Linux动态库搜索路径的技巧

众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函数,以及该动态库的其它资源了.在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定. 方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径. 可以通过编辑配置文件/etc

[转]谈谈Linux下动态库查找路径的问题

http://blog.chinaunix.net/uid-23069658-id-4028681.html 学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续“上路”.回想起自己当年刚接触Linux时,不管是用源码包编译程序,还是程序运行时出现的和动态库的各种恩恩怨怨,心里那真叫一个难受.那时候脑袋里曾经也犯过嘀咕,为啥Linux不弄成windows那样呢,装个软件那个麻烦不说,连运行软件都这么恼火呢?如果那样的话就不叫Linux了.借用小米公司CEO雷军一句话:小米,为发烧而生

谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH

谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH  PKG_CONFIG_PATH 转载自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=23069658&id=4028681 学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续“上路”.回想起自己当年刚接触Linux时,不管是用源码包编译程序,还是程序运行时出现的和动态库的各种恩恩怨怨,心里那真叫一个难受.那时候脑袋里曾经

转:谈谈Linux下动态库查找路径的问题

http://blog.chinaunix.net/uid-23069658-id-4028681.html 学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续"上路".回想起自己当年刚接触Linux时,不管是用源码包编译程序,还是程序运行时出现的和动态库的各种恩恩怨怨,心里那真叫一个难受.那时候脑袋里曾经也犯过嘀咕,为啥Linux不弄成windows那样呢,装个软件那个麻烦不说,连运行软件都这么恼火呢?如果那样的话就不叫Linux了.借用小米公司CEO雷军一句话:小米,

Ubuntu 16.04 安装Mysql 5.7 踩坑小记

title:Ubuntu 16.04 安装Mysql 5.7 踩坑小记 date: 2018.02.03 安装mysql sudo apt-get install mysql-server mysql-client 测试是否安装成功 sudo netstat -tap | grep mysql 相关操作 登录 mysql -uroot -p 检查MySQL服务器占用端口 netstat -nlt|grep 3306 检查MySQL服务器系统进程 ps -aux|grep mysql 查看数据库的

linux添加动态库搜索路径

在有时运行程序出现动态库找不着的问题,而明明装了的.这时候可能是没有将相应的路径添加到系统中去. 具体说:cd /etc/ld.so.conf.d/ 可以发现里面有一堆*.conf的文件 我们要做的就是建一个自己的文件,里面写上我们的动态库路径.具体形式如果有问题可以参考其他的*.conf文件 添加完毕之后记得在terminal里面输入sudo ldconfig

GDB动态库搜索路径

当GDB无法显示so动态库的信息或者显示信息有误时,通常是由于库搜索路径错误导致的,可使用set sysroot.set solib-absolute-prefix.set solib-search-path来指定库搜索路径. 1. set sysroot 与 set solib-absolute-prefix 是同一条命令,实际上,set sysroot是set solib-absolute-prefix 的别名. 2. set solib-search-path设置动态库的搜索路径,该命令可

linux 添加动态库路径

众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该 动 态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函数,以及 该动态库的其它资源了.在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定. 方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径. 可以通过编辑配置文件/