解决CMake时的Find_Package失败问题

144 篇文章 6 订阅
文章讲述了在使用CMake编译项目时遇到find_package无法找到redis和hiredis库的问题。解决方案包括安装对应的开发库,创建缺失的Config.cmake文件,并调整CMAKE_PREFIX_PATH。问题出在CMake的Module和Config模式查找路径上,通过手动创建配置文件或修改搜索路径可解决此类问题。
摘要由CSDN通过智能技术生成

今天在编译组内代码时遇到了Find_package问题,具体来说就是找不到redis的库及相关头文件。

CMake Error at cmake/micros.cmake:75 (find_package):
  By not providing "Findclass_loader.cmake" in CMAKE_MODULE_PATH this project
  has asked CMake to find a package configuration file provided by
  "class_loader", but CMake did not find one.

  Could not find a package configuration file provided by "class_loader" with
  any of the following names:

    class_loaderConfig.cmake
    class_loader-config.cmake

  Add the installation prefix of "class_loader" to CMAKE_PREFIX_PATH or set
  "class_loader_DIR" to a directory containing one of the above files.  If
  "class_loader" provides a separate development package or SDK, be sure it
  has been installed.

 针对上述问题,我们查找并安装了class_loader的开发库,上述问题就解决了。也就是

ok@u20:~/code/micros_information-dev_v2/build$ sudo apt-cache search class_loader
libclass-loader-dev - development files for Robot OS class_loader library
libclass-loader1d - ROS class_loader library
ok@u20:~/code/micros_information-dev_v2/build$ sudo apt-get install libclass-loader-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
下列软件包是自动安装的并且现在不需要了:
  apport-symptoms python3-systemd
使用'sudo apt autoremove'来卸载它(它们)。
将会同时安装下列软件:
xxxxxx

继续执行cmake,又出现了问题,找不到hiredis库

Could not find a package configuration file provided by "hiredis" with any
  of the following names:

    hiredisConfig.cmake
    hiredis-config.cmake

  Add the installation prefix of "hiredis" to CMAKE_PREFIX_PATH or set
  "hiredis_DIR" to a directory containing one of the above files.  If
  "hiredis" provides a separate development package or SDK, be sure it has
  been installed.

使用前面的方法,发现安装hiredis的开发库之后,仍然报错。

ok@u20:~/code/micros_information-dev_v2/build$ sudo apt-get install libhiredis-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
下列软件包是自动安装的并且现在不需要了:
  apport-symptoms python3-systemd
使用'sudo apt autoremove'来卸载它(它们)。
下列【新】软件包将被安装:
  libhiredis-dev
xxxxx

然后使用whereis查找hiredis对应的头文件和库。分别在/usr/include/hiredis下面和/usr/lib/x86_64-linux-gnu下面。

ok@u20:/usr/include/hiredis$ ls
adapters  alloc.h  async.h  hiredis.h  read.h  sds.h
ok@u20:/usr/lib/x86_64-linux-gnu$ ls libhi
libhiredis.a        libhiredis.so.0.14  libhistory.so.8.0
libhiredis.so       libhistory.so.8     

于是决定重建hiredis对应的cmake文件,创建/usr/local/lib/cmake/hiredis/hiredisConfig.cmake文件,内容如下:

FIND_PATH(HIREDIS_INCLUDE_DIR hiredis.h
          /usr/local/include
          /usr/include
          )

FIND_LIBRARY(HIREDIS_LIBRARIES NAMES HIREDIS
             PATHS
             /usr/local/lib
             /usr/lib
             /usr/lib/x86_64-linux-gnu
             )

然后重新执行cmake,成功。

上述出现这些错误的原因是因为我们在CMakeLists.txt中使用了find_package操作

find_package(hiredis REQUIRED)

 但是实际上libclass_loader.so和libhireids.so在相同目录下:

ok@u20:/usr/lib/x86_64-linux-gnu$ ls libcl
libclass_loader.so                  libclucene-shared.so.2.3.3.4
libclass_loader.so.0.4.1            libclutter-1.0.so.0
libclass_loader.so.1d               libclutter-1.0.so.0.2600.4
libclucene-contribs-lib.so.1        libclutter-glx-1.0.so.0
libclucene-contribs-lib.so.2.3.3.4  libclutter-gst-3.0.so.0
libclucene-core.so.1                libclutter-gst-3.0.so.0.27.0
libclucene-core.so.2.3.3.4          libclutter-gtk-1.0.so.0
libclucene-shared.so.1              libclutter-gtk-1.0.so.0.800.4

但是为什么class_loader安装后就可以使用了,而hiredis不行呢?因为安装class_loader后,已经有了对应的cmake文件。使用模糊查找如下:

ok@u20:/$ sudo find / -iname "*loaderConfig.cmake"
find: ‘/run/user/1000/doc’: 权限不够
find: ‘/run/user/1000/gvfs’: 权限不够
find: ‘/run/user/125/gvfs’: 权限不够
/usr/share/class_loader/cmake/class_loaderConfig.cmake

 而查找hiredis的cmake文件:

ok@u20:/$ sudo find / -iname "*redisConfig.cmake"
find: ‘/run/user/1000/doc’: 权限不够
find: ‘/run/user/1000/gvfs’: 权限不够
find: ‘/run/user/125/gvfs’: 权限不够
/usr/local/lib/cmake/hiredis/hiredisConfig.cmake
/usr/lib/cmake/Poco/PocoRedisConfig.cmake
/usr/lib/x86_64-linux-gnu/cmake/Hiredis/HiredisConfig.cmake

 可以发现,实际上也是有的,只不过所在位置为/urs/local/x86_64-linux-gnu目录下,而这个目录估计不在Cmake的find_package的查找路径下。因此,针对hiredis这个配置,除了前面编写cmake文件外,也可以修改find_package的搜索路径。

Find_Package()的原理

首先,我们简单了解下Find_Package()的原理,它在搜索包时有两种模式:“Module(模块)”模式和“Config(配置)”模式

在Module模式中,CMake会搜索所有名为Find<package>.cmake的文件,此文件的路径由安装CMake时指定的CMAKE_MODULE_PATH变量指定。如果找到了该文件,它会被CMAKE读取并进行处理,会生成以下相关变量:

// 是否发现该库
<LibaryName>_FOUND
// 头文件
<LibaryName>_INCLUDE_DIR or <LibaryName>_INCLUDES 
// 库文件
<LibaryName>_LIBRARY or <LibaryName>_LIBRARIES

如果在Module模式中没有找到Find<package>.cmake文件,那么会进入Config模式,Cmake会搜索名为<package>Config.cmake与<package>-config.cmake文件,Cmake路径有很多,有兴趣的可以参考下CMake官方教程,这里提供一个常用路径:/usr/local/lib/cmake/xxx/。该配置文件中指定了依赖库的头文件、库文件地址。通过Config模式找到依赖库后,同样也是会生成库的相应变量,供调用者使用。如果没有找到该配置文件,可以自己创建一个,并不复杂。

对于Module模式,用户也可以自己编写对应的文件,方便自定义模块在Cmake中使用。具体可以参考:Cmake中find_package命令的搜索模式之模块模式(Module mode) - 简书 (jianshu.com)

`find_package` 是 CMake 中用于查找和加载外部依赖库的命令。它会在系统中搜索指定名称的库,并自动配置编译选项。一般情况下,我们需要在 CMakeLists.txt 文件中使用 `find_package` 命令来查找我们需要的库,然后将它们链接到我们的项目中。 下面是使用 `find_package` 命令的一般步骤: 1. 在 CMakeLists.txt 文件中使用 `find_package` 命令,指定要查找的库的名称和版本。 例如,要查找 Boost 库,可以使用以下命令: ``` find_package(Boost 1.46 REQUIRED COMPONENTS system thread) ``` 2. 如果库没有被找到,可以通过设置 `CMAKE_PREFIX_PATH` 环境变量或者 `CMAKE_MODULE_PATH` 变量来指定库的安装路径或者 CMake 模块所在路径。 3. 如果找到了库,`find_package` 命令会自动定义一些变量,用于指定库的路径、头文件路径和库文件路径等信息。 例如,对于 Boost 库,`find_package` 命令会定义以下变量: ``` Boost_FOUND Boost_INCLUDE_DIRS Boost_LIBRARY_DIRS Boost_LIBRARIES ``` 4. 在项目中使用这些变量,例如: ``` include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) target_link_libraries(my_target ${Boost_LIBRARIES}) ``` 这些变量包含了库的路径信息,可以用来编译和链接项目。 需要注意的是,`find_package` 命令只能用于已经被 CMake 支持的库。对于一些非常规的库,可能需要手动配置编译选项来使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值