新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux下Eigen、OSQP与OSQP-Eigen安装指南:CMake链接避坑实战

发布时间:2026/10/1 5:17:36来源:尧图网络
Linux下Eigen、OSQP与OSQP-Eigen安装指南:CMake链接避坑实战
在Linux上装Eigen、OSQP、OSQP-Eigen这三个库说难不难但说简单也真不简单。尤其是当你第一次接触OSQP-Eigen以为它就是又一个C库直接clone、cmake、make一条龙结果在CMake阶段就被Could not find a package configuration file provided by Osqp打懵的时候你就会明白这三样东西的关系、安装顺序和CMake链接逻辑比想象中要绕一点。这篇文章把我实际安装和验证的过程完整写下来包括我踩过的坑、为什么这么装、装完怎么确认能用以及一段可以直接跑的求解代码。适合在Ubuntu、Debian、CentOS这类Linux发行版上做机器人控制、模型预测控制、轨迹优化、二次规划相关开发的同学参考。1. 先弄明白这三样东西到底是什么关系很多人上来就照着网上的命令一通装装完发现include头文件的时候还是报错根本原因是没搞懂这三个库各自的角色以及它们是怎么串起来的。1.1 Eigen一个不需要编译的线性代数模板库Eigen是C写的模板头文件库核心功能是矩阵运算、向量运算、线性方程组求解、特征值分解等。它最特别的地方在于它没有.so或.a文件不需要单独编译。你在项目里include它的头文件编译器直接就把代码展开了。也正因为是模板库Eigen的版本兼容性相对严格。它的API在不同版本之间有变动尤其是高版本新增了一些矩阵类型和算法旧版本没有。如果你的代码用了某个新API但系统里装的是老的Eigen编译期就会报一堆no member named之类的错误。在Linux上Eigen最常见的安装位置是/usr/include/eigen3头文件会放在/usr/include/eigen3/Eigen/这个子目录下。这个细节后面会坑到你我先提前说一句。1.2 OSQP一个用C写的二次规划求解器OSQPOperator Splitting Quadratic Program是一个专门求解凸二次规划问题的开源求解器由牛津大学团队维护。它底层用C语言实现所以安装后会生成动态库和头文件和Eigen完全不是一回事。OSQP解决的二次规划问题是这种形式min 0.5 * x * P * x q * x s.t. l A * x u其中P是对称正半定矩阵A是约束矩阵l和u是上下界。这类问题在模型预测控制、运动规划、金融组合优化里特别常见。OSQP本身的接口是C API用起来有点啰嗦。你要自己创建OSQPSettings、OSQPData、OSQPSolver这些结构体再手动设置矩阵的数值。所以在实际工程里大家更习惯用一个C封装层这就是OSQP-Eigen存在的意义。1.3 OSQP-Eigen把OSQP包装成Eigen风格的C接口OSQP-Eigen是意大利技术研究院IIT的机器人实验室开源的库专门用Eigen的数据类型封装OSQP的C接口。它把OSQP里那些结构体全部隐藏在内部对外提供的是一个OsqpEigen::Solver类构造数据和求解都变得非常直观。它的依赖链是这样的Eigen基础矩阵运算 └── OSQP底层求解器C接口 └── OSQP-EigenC封装依赖上面两者所以安装顺序必须是Eigen - OSQP - OSQP-Eigen。反着装或者漏装后面都会出问题。我在实际安装时发现OSQP-Eigen的CMake工程会在配置阶段就强制寻找Eigen3和Osqp这两个依赖包找不到直接报错不会给你任何商量的余地。2. 安装方式选型apt、源码、还是包管理器很多教程会直接告诉你sudo apt install libeigen3-dev libosqp-dev然后编译安装osqp-eigen结束。这个流程在多数情况下能跑通但有几个隐藏的坑2.1 我推荐的组合能apt就apt源码编译兜底我的建议是分层次处理Eigen优先用apt装的版本只要不是太老的发行版libeigen3-dev一般够用。但如果你的代码用到了Eigen 3.4才有的特性那就需要编译最新源码。OSQP优先源码编译。apt仓库里虽然有libosqp-dev但版本往往偏老且不一定带CMake配置文件而OSQP-Eigen在查找依赖时需要的正是这个CMake config文件。OSQP-Eigen只能源码编译没有apt包。用apt最大的好处是省事它会把头文件、库文件、CMake配置文件全部放到系统目录下之后find_package基本不用手动指定路径。源码编译则需要你注意安装路径和CMake查找路径的对应关系否则就会遇到明明装了却找不到包的诡异情况。2.2 不同发行版的差异注意点以Ubuntu为例这几个库的包名分别是发行版Eigen包名OSQP包名OSQP-Eigen包名Ubuntu/Debianlibeigen3-devlibosqp-dev无Fedora/RHELeigen3-develosqp-devel无Arch Linuxeigenosqp无CentOS/RHEL系列里OSQP的包不一定在默认源里可能需要启用EPEL或者直接从源码编译。我自己的经验是与其跟仓库版本较劲不如统一走源码编译至少你能控制版本也能保证CMake配置文件的路径是正确的。另外提醒一句在同一台机器上如果又用apt又用源码装同一个库很容易出现头文件覆盖、库版本不一致的问题。比如你apt装了OSQP后来又手抖编译安装了一个新版本两个版本的头文件和库混在一起程序链接时可能会莫名其妙地加载到旧版本。装之前最好先确认一下系统里是不是已经有同名库了。3. 手把手安装从零到编译通过我以Ubuntu 22.04为例从零开始完整走一遍安装流程。如果你用其他发行版把包管理器命令替换成对应的即可。3.1 安装Eigensudo apt update sudo apt install -y libeigen3-dev装完后验证一下dpkg -L libeigen3-dev | grep Eigen你会看到类似这样的输出/usr/include/eigen3/Eigen/Core /usr/include/eigen3/Eigen/Dense /usr/include/eigen3/Eigen/Sparse /usr/include/eigen3/Eigen/Cholesky /usr/share/eigen3/cmake/Eigen3Config.cmake说明头文件和CMake配置文件都在系统目录里了。注意这里的关键点头文件根目录是/usr/include/eigen3而不是/usr/include。所以你在写#include Eigen/Dense的时候编译器需要额外的include路径/usr/include/eigen3才能找到文件。如果你需要最新版Eigen可以走源码安装wget https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz tar xzf eigen-3.4.0.tar.gz cd eigen-3.4.0 mkdir build cd build cmake .. sudo make installEigen是header-only库所谓make install实际上只是把头文件和CMake配置复制到/usr/local/include/eigen3和/usr/local/share/eigen3/cmake。装完后用find_package(Eigen3)就能找到或者手动加一个/usr/local/include/eigen3到include目录。3.2 源码编译安装OSQP建议直接clone官方仓库然后走标准的CMake流程git clone --recursive https://github.com/osqp/osqp.git cd osqp mkdir build cd build cmake -G Unix Makefiles .. cmake --build . sudo cmake --install .--recursive参数很重要因为OSQP依赖ODBC、SuiteSparse这些子模块不拉子模块的话编译到一半会报缺文件。编译完成后默认安装位置是/usr/local。你需要确认这几个文件都出现了/usr/local/include/osqp/osqp.h/usr/local/lib/libosqp.so/usr/local/lib/cmake/osqp/OsqpConfig.cmake其中OsqpConfig.cmake是OSQP-Eigen能不能找到它的关键。如果你用的是系统的libosqp-dev这个文件在/usr/lib/cmake/osqp/下路径不一样而已。如果你想指定安装路径可以在cmake阶段加-DCMAKE_INSTALL_PREFIX~/.local。但我不建议这么干因为后续每次编译项目你都要手动告诉CMake去哪找OSQP平白无故多出一堆路径配置。3.3 编译安装OSQP-Eigen装完依赖终于轮到主角了git clone https://github.com/robotology/osqp-eigen.git cd osqp-eigen mkdir build cd build cmake -DOSQP_EIGEN_UNIT_TESTSOFF -DCMAKE_BUILD_TYPERelease .. make -j$(nproc) sudo make install这里我特意关掉了OSQP_EIGEN_UNIT_TESTS这个开关原因后面讲。install完成后再确认一下/usr/local/include/OsqpEigen/OsqpEigen.h/usr/local/lib/libOsqpEigen.so/usr/local/lib/cmake/OsqpEigen/OsqpEigenConfig.cmake这三个文件齐全安装就基本成功了。3.4 配置CMake的查找路径如果你全流程都用默认路径安装其实不需要手动配置什么。但如果你装到过自定义目录或者系统里同时存在多个版本的同一个库那就需要显式告诉CMake去哪找。最常见的一种写法是在~/.cmake/packages或直接在项目的CMakeLists.txt开头设置set(Osqp_DIR /usr/local/lib/cmake/osqp) set(OsqpEigen_DIR /usr/local/lib/cmake/OsqpEigen)你也可以用环境变量export Osqp_DIR/usr/local/lib/cmake/osqp export OsqpEigen_DIR/usr/local/lib/cmake/OsqpEigen在写find_package之前把路径指对后面就顺了。4. 踩坑实录我在这条路上卡过的四个坎这部分是我真正想写的。网上教程大多是命令复制粘贴级别的但实际安装中遇到的坑不会有人提前告诉你。4.1 找不到Osqp的CMake配置包路径比想象中更严格新装的OSQP明明已经在/usr/local下了但cmake配置osqp-eigen时依然报Could not find a package configuration file provided by Osqp with any of the following names: OsqpConfig.cmake osqp-config.cmake我当时的反应是包管理器没配上吗重新make install一遍没用。后来用find / -name OsqpConfig.cmake 2/dev/null一查发现文件在/usr/local/lib/cmake/osqp/里。问题出在CMake的查找路径上。CMake默认在系统路径和/usr/local/lib/cmake、/usr/local/share/cmake这些目录下找但不同版本的CMake对非标准路径的处理不太一样。有些时候它不会自动去找/usr/local/lib/cmake需要你在CMakeLists里显式指定。解决办法很简单就是在配置osqp-eigen之前设置环境变量或者直接把Osqp_DIR加到CMake命令里cmake -DOsqp_DIR/usr/local/lib/cmake/osqp ..如果你用的是apt装的libosqp-dev对应的路径通常是/usr/lib/cmake/osqp可以先用find /usr -name *osqp*cmake*找到确切位置。这个坑还有一个变种先装了OSQP-Eigen后来才装OSQP。OSQP-Eigen的CMake配置阶段就会检查依赖依赖缺失直接失败所以安装顺序必须严格保持。4.2 Eigen头文件带了eigen3前缀目录include时容易懵Eigen装完后头文件在/usr/include/eigen3/Eigen/下。所以你在代码里写#include Eigen/Core编译时必须要让编译器能搜到/usr/include/eigen3这个目录。如果直接在CMakeLists里写find_package(Eigen3 REQUIRED) include_directories(${EIGEN3_INCLUDE_DIR})那一般没问题。但如果你图省事直接在target_include_directories里写/usr/include那么#include Eigen/Core是找不到的因为实际路径是/usr/include/eigen3/Eigen/Core。我见到有人的解决方法是include的时候写#include eigen3/Eigen/Core也能编译过但这样不够简洁换到别的机器上很可能就崩了。正确做法是给编译器加上-I/usr/include/eigen3然后代码里保持#include Eigen/Core。4.3 单元测试开关导致编译卡死我第一次编译osqp-eigen的时候直接照搬了网上某条命令cmake .. make -j8结果编译到一半各种测试依赖的头文件缺失报错信息铺天盖地。后来才发现osqp-eigen默认会编译单元测试而测试代码依赖Google Test之类的库我没装自然编译不过。解决办法就是在cmake配置时加上-DOSQP_EIGEN_UNIT_TESTSOFF。这个开关官方文档里有提但不仔细看很容易漏掉。还有一次我是在嵌入式板子上编译内存只有1GBmake -j$(nproc)直接把机器卡死了。后来改成make -j2才勉强跑完。对于小内存机器一定不要无脑-j$(nproc)。4.4 版本太旧导致API对不上OSQP-Eigen对OSQP的版本是有要求的。旧版的OSQP比如0.5.x和某些版本的OSQP-Eigen组合会出现solver.solve()返回错误、甚至运行时崩溃的情况。如果你发现osqp-eigen的示例代码在你自己工程里怎么调都不对先检查版本# 查看osqp版本 grep -r OSQP_VERSION /usr/local/include/osqp/constants.h我建议直接装OSQP最近的release版本不要用太老的distro自带包。Ubuntu 20.04的libosqp-dev版本偏旧你如果后面要对接MPC或轨迹优化很可能踩到某些新功能缺失的问题。Eigen也是同理。比如Eigen::Map、Eigen::Ref这些API在新老版本中都有但某些稀疏矩阵操作的函数签名在不同版本里有细微差别。Eigen版本尽量用3.4以上兼容性会好很多。5. 装完怎么知道能用写个小程序跑一遍安装完成不等于万事大吉。写个测试程序真正跑通一次求解才算真正搞定。5.1 CMakeLists.txt的正确写法我建议用下面这份CMakeLists.txt作为模板cmake_minimum_required(VERSION 3.16) project(osqp_eigen_demo) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Eigen3 REQUIRED) find_package(Osqp REQUIRED) find_package(OsqpEigen REQUIRED) add_executable(osqp_eigen_demo main.cpp) # 如果上面三个find_package都成功了一般不需要手动指定路径 # 但如果你用的CMake版本较老可能需要加下面这几行 if(NOT Osqp_DIR) set(Osqp_DIR /usr/local/lib/cmake/osqp) endif() if(NOT OsqpEigen_DIR) set(OsqpEigen_DIR /usr/local/lib/cmake/OsqpEigen) endif() target_include_directories(osqp_eigen_demo PRIVATE ${EIGEN3_INCLUDE_DIR} ${OsqpEigen_INCLUDE_DIRS} ) target_link_libraries(osqp_eigen_demo PRIVATE OsqpEigen::OsqpEigen )这个写法的好处是兼容性比较强。OsqpEigen::OsqpEigen是osqp-eigen的CMake target链接它的时候会自动带上OSQP的库依赖。如果你的osqp-eigen版本比较老可能没有这个target这时候可以退而求其次直接链接库文件target_link_libraries(osqp_eigen_demo PRIVATE /usr/local/lib/libOsqpEigen.so /usr/local/lib/libosqp.so )两种方式至少有一种能跑通。5.2 一段可复现的OSQP-Eigen求解示例下面这段代码解决一个非常简单的二维二次规划问题minimize x1^2 x2^2 - x1 - x2 subject to x1 x2 10这个问题的最优解是(0.5, 0.5)可以用来自测。#include OsqpEigen/OsqpEigen.h #include Eigen/Dense #include Eigen/Sparse #include iostream int main() { // 目标函数中的H矩阵二次项 Eigen::SparseMatrixdouble H(2, 2); H.insert(0, 0) 2.0; H.insert(1, 1) 2.0; H.makeCompressed(); // 目标函数中的f向量一次项 Eigen::VectorXd f(2); f -1.0, -1.0; // 约束矩阵A Eigen::SparseMatrixdouble A(1, 2); A.insert(0, 0) 1.0; A.insert(0, 1) 1.0; A.makeCompressed(); // 约束上下界 Eigen::VectorXd lowerBound(1); lowerBound -10.0; Eigen::VectorXd upperBound(1); upperBound 10.0; OsqpEigen::Solver solver; // 设置求解器参数 solver.settings()-setVerbosity(false); solver.settings()-setWarmStart(true); // 设置问题维度 solver.data()-setNumberOfVariables(2); solver.data()-setNumberOfConstraints(1); // 设置矩阵 if (!solver.data()-setHessianMatrix(H)) { std::cerr set Hessian matrix failed std::endl; return 1; } if (!solver.data()-setGradient(f)) { std::cerr set gradient failed std::endl; return 1; } if (!solver.data()-setLinearConstraintsMatrix(A)) { std::cerr set constraint matrix failed std::endl; return 1; } if (!solver.data()-setLowerBound(lowerBound)) { std::cerr set lower bound failed std::endl; return 1; } if (!solver.data()-setUpperBound(upperBound)) { std::cerr set upper bound failed std::endl; return 1; } // 初始化求解器 if (!solver.initSolver()) { std::cerr init solver failed std::endl; return 1; } // 求解 if (!solver.solve()) { std::cerr solve failed std::endl; return 1; } Eigen::VectorXd solution solver.getSolution(); std::cout solution: solution.transpose() std::endl; return 0; }编译运行cmake -S . -B build cmake --build build ./build/osqp_eigen_demo如果输出solution: 0.5 0.5恭喜你三个库全部安装成功而且CMake配置和链接也完全正常。5.3 常见链接错误速查我把自己遇到过的链接相关报错整理成一个表方便你对照排查报错信息原因解决办法fatal error: OsqpEigen/OsqpEigen.h: No such file or directoryinclude路径没加对确认find_package(OsqpEigen)执行成功target_include_directories里加入${OsqpEigen_INCLUDE_DIRS}undefined reference to OsqpEigen::Solver::initSolver()忘了链接libOsqpEigentarget_link_libraries里加上OsqpEigen::OsqpEigenundefined reference to osqp_*找不到OSQP动态库确认libosqp.so被链接或者CMake里显式加/usr/local/lib/libosqp.soCMake Error at CMakeLists.txt: find_package(Osqp) requires a string变量类型错误set(Osqp_DIR /usr/local/lib/cmake/osqp)路径必须带引号6. 我最后的几个习惯性建议到这里安装、验证、测试就全走完了。系统里现在应该同时存在Eigen、OSQP和OSQP-Eigen三个库而且能用CMake正确链接。最后再分享几个我自己形成习惯的做法不一定出现在官方文档里但长期用下来真能省不少事。一是不要图省事只装一个库。OSQP-Eigen是依赖前两者的只装它没意义。二是所有涉及源码编译的库尽量把CMAKE_INSTALL_PREFIX统一到一个路径下比如/usr/local。这样后面对外交付工程时CMake的查找路径只需要配置一次。三是源码包clone下来之后先看一眼CMakeLists.txt里的可选项比如OSQP-Eigen的单元测试开关默认是开的不确定自己需要不需要的话先关掉再编译避免编译到一半报错。四是我个人的习惯把这些库的安装命令写成一个shell脚本丢到团队的开发环境初始化脚本里。新同事入职需要配环境时直接跑一遍不会漏步骤也不会撞版本。脚本里加一个set -e任何一步出错就停下来大家都能很快定位问题。Linux下装第三方C库这件事说到底是三个词路径、版本、依赖顺序。把这三样都理顺了什么库都拦不住你。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

并行计算从原理到实战:缓存一致性、OpenMP与性能陷阱 2026/10/1 6:18:34

并行计算从原理到实战:缓存一致性、OpenMP与性能陷阱

并行计算这四个字,很多人第一次真正注意到它,是在《深入理解计算机系统》那本书里讲并发的那一章,或者在操作系统课上被老师用二十分钟带过。但当你真的坐到键盘前,想让一段代码跑满机器上那十六个物理核心,才会发现课…

阅读更多 →
Scrapy+ElasticSearch+Django构建小型全文搜索引擎实战 2026/10/1 6:18:33

Scrapy+ElasticSearch+Django构建小型全文搜索引擎实战

简介:基于Scrapy、ElasticSearch与Django的小型全文搜索引擎毕业设计项目,面向计算机相关专业学生及需要快速搭建垂直搜索应用的开发者。资源围绕爬虫采集、索引构建、Web检索三条主线展开,覆盖需求分析、技术选型、爬虫策略、索引映射、Djan…

阅读更多 →
YOLOv5自定义数据集训练指南:从目录格式到避坑实践 2026/10/1 6:18:27

YOLOv5自定义数据集训练指南:从目录格式到避坑实践

简介:面向小型目标检测与水果分拣场景,提供一套开箱即用的YOLOv5格式数据集,覆盖苹果、橘子、梨三个类别,包含完整训练集与验证集。所有图像均为1080810的RGB照片,每张图含多个目标且边界框标注完整,可直接…

阅读更多 →
外贸GEO优化公司哪家好?聚焦B2B出口企业的询盘转化提升与海外市场覆盖策略 2026/10/1 6:18:27

外贸GEO优化公司哪家好?聚焦B2B出口企业的询盘转化提升与海外市场覆盖策略

当海外买家不再用搜索引擎找供应商,你的品牌还找得到吗过去十几年,中国B2B外贸企业的获客路径非常清晰:建英文官网、投Google竞价、入驻B2B平台、等待询盘邮件。但这套逻辑正在被快速改写。海外采购商如今越来越多地直接向ChatGPT、Gemini、P…

阅读更多 →
ESP32-S3环境监测节点Madeira:硬件选型、固件架构与低功耗设计 2026/10/1 6:18:27

ESP32-S3环境监测节点Madeira:硬件选型、固件架构与低功耗设计

最近在整理一个用 ESP32-S3 做的桌面环境监测小项目,项目代号就叫 Madeira。名字是随手取的,没有特别含义,但这套板子的硬件选型、固件结构和联调方法,做完之后基本沉淀成了我手边一个可复用的物联网节点模板。所以这篇文章打算把…

阅读更多 →
计算机系统与并行计算:任务分解、内存一致性与加速比 2026/10/1 6:18:27

计算机系统与并行计算:任务分解、内存一致性与加速比

1. 为什么并行计算不是"多开几个线程"这么简单我见过太多人第一次接触并行计算时的反应:既然一个核跑得慢,那就开八个线程一起跑,速度不就翻八倍了?这个想法很符合直觉,但现实往往很残酷——你写完多线程版本…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉