感谢盛齐师兄指导。该博客记录了师兄的解决思路和原理讲解。
在编译某一开源工具包时,使用cmake编译报错:
CMake Error at /(我的文件路径)/cmakelist.txt (find_package):Could not find a configuration file for package "Eigen3" that is compatible with requested version "3.3"
在cmakelist中我们设定了寻找eigen包,且在find_package中限定了eigen库的版本不低于3.3. 在编译中报错说找不到3.3版本的eigen库。下述问题的解决思路和相关原理:
1 解决思路
1.1 使用sudo apt-get install libeigen3-dev安装eigen库
在终端输入:
sudo apt-get install libeigen3-dev
这是首先想到的办法。但是,使用该方法安装后编译,仍然报错。我们需要检查这个办法所安装的eigen库是否为cmakelist所要求的3.3版本。
1.2 检查eigen库版本
在cmakelist.txt中插入如下命令:
(安这个包的硬盘拆掉了,暂时写不出来。后面有空再补上这段代码)
第一段find_package在电脑中搜索eigen包,当怀疑cmake找到的包的版本不对时可以用这个办法查看;
第二段当找到指定名字的包后,输出包的相关信息,以查看cmake所找到的包是否是我们想要的那个。
根据输出结果,我们发现,找到了eigen3,但不是所要求的eigen3.3,说明使用apt-get安装的包不行。
1.3 源码编译安装eigen3.3
在eigen官网下载我们想要的版本:
http://eigen.tuxfamily.org/index.php?title=Main_Page
当然也可以直接clone:
git clone https://gitlab.com/libeigen/eigen.git
总之我们下载了想要的eigen源码。之后就是惯常的安装。首先建立build文件夹,进入:
mkdir build
cd build
# 建立build文件夹并进入
编译,安装:
cmake ..
make
sudo make install
make blas
完成安装。
但是,当我们再次编译前述某工具包时,仍然报相同的错。这就说明,cmake似乎并没有找到我们安装的新版本eigen,似乎找到的仍然是旧版本eigen。如果是这样的话,我们也有对应的办法。下面我们就来验证这个猜测。
1.4 检查Eigen3Config.cmake
为了查看cmake找到的包,惯常做法是查看config.cmake文件。这里就是查看Eigen3Config.cmake文件。
搜索这个文件名,找到。它的默认位置是在/usr/lib/cmake 中。
打开看,果然,eigen库是3.2.9版,不是我们新安装的3.3版。而解决办法也很多
法1:替换eigen库,修改.cmake文件。
这一段是eigen3库的位置,如果替换好了eigen库的话,就不需要修改。
set (EIGEN3_DEFINITIONS "")
set (EIGEN3_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/eigen3")
set (EIGEN3_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/eigen3")
set (EIGEN3_ROOT_DIR "${PACKAGE_PREFIX_DIR}")
这一段是eigen3库的版本号,4行全部修改掉。
set (EIGEN3_VERSION_STRING "3.3.7")
set (EIGEN3_VERSION_MAJOR "3")
set (EIGEN3_VERSION_MINOR "3")
set (EIGEN3_VERSION_PATCH "7")
法2:使cmakelist查找的.cmake文件不指向默认位置,而是我们前面编译eigen3,3产生的新的Eigen3Config.cmake。只需要在cmakelist.txt里查找eigen3的find_package前加入一句:
set(Eigen3_DIR "home/(eigen3.3的文件路径/build)")
再次编译这个工具包,终于不报错找不到指定版本的eigen库了,改报别的错了。
2 原理
cmake查找一个包的基本流程如上图所示。我们前面版本号报错就是出在了cmakelist.txt里要求的版本号和默认位置的config.cmake里提供的版本号矛盾所致。
所以,我们前面提出的解决办法就很好理解了。无非是暗度陈仓(更改config.cmake)的位置,或者狸猫换太子(替换默认位置的config和eigen库内容)