IDE: XCode Tutorial(Mac)
平台信息:(MacBook Pro、Apple M1 Pro、Sequoia 15.1)
参考工程:
*/lht_Xcode/Learn_Eigen_Sophus_Pinocchio_boost
以(Eigen、Sophus、Pinocchio、Boost)这四个C++库的使用以例
Note: 只在在知乎上发过一个帖子,进行过记录XCode Version 16.1
。本文档是对之前的记录进行修改完善,软件版本有一定的升级XCode Version 16.3
,版本应该影响不大。
1 XCode与brew介绍
1.1 brew介绍
homebrew是一个开源的包管理器,一般主要用于mac上。homebrew官网(打开如下图所示);brew github。利用brew工具可以下载库。
# brew常用的几个命令
brew --version # 查看brew版本。
brew update # 更新 Homebrew 本身及其软件配方(Formulae)信息
brew upgrade # 升级本地安装的软件
brew list # 查看brew所安装的libraries。
brew install <package_name> #安装
brew info <package_name> # 查看package信息。
brew --prefix <package_name> # 查看库的地址。
大多数软件包会提供预编译的二进制文件(bottle)。brew一般就是安装的是编译好的版本。利用brew info <package_name>
查看。
1.2 brew安装位置
对心新手,可能比较好奇:利用brew
安装的库,到底安装哪里去了呢?
注意:Mac上磁盘默认情况下,只有这四个文件
需要显示隐藏文件(shift cmd .),找到opt
在/opt/homebrew/Cellar
文件夹下就可以找到下载的库。比如后面介绍的eigen
、sophus
、pinocchio
等
使用这个brew --prefix pinocchio
、brew --prefix eigen
命令可以查询库的地址。
/opt/homebrew/opt/pinocchio
/opt/homebrew/opt/eigen
/opt/homebrew/opt/xxx
是一个快捷方式(symlink),指向 xxx
的实际安装目录。
/opt/homebrew/Cellar/xxx
是库的实际安装路径,即最终真实路径为:
/opt/homebrew/Cellar/eigen
/opt/homebrew/Cellar/pinocchio
1.3 conda和pip安装位置
conda主要是环境和包管理,主要是python语言,也支持其他语言(但用的不多)
注意:conda中涉及的python版本跟conda有关,跟系统自带、homebrew,官网安装都没关系。
利用conda的话,一般会创建虚拟环境,比如env_temp。在这个虚拟环境中中安装的库,一般会在opt/anaconda3/envs/env_temp/lib/python3.x/site-packages/。如果使用PyCharm,下图就是存放库的文件夹。
pip是python官方的包管理工具。专门用于安装 Python 包(从 PyPI 仓库中获取)
pip安装的库的位置取决于使用的环境等因素、
-
如果还是conda创建的虚拟环境,同上
-
如果不是onda创建的虚拟环境,就是空的话,跟python和pip有关。
which python3
/Library/Frameworks/Python.framework/Versions/3.13/bin/python3
which pip
/opt/homebrew/bin/pip
1.4 XCode介绍
1.4.1 Xcode_Command Line Tool
Xcode是苹果公司向开发人员提供的集成开发环境,用于开发macOS、iOS、iPadOS、watchOS、tvOS和visionOS的应用程序。
打开Xcode软件$\to$Create New Project,会看到如下界面。
对于我们来说,就用到命令行工具,调C++库,写代码就可以
Create New Project…$\to$ macOS$\to$Command Line Tool)
1.4.2 引用C++库
按照1.4.1建立的工程,会有一个main.cpp的文件,有一个示例程序,可以用标准c++的库函数,比如
iostream
、fstream
、sstream
等等。 但是涉及特定的C++的库,就需要自己下载。
- 1 包含头文件
有的C++库只由头文件组成,那么只需要这一步就可以了,比如
Eigen
、Sophus
、manif
等;
另外,对于这种只有头文件的库,将下载好的库直接拖到这个路径下/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/
中,也是可以的。以eigen库的安装进行了举例,参考。
- 2 包含lib库
-
3.1 Other Linker Flags(下面这个图,在搞清楚一下,在修改一下)
-
3.2 跟3.1的目的类似,但是好像也不管用。
2 Eigen, Sophus库的安装与使用
2.1 eigen
method 1: without brew
Eigen是一个纯头文件构建的库,没有.cpp,也没有.lib,直接include就可以
在mac上,直接下载、解压,得到eigen-3.4.0。将这个文件夹中的Eigen文件夹
拖到
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/
中,就可以直接使用了。
在XCode中就可以愉快使用了(不需要进行其他的链接等配置)
method 2: with brew
利用brew install eigen
方法安装。
在Header Search Paths
中添加路径/opt/homebrew/Cellar/eigen/3.4.0_1/include/eigen3
即可
注意:并且在
PROJECT
和TARGETS
中都有Header Search Paths
,一般是TARGETS
中添加路径。
2.2 sophus(brew)
这个库也是只有头文件的
直接利用brew安装:brew install sophus
。
也是安装在了/opt/homebrew/Cellar/sophus
中。
和基于brew方法安装eigen的操作相同,在头文件中包含就可以了。
3 pinocchio、boost库(C++版)(brew)
参考这个,在Mac利用brew上安装、直接运行的下图的两行代码
pinocchio库需要依赖boost库。但是boost库在xcode上感觉有问题一直不成功。
基本把全网的方法都尝试了就是不行???2024.11.18。
(终于解决啦2024.11.18)在header search paths和library search paths包含include和lib的时候,不要选择recersive模式,直接就non-recursive模式就可以了,太tm无语了,也不知道为啥!!!
4 demo(Eigen, Sophus, Pinocchio)
完成上述配置,就可以愉快的写代码了,测试代码如下:
#include <iostream>
#include <ctime>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/Dense>
#include <pinocchio/multibody/sample-models.hpp>
#include "pinocchio/algorithm/joint-configuration.hpp"
#include "pinocchio/algorithm/rnea.hpp"
#include <sophus/se3.hpp>
int main(int argc, const char * argv[]) {
// 计算程序运行时间
clock_t start,finish;
start=clock();
// 测试一下Eigen库
Eigen::MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
std::cout << m << std::endl;
// 测试一下sophus库
// 沿着Z轴旋转90度的旋转矩阵
Eigen::Matrix3d R = Eigen::AngleAxisd(M_PI / 2, Eigen::Vector3d(0, 0, 1)).toRotationMatrix();
Eigen::Quaterniond q_(R);
Sophus::SO3d SO3_R(R);
Sophus::SO3d SO3_q(q_);
std::cout << "SO(3) from matrix:\n" << SO3_R.matrix() << std::endl;
std::cout << "SO(3) from quaternion:\n" << SO3_q.matrix() << std::endl;
std::cout << "they are equal" << std::endl;
// 测试一下pinocchio库
// 参考:https://gepettoweb.laas.fr/doc/stack-of-tasks/pinocchio/master/doxygen-html/
pinocchio::Model model;
pinocchio::buildModels::manipulator(model);
pinocchio::Data data(model);
Eigen::VectorXd q = pinocchio::neutral(model);
Eigen::VectorXd v = Eigen::VectorXd::Zero(model.nv);
Eigen::VectorXd a = Eigen::VectorXd::Zero(model.nv);
const Eigen::VectorXd & tau = pinocchio::rnea(model, data, q, v, a);
std::cout << "tau = " << tau.transpose() << std::endl;
finish=clock();
std::cout << finish-start << "/" << CLOCKS_PER_SEC << " (s) "<< std::endl;
return 0;
}
运行结果
5 进阶
5.1 XCode多cpp文件
如果只是想验证多个cpp文件的功能,彼此没有耦合关系。
运行哪个文件,就设置它的Taret Membership,其他文件不要设置,就可以了。
5.2 brew不能安装的C++库(如manif)
有一些库不能直接用brew直接安装,需要自己手动编译,比如manif库。
想要编译的库的存放位置,比较随意。可以直接在某个工程中新建一个dev文件夹,在这个dev中进行clone、cmake等操作。manif的C++安装教程。
编译好的库一般在/usr/local/include/
中。
然后在XCode中进行配置。参考1.4.2。
5.3 安装Pangolin
Pangolin是《视觉SLAM十四讲》P.66 中提到的一个库。
==2025.6.21==
利用Port:sudo port install Pangolin
。过程比较慢。
安装成功以后,检查一下:
xxx@xxxMacBook-Pro ~ % port installed | grep Pangolin
Pangolin @0.8_0 (active)
- 有头文件。但是没有找到编译后的lib文件,很奇怪。
==2025.7.30==
利用源码编译,也出现了问题,不太清楚怎么回事?