关于CMakeLists.txt中find_packge()和动态库查找的遇到的大部分问题总结

前段时间,一直在编译代码,遇到一些关于cmake中编译的相关问题,想着经下心来总结以下相关问题,发现深挖后,真是理解到了学无止境,还有很多东西需要了解,不过在其中也总结了一些东西想要分享给大家,有什么问题可以及时沟通。

下面主要从两个方面介绍cmake中的查找默认路径和方式,以及我们能够做的工作,下面介绍的这是其中的一小部分,让我用简短的一段文字完全讲述其中的相关知识背景,我实在无能为力,此外由于知识水平有限,其中会有我的知识瓶颈,如有不同观点,欢迎沟通交流,互相成长!

常见报错形式:
以下3个报错,为常见错误。

  1. Could not find a package configuration file provided by “XXX” with any of the following names:
    原因:没有找到你的功能包,其实是没有找到.cmake文件,可以采用1.1.1中的最后一个针对配置模式的解决方案,就可以解决了。
  2. error: ld returned 1 exit status。
    原因:ld是链接器的简称,所以是链接是没有找到这个库文件,一般为编译时,没有找到库的地址,可以通过添加下面代码,让ld找到库文件,括号内的地址是你的库文件存放的地址,这个问题解决后,可能会出现3中出现的问题,找到了链接不上,我还没有解决此问题,欢迎讨论。不过还是可以通过1.1.2.1中的其中一个方法解决此问题的。
link_directories(${PROJECT_SOURCE_DIR}/bin/)
  1. error while loading shared libraries: libSatp.so.1: cannot open shared object file: No such file or directory。
    原因:这种情况一般是编译通过后,运行时报的错误,编译没有报错误,说明这个包存在,并且找到了,就是没有链接上,采用1.1.2.1中的任意一个一般可以解决,没有解决可以沟通交流。但是我困惑的是想要通过1.1.2.2中提出的方式解决,一直没有成功,报这个错误,我很困惑一直没有解决。

1 不同方式引入的库

在我目前知识范围内,自己编译环境存在的库的形式大致可以分为两大类,一种是自己编译环境下通过cmake/make由源码编译生成的库文件另外一种是在别人电脑编译生成库文件后,拷贝到自己环境中的,此时特指只拷贝了库文件,没有拷贝源码,如果拷贝了源码,在自己环境中进行再次编译生成动态库就和第一中情况一样了。以上库文件,一般指动态链接库和静态链接库,其中动态链接库(有的称为共享库)unbuntu下常以.so结尾,静态链接库以.a结尾。

以上两种方式引入的动态库,在我们编写CmakeLists.txt时的引用方式不同,具体引用方式如何书写,此文章暂时不进行分享,以后了解更多了再写。此文章重点书写在链接过程中出现链接失败,如何使编译通过。

1.1 通过编译引入的库

通过编译引入的动态库,一般make都会生成一个Config.cmake文件,如果提示查找不到某个包(can not find package),你就可以在根目录下搜索一下有没有这个文件,有的话,直接把这个地址给find_pkg 就行了,此方式也可以指定你想要选择的包版本。具体是如何查找的,以及查找路径可以看下面的讲解。

1.1.1 findpackage查找路径

  1. 模块模式

    cmake的模块模式,我理解的就是cmake编译时查找你想要引入的库的Find.cmake文件

    1) 首先查找当前cmake 路径下的所有目录中是否存在你想引入库的Find.cmake,此文件一般为用户自定义的。

    2)如果没有查找到,cmake一般会在/usr/share/cmake-x.y/Modules/中查找,此文件夹中的Find.cmake为cmake 官方给出专门查找功能包的文件,其中的一个Find.cmake可以找到一个对应的功能包,其中只是一部分常用功能包。

    如果官方给出了某个功能包的Find.cmake文件,你就可以在cmakelist.txt中通过find_package(XXX)引入此功能包。

  2. 配置模式

    cmake在模块模式中如果没有查找到对应的库,将会进入配置模式,我目前理解的配置模式就是查找
    <包名>Config.cmake

    1) 首先会在~/.cmake/packages中查找是否有你引入的 <包名>Config.cmake,我查看的我的电脑这个目录中没有什么东西。

    2) 然后会在/usr/local/share/中查找是否存在你想要引入的 <包名>Config.cmake

  3. 根据模块模式和配置模式我们可以做什么?

    知道了模块模式和配置模式的查找方式后,我们就可以使用这些规则制定我们自己的Find.cmake<包名>Config.cmake了。

    1)针对模块模式,我们可以在自己当前cmake目录下,编写Find.cmake文件,指定引入的库的路径。

    下面是编写的find_qt.cmake文件示例。

    if (WIN32)
    # set stuff for windows
    #    SET(Qt5_PATH /path/to/your/qt/lib)
    else()
    # set stuff for other systemsSET(Qt5_PATH /home/wsb/Qt5.12.2/5.12.2/gcc_64/lib/cmake/Qt5/)
    #此处被更改,更改为本机QtConfig.cmake的地址
    endif()SET(CMAKE_PREFIX_PATH ${Qt5_PATH})set(CMAKE_INCLUDE_CURRENT_DIR ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_AUTOUIC ON)if(CMAKE_VERSION VERSION_LESS "3.7.0")
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    endif()#set(Qt5 /home/wsb/Qt5.12.2/5.12.2/gcc_64/lib/cmake/Qt5/)
    #此处为添加内容,为本机QtConfig.cmake的地址,与上处可替换
    find_package(Qt5 COMPONENTS Core Network RemoteObjects REQUIRED)include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS})
    

    2)针对配置模式,如果我们想要指定某一个库的版本,例如有多个OpenCVd的版本,我们需要先在本机找到需要版本的 <包名>Config.cmake
    然后在CMakeLists.txt中添加以下代码,"/usr/local/share/OpenCV/"路径为我需要的OpenCV的OpenCVConfig.cmake的地址。

    set(OpenCV_DIR "/usr/local/share/OpenCV/")
    #指定自己需要的OpenCV的版本
    find_package(OpenCV REQUIRED)
    

1.1.2 通过单独复制引入的库

其中有一些库并不是通过make源码安装的,我遇到的情况是,我购买了摄像头,供应商给我提供的一些 动态库(.so文件),这些动态库是零散的,
无法通过上面提到的模块模式和配置模式完成引入库的功能,cmake 还提供了一些单独查找库的方法。

1.1.2.1 几种从系统中角度引入单个动态库的方法

  1. export LD_LIBRARY_PATH=/usr/lib64/(/usr/lib64/为 .so所在路径),只对当前用户的终端生效,其他用户没用。

  2. 在 /etc/ld.so.conf文件下,找一个文件将动态库的路径加进来,然后 执行sudo /sbin/ldconfig 进行更新。

  3. 无论什么动态库, Linux操作系统,都是默认去该目录下 /usr/lib/查找使用的动态库,所以有两种办法。

    1)创建动态库的软连接至该目录;sudo ln -s (动态库的源文件) /usr/lib。这个方法的好处是动态库进行更新时,会把目录下的一起更新,不需要额外操作。

    2)sudo cp (动态库的源文件) /usr/lib;(不推荐把动态库拷贝至该目录下 ,因为更新时需要把该目录下的都重新拷贝)

  4. 修改该用户下的 .bashrc 配置文件;将动态库的路径添加进来;重新执行配置文件:source .bashrc。(弊端:只 在当前用户下有用)

1.1.2.2 如何通过CMakeLists.txt引入单个动态库?

最近一直被在各个问题困惑,还没有搞清楚怎么回事,前面的几种方式都是在系统中添加自己的库文件,怎么有一种方式,不需要通过系统,直接在CMakeLists.txt中引入单个库,这样就不用每次对系统都进行更改某些内容了,有知道的朋友,可以与我分享一下。我尝试以下代码引入,单个动态库,同一个文件中的动态库,有的被成功链接到,有的就是链接不会上,不知道怎么回事?

#添加头文件地址
include_directories(${catkin_INCLUDE_DIRS}${OpenCV_INCLUDE_DIRS}${PROJECT_SOURCE_DIR}/include/
)
#添加库文件地址
link_directories(${PROJECT_SOURCE_DIR}/bin/)
#多个库赋值到STECAM_LIBS变量中
set(STECAM_LIBS StereoCamera  Satp icudata icui18n icuuc ImageUtils QAsioSocket Qt5Core Qt5Gui Qt5Network Qt5RemoteObjects  SatpExt)
#创建可执行文件
add_executable(stereo_publishersrc/stereo_publisher.cppsrc/framemonitor.cppsrc/pointcloudgenerator.cpp)#添加链接库
target_link_libraries(stereo_publisher${catkin_LIBRARIES}${STECAM_LIBS})

Could not find a package; ld returned 1 exit status;error while loading shared libraries相关推荐

  1. redis编译安装:make 的新错误--collect2: ld returned 1 exit status

    redis的一个下载链接不知道为什么到我这里的终端下载提示no such of directory,但在浏览器下载是没有问题的 [root@user10 src]# wget https://code ...

  2. collect2.exe: error: ld returned 1 exit status分析与解决

    阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量.文章设置为仅粉丝可见,是因为写博客确实花了不少精力.希望互相进步谢谢!! 文章目录 阅读前请看一下:我是一个热衷于记 ...

  3. 问题记录vips.h:133: undefined reference to `vips_reduce‘ collect2: error: ld returned 1 exit status

    @[TOC]背景 ubuntu下go build 出错: # github.com/h2non/bimg /tmp/go-build2910330990/b131/_x005.o: In functi ...

  4. undefined reference to `__gxx_personality_v0' collect2: ld returned 1 exit status

    [root@localhost dss]# gcc -o abc abc.cpp /tmp/ccY3hmyr.o(.eh_frame+0x11): undefined reference to `__ ...

  5. /usr/bin/ld: cannot find -lltdl collect2: ld returned 1 exit status make: *** [sapi/cgi/php-cgi] Err

    /usr/bin/ld: cannot find -lltdl collect2: ld returned 1 exit status make: *** [sapi/cgi/php-cgi] Err ...

  6. dev c++ 报错[Error] ld returned 1 exit status 的解决办法

    我是个C语言的初学者,在使用dev c++ 编译器时,遇到一个情况:程序是正确的,能够正常的编译和运行,但是运行一次之后再次运行之时就出现了 报错[Error] ld returned 1 exit ...

  7. 类似collect2: ld returned 1 exit status的错误

    今天帮忙处理一个链接问题,使用vs2015编译,链接时报错:collect2: ld returned 1 exit status以及not found (try using -rpath or -r ...

  8. Qt error: collect2: error: ld returned 1 exit status

    Ubuntu安装好Qt5.10.0后,新建最简单的项目测试环境是否OK时,出现"error: collect2: error: ld returned 1 exit status" ...

  9. 在dev-c或者cb上建立 Consol Application project\collect2.exe [Error] ld returned 1 exit status

    代码没有任何错误,也没有多开的终端,但是依然出现以下错误 \collect2.exe [Error] ld returned 1 exit status 在该项目中加入了两个文件,将其中一个文件移除, ...

最新文章

  1. 自制奇葩vb面试题,看你能对几道
  2. web前端培训分享Electron之Main Process API
  3. 智能检测营销是否合规,网易易盾发布广告合规检测解决方案
  4. linux实验之文件与文件,linux实验报告文件系统与文件管理.doc
  5. Android Input子系统-含实例源码
  6. 信息学奥赛一本通(1174:大整数乘法)
  7. 浏览器九宫格的简单实现 - 蒋宇捷的专栏 - 博客频道 - CSDN.NET
  8. 批处理学习笔记6 - 重定向符和
  9. JavaWeb——servlet介绍
  10. 示波器同步的调节方法
  11. 编译Openwrt(LEDE)for K3固件详细指南
  12. 中国无线VOC检测器行业市场供需与战略研究报告
  13. Android开发之Google地图开发
  14. 2022年~全网最真实的软件测试面试题合集
  15. 20年ICPC澳门站L - Random Permutation
  16. 【转载】通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
  17. 基于单片机多功能万年历系统毕业设计(完整资料)
  18. MATLAB学习系列--绘制函数曲线
  19. 中心极限定理的形象理解
  20. html5怎么做相册影集,照片制作视频软件|狸窝照片制作视频软件 如何用照片制作视频...

热门文章

  1. 扎金花大小比较算法(Java版)
  2. 如何用Qt抠一个圆形头像出来
  3. 微信小程序周报(第二期)
  4. 常用JS网页广告代码
  5. myeclipse-添加jar包
  6. fffffffffffff
  7. fpga挂一片ddr2_基于Cyclone III FPGA的DDR2接口设计分析
  8. 运维之红帽管理员篇-----1. Linux系统简介 、 安装RHEL7系统 、 RHEL7基本操作
  9. Prompt Learning-使用模板激发语言模型潜能
  10. 每次回西安,都会动摇我继续留在深圳的决心