简介:Eigen 3.3.3 是一份面向 C++ 开发者的线性代数库源码压缩包,广泛用于矩阵与向量运算、稀疏求解、几何变换等数值计算场景。这份资源基于 eigen-3.3.3 官方源码整理,共包含 2000 个文件,容量约 9.74MB;主体为 .h/.hh 头文件与模板实现,另配有大量 make、cmake 构建脚本、cpp/cu 示例程序、txt 说明文档以及 json 配置文件,便于在 CMake 或 Make 工程中快速引用。作为纯头文件库,Eigen 无需预编译和链接,解压后把 Eigen 目录加入项目包含路径即可直接使用,这对需要离线安装包的开发者非常方便。包内还保留了 dox 文档和单元测试样例,可辅助理解矩阵乘法、特征值分解等核心接口。资源已获得 681 人学习下载,适合希望在本地搭建 Eigen 开发环境或快速上手线性代数运算的工程师选用。 搞机器人、视觉SLAM或者点云处理的朋友,估计没少跟Eigen打交道。它就是那个让你用一行代码完成矩阵逆运算、SVD分解、特征值计算的C++模板库,号称“下载解压就能用”。但问题恰恰出在这个“下载解压”上:网上教程绝大多数都在讲最新版3.4.x,可很多老项目(比如ORB-SLAM2、VINS-Mono)明确锁定了eigen 3.3.3版本安装包,照着新版教程操作,CMake配置和头文件路径经常对不上,一不小心就编译报错。
这篇博文就围绕eigen 3.3.3版本安装包来写,把Windows、Linux、macOS三平台的下载安装、CMake集成、版本校验和常见坑一次说清楚。不管你是刚入门C++的小白,还是被老项目折腾到头疼的开发者,照着操作都能装上并跑通。
1. 先搞清楚:Eigen 3.3.3 到底是一个什么样的包
很多人在第一步就迷糊了,因为Eigen的“安装”和普通库的“安装”完全不是一个概念。这直接决定了你后续所有操作的方式。
1.1 纯头文件库,下载解压就已经“装完一半”
Eigen是一个header-only的模板库,也就是说,它的源码全部由.h头文件组成,没有.so、没有.dll、没有.a,也不需要单独编译成二进制文件。编译器在编译你的代码时,会直接把Eigen的模板实现展开到你的程序里。用生活来类比:普通库安装像是买一台整机,插上电源就能用;而Eigen更像拿到一箱零件,最关键的“组装图纸”就在头文件里,编译时自动拼装。
所以“安装eigen 3.3.3”本质上只做两件事:
- 获取eigen 3.3.3源码包
- 让编译工具(编译器、CMake、IDE)能找到它include目录下的头文件
这就导致很多人第一次安装时产生一个困惑:“我make install了,为什么没有生成库文件?”——根本没有库文件可生成,你安装的是头文件和CMake配置文件。
但细节上还是有讲究的。源码包解压后你会看到Eigen目录(注意大小写,Linux下严格区分)和unsupported目录。Eigen是官方稳定模块,unsupported是实验性模块(比如FFT、多项式、样条)。CMake配置时要特别注意,include路径要指到包含Eigen目录的上一级,而不是直接指到Eigen文件夹里面。我见过太多人把路径写成include/Eigen,结果编译器死活找不到#include <Eigen/Core>。
1.2 为什么老项目都把版本锁死在 3.3.3
Eigen 3.3.3发布于2017年,在3.3系列里算是承上启下的版本。它的API接口非常稳定,后续3.3.4到3.3.7基本都是修bug和做编译兼容性优化,功能上变化不大。很多经典开源项目在2017到2019年间活跃维护,就把依赖锁在了这个版本上。
3.3.3版相比早期版本有几个核心变化:
- 改进了向量化代码生成,对SSE/AVX指令集支持更成熟
- 优化了矩阵求逆和线性求解器性能
- 提供了更完善的C++11支持
- 修复了此前版本中部分内存对齐导致的崩溃问题
表格对比3.3系列常见版本:
| 版本 | 发布时间 | 核心特点 | 适用场景 |
|---|---|---|---|
| 3.3.1 | 2016年 | 3.3系列首个稳定版 | 老教程、老系统 |
| 3.3.3 | 2017年 | 接口稳定、兼容性好 | 大量视觉SLAM项目锁定此版本 |
| 3.3.4 | 2017年 | 修复3.3.3若干编译期bug | 需要小修版本再升级 |
| 3.3.7 | 2018年 | 3.3系列最终版,兼容性最佳 | 无明显理由时的稳妥选择 |
这里有个很实际的场景:Ubuntu 18.04通过apt默认安装的libeigen3-dev就是3.3.4,Ubuntu 20.04自带3.3.7,也就是说用包管理器安装,大概率装不到3.3.3。如果你跟我一样遇到“项目文档明确写了要求Eigen 3.3.3,编译时却提示版本不匹配”,那大概率就是包管理器版本和项目要求对不上。
2. 动手安装:三种主流安装方式与平台适配
搞清楚了Eigen的header-only属性,接下来就是实操。我按平台来拆,每个平台给一个最稳妥的方案。
2.1 Windows:解压即用,关键是路径别放错
Windows下最省事的方式就是下载官方release的zip压缩包,然后解压到一个固定目录。
步骤很简单:
- 去官方发布页找到3.3.3版本的zip包
- 解压到某个无中文、无空格的路径,例如
D:\libs\eigen-3.3.3 - 在Visual Studio的项目属性里,把
D:\libs\eigen-3.3.3添加到“C/C++ → 常规 → 附加包含目录” - 代码里直接
#include <Eigen/Core>就可以编译
如果你用CMake,那更简单,在CMakeLists.txt里加上include_directories("D:/libs/eigen-3.3.3"),或者用find_package(Eigen3 REQUIRED),后面详讲。
Windows下的两个坑要重点说:
第一,路径别带空格和中文。有人把Eigen解压到C:\Program Files (x86)\eigen 3.3.3,结果CMake的find_package解析路径时被空格搞崩溃,折腾半天还以为是Eigen和VS不兼容。第二,zip包解压后有个顶层目录(比如eigen-eigen-5a0156e40feb这种带哈希后缀的),这个哈希目录名没有固定规律,解压后要么重命名成eigen-3.3.3,要么在配置时找准路径。我见过有个同事把哈希目录名原封不动写进CMakeLists,结果换一台电脑解压哈希变了,路径又失效,浪费时间。
2.2 Linux:源码编译安装与包管理器安装二选一
Linux下有两种安装方式,思路完全不同。
方式一:源码编译安装(精确版本推荐)
wget https://github.com/eigenteam/eigen-git-mirror/archive/refs/tags/3.3.3.tar.gz tar -xzf 3.3.3.tar.gz cd eigen-git-mirror-3.3.3 mkdir build && cd build cmake .. sudo make install执行完后,头文件会安装到/usr/local/include/eigen3,CMake配置文件会安装到/usr/local/share/eigen3/cmake/。这个方式的优点是指定版本精确、不会污染系统目录,缺点是稍微多敲几条命令。
方式二:apt安装(不推荐用于锁定版本)
sudo apt install libeigen3-devapt安装速度快、依赖管理省心,但是版本完全由系统仓库决定。Ubuntu 18.04装出来是3.3.4,Ubuntu 20.04是3.3.7,你想要3.3.3根本选不了。所以项目明确要求3.3.3时,老老实实用源码安装。
这里多提一句源码安装里面的细节:Eigen官方在构建时其实可以跳过build目录直接执行make install,但官方文档推荐用out-of-source构建,也就是先建一个build目录在里面执行CMake。原因是CMake会在源码目录生成一堆缓存文件和临时产物,Eigen是纯模板库还好,如果是其他项目会污染源码树。养成这个习惯,以后编译其他库也能少吃点亏。
2.3 macOS:Homebrew与源码方式二选一
macOS上最省力的方式是Homebrew:
brew install eigen安装完成后终端会提示头文件路径在/opt/homebrew/include/eigen3(Apple Silicon)或/usr/local/include/eigen3(Intel版)。这种方式装到的版本取决于Homebrew仓库当前维护的版本,要精确装3.3.3,可以查看历史版本然后直接用源码编译,方式跟Linux一样,就是下载tar.gz、解压、cmake、make install一套流程。
我在macOS上踩过一个小坑:Homebrew安装的Eigen可能不是最新也是较新的,但某些老项目编译时不看版本号只认路径,结果代码里写的是老API,新版本虽然兼容但行为有细微差别。所以如果你在Mac上编译老项目,最稳妥的还是下载3.3.3源码包手动安装。
2.4 header-only带来的“伪安装”现象
这里要单独澄清一个问题:很多人执行完源码安装后发现/usr/local/lib目录下并没有新增任何库文件,就以为安装失败了。实际上这是正常的,我用一行命令说明Eigen安装的最终结果:
/usr/local/include/eigen3/Eigen/Core /usr/local/share/eigen3/cmake/Eigen3Config.cmakeEigen安装完毕后主要产物就是头文件目录和一个CMake配置文件。没有二进制库文件。所以当你用ldconfig或者ls /usr/local/lib检查时看不到东西,不代表安装有问题。
3. CMake工程集成:让编译器找到头文件
安装只是第一步,真正让工程跑起来的是CMake配置。Eigen在CMake里的集成方式非常灵活,但也很容易写错。
3.1 find_package 正确用法与 EXACT 精确匹配
最规范的写法是:
cmake_minimum_required(VERSION 3.10) project(eigen_demo) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Eigen3 3.3 REQUIRED NO_MODULE) add_executable(demo main.cpp) target_link_libraries(demo Eigen3::Eigen)注意几个点:
NO_MODULE是为了使用Eigen3Config.cmake这种现代CMake的package配置模式,而不是老的FindEigen3.cmake模块模式。如果你不加NO_MODULE,CMake会优先搜索FindEigen3.cmake,而老模块里获取的变量名是EIGEN3_INCLUDE_DIR,写法完全不同。- 版本号写
3.3表示要求3.3及以上版本,如果你一定要精确3.3.3,可以加EXACT参数:
find_package(Eigen3 3.3.3 EXACT REQUIRED NO_MODULE)这样CMake找到的版本只要不是3.3.3就会直接报错,从底层杜绝“装错版本”的问题。
如果不想用find_package,也可以用最粗暴的include_directories:
include_directories("/usr/local/include/eigen3")这种写法的优点是简单直观,缺点是换环境就得改路径,也不方便版本管理。我建议新项目用Eigen3::Eigen目标方式,老项目如果原本就是include_directories风格,没必要瞎折腾,保持原样就好。
3.2 一个可直接编译的矩阵运算 Demo
写一个最简单的Demo用来验证Eigen安装是否成功,代码内容就是输出Eigen版本号并做一次矩阵乘法。
#include <iostream> #include <Eigen/Dense> int main() { std::cout << "Eigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << std::endl; Eigen::Matrix3d A; A << 1, 2, 3, 4, 5, 6, 7, 8, 10; Eigen::Vector3d b(1, 2, 3); Eigen::Vector3d x = A.colPivHouseholderQr().solve(b); std::cout << "Solution x:\n" << x << std::endl; return 0; }编译并运行:
mkdir build && cd build cmake .. make ./demo输出类似这样:
Eigen version: 3.3.3 Solution x: -0.333333 0.666667 0看到Eigen version: 3.3.3就说明安装和集成全部正常。
3.3 编译期版本验证三件套
除了上面Demo里的宏输出,还有几种验证版本的方式,按场景不同选择:
- 看宏:
EIGEN_WORLD_VERSION、EIGEN_MAJOR_VERSION、EIGEN_MINOR_VERSION三个宏组合出来的数字就是当前生效的版本。这是最直接的方式,编译期就能看到。 - 看CMake变量:find_package成功后,可以通过
${Eigen3_VERSION}变量拿到版本号,在CMakeLists里message(STATUS "found Eigen version: ${Eigen3_VERSION}")打印出来。 - 看头文件路径:编译器加
-H参数或者-E -dM预处理输出,能列出实际包含的头文件绝对路径,排查多版本污染时非常好用。
版本验证这一步千万别省。很多时候你以为装的是3.3.3,实际因为环境变量PATH、CMake缓存、系统目录干扰,编译用的根本不是同一个版本,排查起来会异常痛苦。
4. 常见问题与避坑实录
最后这部分是我实际折腾Eigen时遇到的最多的坑,整理成一个速查表,另外每个问题展开说一下排查思路。
4.1 多版本共存:头文件路径污染怎么破
场景是这样:你自己源码编译了一个3.3.3到/usr/local/include/eigen3,同时apt也装了一个3.3.7在/usr/include/eigen3。CMake的find_package搜索路径通常按“当前项目优先 → 用户目录 → 系统目录”的顺序,但很多老项目的CMakeLists里又同时存在include_directories和find_package,两个路径打架,最终编译器可能用了/usr/include/eigen3里的3.3.7头文件。
排查命令特别简单:
grep -R "EIGEN_MINOR_VERSION" /usr/include/eigen3/Eigen/src/Core/util/Macros.h grep -R "EIGEN_MINOR_VERSION" /usr/local/include/eigen3/Eigen/src/Core/util/Macros.h分别看看系统目录和用户目录里各自是什么版本。如果确实存在多版本,解决方案有三个:
- 卸载apt安装的eigen:
sudo apt remove libeigen3-dev - 用CMake的
CMAKE_IGNORE_PATH排除特定搜索目录 - 在CMakeLists里显式
include_directories(BEFORE /usr/local/include/eigen3),让用户目录优先
我个人的习惯是把所有个人编译的库都装在/usr/local,系统包管理器装的一律不用,然后通过CMake的NO_DEFAULT_PATH限制搜索范围,一劳永逸。
4.2 对齐断言与编译报错
Eigen在3.3.x时代对内存对齐要求很高,尤其是固定尺寸的向量和矩阵(比如Vector4d、Matrix2d),如果你在类里直接定义Eigen对象作为成员变量,并且用STL容器存放固定尺寸Eigen类型,很容易触发类似下面的编译断言:
static assertion failed: YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES或者运行期崩溃,报错和unaligned相关。
解决办法有三个:
- 在类成员里添加
EIGEN_MAKE_ALIGNED_OPERATOR_NEW宏 - 使用
Eigen::aligned_allocator替代std::allocator - 如果你确定不需要向量化加速,可以在编译选项里加
-DEIGEN_MAX_ALIGN_BYTES=0禁用对齐
第三种方式最省事,但会牺牲SIMD性能,不建议在追求性能的项目里用。Eigen官方文档里对这个问题的描述非常详细,核心原则就是:允许编译器告诉你如何对齐,不要自己去手动控制内存地址。
4.3 下载渠道与验证包完整性
Eigen 3.3.3安装包建议优先使用官方发布页的release附件,或者是官方git镜像仓库的tag标签。下载完成后建议先做两步验证:
- 校验文件大小和解压是否报错,很多“安装失败”其实是压缩包下载不完整导致解压缺文件
- 解压后检查
Eigen/src/Core/util/Macros.h里的三个宏是否匹配3.3.3
另外,下载的Eigen安装包建议归档保存,因为很多项目构建时对Eigen的版本是硬性要求,万一以后换电脑、换环境,安装包还是原来那个版本最稳妥。我本地的做法是建了一个/libs/eigen/3.3.3目录,专门存放源码包和解压后的文件,用CMake时直接定位这个目录,从不在系统全局目录里装来装去。
| 常见问题 | 原因 | 解决方案 |
|---|---|---|
| 编译报找不到Eigen/Core | include路径未配置或写错层级 | 检查include路径指向包含Eigen目录的上级目录 |
| 版本输出3.3.7但想要3.3.3 | 多版本共存路径污染 | 用grep定位实际生效的头文件路径,清理多余版本 |
| static assertion failed对齐报错 | 固定尺寸Eigen类型对齐问题 | 添加EIGEN_MAKE_ALIGNED_OPERATOR_NEW或使用aligned_allocator |
| CMake提示找不到Eigen3 | find_package搜索路径不包含安装目录 | 显式设置Eigen3_DIR缓存变量指向配置文件目录 |
| 解压失败或缺文件 | 下载源包损坏 | 重新下载并校验文件完整性 |
最后再分享一个个人经验:Eigen这个库,版本不在多新,而在准。很多项目锁3.3.3不是因为新功能,而是因为测试全部在这个版本上跑过,贸然更新版本,编译能过但结果可能就变了。安装Eigen这件事,最忌讳的就是“这个版本应该也能用”的侥幸心理。该锁定3.3.3就锁死,别让“版本漂移”成为你调不通代码的第一嫌疑人。
本文还有配套的精品资源,点击获取