今天在编译组内代码时遇到了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()的原理,它在搜索包时有两种模式:“Module(模块)”模式和“Config(配置)”模式。
在Module模式中,CMake会搜索所有名为Find
// 是否发现该库
_FOUND
// 头文件
_INCLUDE_DIR or _INCLUDES
// 库文件
_LIBRARY or _LIBRARIES
如果在Module模式中没有找到Find
对于Module模式,用户也可以自己编写对应的文件,方便自定义模块在Cmake中使用。具体可以参考:Cmake中find_package命令的搜索模式之模块模式(Module mode) - 简书 (jianshu.com)