Eigen的安装与版本管理

本文最后更新于 2024年10月11日 下午

本文主要分享了在Linux下Eigen库的安装与版本管理。

推荐安装 Eigen >= 3.3.4。在我运行的几个程序上,3.3.0 版本可能计算分配有点问题,程序计算卡顿,做不到实时,单个 CPU 核心满载,其它 CPU 核心空闲。

安装

利用apt-get进行安装

1
sudo apt-get install libeigen3-dev

通过上面的方式进行安装的Eigen,一般是存放在/usr/include,有一个eigen3文件夹。

查看当前版本:

1
2
gedit /usr/include/eigen3/Eigen/src/Core/util/Macros.h  # 或
sed -n '10,20p' /usr/include/eigen3/Eigen/src/Core/util/Macros.h # 将Macros.h文件的第10-20行打印到终端

利用源码进行安装

这里我是在之前已经通过apt-get/usr/include/eigen3里安装了Eigen3.4.0的基础上安装配置Eigen3.3.0

  1. /usr/include新建文件夹,等会用来存放Eigen的编译生成的文件:

    1
    2
    cd /usr/include
    sudo mkdir eigen330

    如果不是为了等会版本管理时替换文件夹方便,我个人更推荐把第三方库安装在/usr/local文件夹下进行管理。例如,在/usr/local文件夹下新建文件夹eigen3,后在eigen3文件夹下新建文件夹eigen330eigen340

    所以,如果你希望使用的版本管理方法是[CMakeLists.txt文件指定](# CMakeLists.txt文件指定)(最简单),而不是[替换eigen3文件夹](# 替换eigen3文件夹),那么就完全可以把路径新建在usr/local下。

  2. 下载Eigen。

    进入你准备放置Eigen源文件的目录:

    1
    cd yourgfolder/  # 区别于第1步的eigen330

    Eigen下载链接下载你需要的Eigen版本,并解压到yourgfolder

  3. 编译Eigen。

    1
    2
    3
    4
    5
    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=/usr/include/eigen330 ..
    sudo make -j8
    sudo make install
  4. 这时,/usr/include/eigen330目录下生成了3个文件夹,分别是includelibshare。而/usr/include/eigen3目录下的3个文件(夹)分别是Eigenunsupportedsignature_of_eigen3_matrix_library

    因此,类比下,我们要使用复制命令cp/usr/include/eigen330/include/eigen3目录下的3个文件(夹)Eigenunsupportedsignature_of_eigen3_matrix_library复制到/usr/include/eigen330/目录下。

    1
    2
    3
    4
    5
    6
    cd /usr/include/eigen330/include/eigen3
    ls
    sudo cp -r Eigen/ /usr/include/eigen330/
    sudo cp -r unsupported/ /usr/include/eigen330/
    sudo cp signature_of_eigen3_matrix_library /usr/include/eigen330/
    # -r 或 --recursive:用于复制目录及其所有的子目录和文件,如果要复制目录,需要使用该选项。
  5. 这样/usr/include目录下就存在两个版本的eigen,一个是以eigen3命名的通过apt-get的方式安装的最新版本3.4.0,另外一个是以eigen330命名通过编译源码的形式安装的自选指定版本3.3.0。

版本管理

CMakeLists.txt文件指定

这是最简单的一种方法,也方便解决在一个项目中不同包需要的Eigen3版本不同的问题。

自己花了不短的时间摸索出的-_-,还是对cmake的原理(内部调用关系)认识不足。

直接在项目的CMakeLists.txt文件中指定你想使用的Eigen版本的路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 指定第三方库所在的路径,即指定其编译安装后`.cmake`文件所在的路径:
# set(Eigen3_DIR /usr/include/eigen330/lib/cmake/eigen3)
# set(Eigen3_DIR /usr/include/eigen340/share/eigen3/cmake)
# 无用。优先级问题?make时还是会指向/usr/include/eigen3

set(EIGEN3_INCLUDE_DIR "/usr/local/eigen/eigen340/include") # 确保你在`set`指定了Eigen3路径后没有调用`find_package(Eigen3 REQUIRED)`,因为这会覆盖你的设置。
# find_package(Eigen3 REQUIRED) # 查找Eigen3的CMake配置文件(通常名为`Eigen3Config.cmake`或者`Eigen3-config.cmake`)。
INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIR})

add_executable(...)
target_link_libraries(...)

message(STATUS "Eigen3_DIR: ${Eigen3_DIR}")
message(STATUS "EIGEN3_INCLUDE_DIR: ${EIGEN3_INCLUDE_DIR}")
message(STATUS "EIGEN3_VERSION_STRING: ${EIGEN3_VERSION_STRING}")

例如,如果路径为/usr/include/eigen340/include/eigen3的话(该路径下有3个文件(夹)分别是Eigenunsupportedsignature_of_eigen3_matrix_library),

  • 在代码文件中使用#include <eigen3/Eigen/Core> <-> 在CMakeLists.txt文件中使用set(EIGEN3_INCLUDE_DIR "/usr/local/eigen/eigen340/include")
  • 在代码文件中使用#include <Eigen/Core> <-> 在CMakeLists.txt文件中使用set(EIGEN3_INCLUDE_DIR "/usr/local/eigen/eigen340/include/eigen3")

如果路径错误的话,会找不到文件,会报错。

[利用apt-get进行安装](# 利用apt-get进行安装)的Eigen3的cmake文件所在的路径:/usr/share/eigen3/cmake

只使用了find_package(Eigen3 REQUIRED),没有使用set函数指定路径的CMakeLists.txt所在的包还会使用默认的Eigen版本,即/usr/include/eigen3路径下的Eigen。

为什么我使用set函数设置了Eigen3.4.0的路径为/usr/include/eigen340/share/eigen3/cmake,Cmake时打印出的message也是3.4.0的路径,但是实际make时使用的还是/usr/include/eigen3中的Eigen3.3.0?

这可能是因为你的项目中的其他地方(可能是其他CMakeLists.txt文件)也设置了Eigen的路径,而且它们的优先级高于你设置的路径。或者,你的系统环境变量中可能已经设置了Eigen的路径。

你可以尝试以下步骤来解决这个问题:

  1. 检查你的项目中的所有CMakeLists.txt文件,确保没有其他地方设置了Eigen的路径。
  2. 检查你的系统环境变量,看看是否有设置Eigen的路径。
  3. 确保你在设置Eigen路径后没有调用find_package(Eigen3),因为这会覆盖你的设置。
  4. 使用message(STATUS ${EIGEN3_INCLUDE_DIR})来打印出实际使用的Eigen路径,以便于调试。

如果以上步骤都不能解决问题,你可能需要更深入地检查你的项目配置和环境设置。

替换eigen3文件夹

使用该方法的前提是[利用apt-get进行安装](# 利用apt-get进行安装)了Eigen,也就是在系统目录/usr/include/eigen3下有Eigen的源文件,/usr/share/eigen3/cmake下有Eigen的*.cmake*文件,/usr/share/pkgconfig下有eigen3.pc

原理就是因为Eigen只有头文件,所以可以通过直接替换头文件的方法来替换Eigen的内容。

mv命令

Linux mv(英文全拼:move file)命令用来为文件或目录改名、或将文件或目录移入其它位置。

1
2
3
4
5
6
7
8
9
# 将源文件名 source_file 改为目标文件名 dest_file
mv source_file(文件) dest_file(文件)
# 将文件 source_file 移动到目标目录 dest_directory 中
mv source_file(文件) dest_directory(目录)
# 目录名 dest_directory 已存在,将 source_directory 移动到目录名 dest_directory 中;
# 目录名 dest_directory 不存在则 source_directory 改名为目录名 dest_directory
mv source_directory(目录) dest_directory(目录)
# 出错
mv source_directory(目录) dest_file(文件)

注意:需要先执行Ctrl+H显示隐藏文件命令,否则,隐藏文件以及隐藏文件夹不会被移动到新目录。

eigen3.pc文件

系统是通过eigen3.pc这个文件搜索eigen库的,两种方式安装都会生成一个eigen3.pc文件,通过apt-get安装的存放在/usr/share/pkgconfig文件夹下,通过源码安装的就存放在安装目录的share/pkgconfig文件夹下。除了第一行的安装位置以及第七行版本的差别,两个文件没有其他差别。

实际操作

由于我们的eigen3放在了/usr/include下,因此第一行不用改,保持prefix=/usr即可。需要修改Version,用哪个版本就改成哪个版本号,另一个版本用//注释掉即可,修改完保存退出。

现为3.4.0版本,想要切换到3.3.0版本:

1
2
3
4
5
6
7
8
9
10
sudo gedit /usr/share/pkgconfig/eigen3.pc
# 把Line 7 改为Version: 3.3.0
cd /usr/include
sudo mv eigen3 eigen340 # 把eigen3重命名为eigen340
sudo mv eigen330 eigen3 # 把eigen330重命名为eigen3
# 此时/usr/include目录下有文件夹eigen3(3.3.0)和eigen340

# 查看当前版本
gedit /usr/include/eigen3/Eigen/src/Core/util/Macros.h # 或
sed -n '10,20p' /usr/include/eigen3/Eigen/src/Core/util/Macros.h # 将Macros.h文件的第10-20行打印到终端

这样就通过重命名的方式改变系统查找文件时的指向,进而完成了版本切换的工作。

现为3.3.0版本,想要切换回3.4.0版本:

1
2
3
4
5
6
7
8
9
10
sudo gedit /usr/share/pkgconfig/eigen3.pc
# 把Line 7 改为Version: 3.4.0
cd /usr/include
sudo mv eigen3 eigen330 # 把eigen3重命名为eigen330
sudo mv eigen340 eigen3 # 把eigen340重命名为eigen3
# 此时/usr/include目录下有文件夹eigen3(3.4.0)和eigen330

# 查看当前版本
gedit /usr/include/eigen3/Eigen/src/Core/util/Macros.h # 或
sed -n '10,20p' /usr/include/eigen3/Eigen/src/Core/util/Macros.h # 将Macros.h文件的第10-20行打印到终端

当然,你也可以使用建立eigen3文件夹的软链接的方式,而不是替换文件夹。效果/目的都是一样的。

你也可以把安装在/usr/local/里的Eigen3调用过来,殊途同归。

参考链接

Eigen3多版本切换

ubuntu系统简单的eigen版本切换

Using Eigen in CMake Projects

ubuntu 编译eigen3.4 和eigen3.3共存

ubuntu 安装使用eigen3 (两种方式)


Eigen的安装与版本管理
http://zeyulong.com/posts/5c3493c4/
作者
龙泽雨
发布于
2024年1月10日
许可协议