赞
踩
这两个问题是比较典型的。
这个看《【cmake开发(6)】Cmakelists 使用 gcc/g++指定版本,find_package 基本原理》中find_package 的原理。
确保三个路径配置好了:
1、#设置包括的头文件
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
)
2、设置搜索的库目录
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs
)
3、目标生成
target_link_libraries( demo
# 目标库需要链接的库
${log-lib} )
在CMakeList.txt我们经常看见find_package这个命令,如
find_package(yaml-cpp REQUIRED)
当找不到包时,则会报错,停止编译。
1.2.1 让 find_package 到指定路径找包,有三种方法
1 设置 DIR
set(yaml-cpp_DIR ~/yaml-cpp)
find_package(yaml-cpp REQUIRED)
2 设置PATHS
set(yaml-cpp required PATHS ~/yaml-cpp)
3 指定 DCMAKE_PREFIX_PATH
cmake -DCMAKE_PREFIX_PATH="~/yaml-cpp" ..
另外《【cmake开发(11)】CMake中的CMAKE_PREFIX_PATH使用技巧与示例》会记录DCMAKE_PREFIX_PATH的用法,可以参考
因为运行和编译是不一样的,编译时 cmake 会组织“材料” 进行加工。运行时,需要使用 系统的寻库程序进行。因此需要依靠系统的工具实现
在之前的文章《【编译原理】linux动态链接库的路径及依赖的查询objdump 和ldd》提到了工具 ldd 查看。
1、一个 二进制文件(动态库、可执行程序)还可能依赖别的动态库,可用以下命令去查询[7]:
$ objdump -x libxxxxx.so | grep NEEDED
2、 还可以直接使用ldd命令查看动态库的依赖关系:
ldd libXXX.so
3、通过 file 命令来查看库的编译平台:
file xxx.so
4、readelf命令,一般用于查看ELF格式的文件信息,常见的文件如在Linux上的可执行文件,动态库(.so)或者静态库(.a) 等包含ELF格式的文件。
使用方式(usage)
readelf -d test #test为可执行文件
readelf -d libc.so.6 #libc.so.6为动态库
/etc/ld.so.conf 此文件记录了编译时使用的动态库的路径,也就是加载so库的路径。
查到/etc/ld.so.conf这个文件,此文件记录了编译时使用的动态库的路径,也就是加载so库的路径。将/usr/lib加入到文件/etc/ld.so.conf中,执行ldconfig命令,刷新库文件缓存。
具体分析:
1、默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件,而通常通过源码包进行安装时,如果不指定–prefix会将库安装在/usr/local目录下,而又没有在文件/etc/ld.so.conf中添加/usr/local/lib这个目录。这样虽然安装了源码包,但是使用时仍然找不到相关的.so库,就会报错。也就是说系统不知道安装了源码包。对于此种情况有2种解决办法:
(1) 在用源码安装时,用–prefix指定安装路径为/usr/lib。
(2) 直接将路径/usr/local/lib路径加入到文件/etc/ld.so.conf文件的中。在文件/etc/ld.so.conf中末尾直接添加:/usr/local/lib(这个方法给力!)
ldconfig
再来看看ldconfig这个程序,位于/sbin下,它的作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。
安装chrpath,sudo apt install chrpath
#显示rpath路径,比如
chrpath -l xxx.so 或者 chrpath -l test
#修改rpath路径,比如
chrpath -r ./lib xxx.so #其中./lib是需要修改的路径,xxx.so为源路径库
chrpath -r ./lib test #其中./lib是需要修改的路径,test可执行文件
安装patchelf sudo apt install patchelf
patchelf --set-rpath ./lib xxx.so #其中./lib是需要修改的路径,xxx.so为源路径库
GCC详解的-Wl选项说明与测试
gcc -o test test.c -I. -L. -lc -Wl,-rpath=.
其中
-I. 是指定头文件路径为当前目录下;
-L. 是指定库文件路径为当前目录下;
-lc 是从-L指定库文件路径下去找libc.so.6这个库,也就是库名砍头去尾(类似使用过-lpthread);
-Wl,-rpath=. 为告诉编译器将后面的参数传递给链接器。
IF(UNIX)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(CMAKE_CXX_FLAGS "-Wl,-z,origin,-rpath,$ORIGIN")
ENDIF()
或者
set(CMAKE_SKIP_BUILD_RPATH FALSE) # 编译时加上RPATH
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # 编译时RPATH不使用安装的RPATH
set(CMAKE_INSTALL_RPATH "./") # 安装RPATH为当前目录
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) # 安装的执行文件不加上RPATH
设置LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yimning/lib
冒号:为设置多个路径下的分割符号。设置之后再去编译即可。
export -p //列出当前的环境变量值
export MYENV //定义环境变量
export MYENV=7 //定义环境变量并赋值
如果直接使用export声明变量,则export 的效力仅限于该次登陆操作。如果想要持久化生效,则需要将export命令写入 /etc/profile 文件或者/root/.bashrc文件中。
https://blog.csdn.net/Castlehe/article/details/107630544
https://cloud.tencent.com/developer/article/1342894
https://www.runoob.com/linux/linux-comm-export.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。