项目环境管理的小天使—Pixi
pixi
Pixi 简介
Pixi 是一个基于 Conda 生态的跨平台包管理与开发环境管理工具。
它可以用来管理:
- Python 环境
- C/C++ 编译器
- CMake、Ninja 等构建工具
- Eigen、Assimp、FCL、OpenCV 等 C/C++ 库
- 项目任务,例如构建、测试、运行命令
可以把 Pixi 理解为:
一个面向项目的环境管理工具,类似于 Conda + Makefile + npm scripts 的组合。
Pixi 适合用于:
- C/C++ 项目
- CMake 项目
- Python 项目
- 机器人开发项目
- 科学计算项目
- 多语言混合项目
- 需要可复现环境的项目
Pixi 主要解决的问题
传统安装依赖时,可能会使用:
1
2
sudo apt install cmake ninja-build libeigen3-dev libassimp-dev
pip install numpy
这种方式的问题是:
- 依赖安装到系统目录,容易污染系统环境;
- 不同项目之间的依赖版本可能冲突;
- 换电脑后很难完全复现环境;
- Windows、Linux、macOS 的安装方式不统一;
- 系统仓库中的软件版本可能较旧;
apt、pip、源码编译混合使用时不容易管理。
使用 Pixi 后,可以把依赖统一写入 pixi.toml:
1
2
3
4
5
6
7
8
9
10
11
[workspace]
channels = ["conda-forge"]
platforms = ["linux-64"]
[dependencies]
cmake = ">=3.30"
ninja = "*"
eigen = "*"
assimp = "*"
python = "3.12.*"
numpy = "*"
其他人拿到项目后,只需要执行:
1
pixi install
即可安装一致的开发环境。
Pixi 项目结构
一个典型 Pixi 项目结构如下:
1
2
3
4
5
6
my_project/
├── pixi.toml
├── pixi.lock
├── CMakeLists.txt
├── include/
└── src/
各部分作用如下:
| 文件或目录 | 作用 |
|---|---|
pixi.toml | Pixi 的项目配置文件,用来声明依赖、平台和任务 |
pixi.lock | 锁定实际安装的依赖版本,用于环境复现 |
.pixi/ | Pixi 创建的本地环境目录,一般不提交到 Git |
CMakeLists.txt | CMake 项目的构建配置文件 |
src/ | 源代码目录 |
include/ | 头文件目录 |
推荐提交到 Git:
1
2
pixi.toml
pixi.lock
推荐忽略:
1
2
.pixi/
build/
pixi.toml 配置文件
pixi.toml 是 Pixi 项目的核心配置文件。
它通常包含三部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[workspace]
name = "path-planner"
channels = ["conda-forge"]
platforms = ["linux-64"]
[dependencies]
cmake = ">=3.28"
ninja = "*"
eigen = "*"
assimp = "*"
[tasks]
configure = "cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release"
build = "cmake --build build"
clean = "cmake -E remove_directory build"
主要部分说明:
| 配置项 | 作用 |
|---|---|
[workspace] | 描述项目名称、平台、包源等信息 |
[dependencies] | 声明项目依赖 |
[tasks] | 定义常用命令,例如构建、测试、运行 |
workspace 配置
[workspace] 用来描述整个项目。
示例:
1
2
3
4
5
[workspace]
name = "path-planner"
version = "0.1.0"
channels = ["conda-forge"]
platforms = ["linux-64"]
常见字段:
| 字段 | 作用 |
|---|---|
name | 项目名称 |
version | 项目版本 |
channels | 使用的 Conda 包源 |
platforms | 支持的平台 |
常用平台:
1
2
3
4
5
6
platforms = [
"linux-64",
"win-64",
"osx-64",
"osx-arm64"
]
dependencies 配置
[dependencies] 用来声明项目依赖。
示例:
1
2
3
4
5
6
7
[dependencies]
cmake = ">=3.28"
ninja = "*"
eigen = ">=3.4"
assimp = "*"
python = "3.12.*"
numpy = "*"
版本写法:
| 写法 | 含义 |
|---|---|
cmake = "*" | 任意版本 |
cmake = ">=3.28" | 版本大于等于 3.28 |
python = "3.12.*" | 使用 Python 3.12 系列 |
eigen = ">=3.4" | Eigen 版本大于等于 3.4 |
添加依赖:
1
pixi add cmake ninja eigen
添加指定版本依赖:
1
pixi add "cmake>=3.28"
删除依赖:
1
pixi remove eigen
查看依赖:
1
pixi list
搜索依赖:
1
pixi search fcl
tasks 配置
[tasks] 用来定义项目常用命令。
例如:
1
2
3
4
5
6
[tasks]
configure = "cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release"
build = "cmake --build build --parallel"
test = "ctest --test-dir build --output-on-failure"
run = "./build/path_planner"
clean = "cmake -E remove_directory build"
执行任务:
1
2
3
4
5
pixi run configure
pixi run build
pixi run test
pixi run run
pixi run clean
使用 task 的好处:
- 不需要重复输入很长的命令;
- 构建流程固定,方便复现;
- 团队成员使用同一套命令;
- 适合 CI 自动化构建。
带依赖关系的 task
Pixi 的任务可以设置依赖关系。
示例:
1
2
3
4
5
6
7
8
9
10
[tasks.configure]
cmd = "cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release"
[tasks.build]
cmd = "cmake --build build --parallel"
depends-on = ["configure"]
[tasks.test]
cmd = "ctest --test-dir build --output-on-failure"
depends-on = ["build"]
执行:
1
pixi run test
会自动按照顺序执行:
1
configure → build → test
Pixi 环境目录
Pixi 会在项目目录下创建隔离环境。
默认环境位置一般是:
1
.pixi/envs/default/
这个环境中包含:
- 可执行程序
- 头文件
- 动态库
- 静态库
- Python 包
- CMake 配置文件
例如:
1
2
3
.pixi/envs/default/include/
.pixi/envs/default/lib/
.pixi/envs/default/bin/
当使用下面命令时:
1
pixi run build
Pixi 会自动进入对应环境并执行命令。
pixi.lock 锁文件
pixi.toml 描述依赖要求,例如:
1
cmake = ">=3.28"
pixi.lock 记录最终实际安装的精确版本。
二者区别如下:
| 文件 | 作用 |
|---|---|
pixi.toml | 描述项目需要哪些依赖 |
pixi.lock | 锁定实际解析出来的依赖版本 |
.pixi/ | 实际安装的环境目录 |
通常建议:
- 提交
pixi.toml - 提交
pixi.lock - 不提交
.pixi/
这样其他人可以复现相同环境。
Pixi 常用命令
初始化项目
1
pixi init
安装环境
1
pixi install
添加依赖
1
pixi add cmake ninja eigen
添加指定版本依赖
1
2
pixi add "python=3.12"
pixi add "cmake>=3.28"
添加 PyPI 依赖
1
pixi add --pypi requests
删除依赖
1
pixi remove eigen
查看已安装依赖
1
pixi list
搜索依赖
1
pixi search fcl
执行命令
1
2
pixi run cmake --version
pixi run python --version
执行 task
1
2
pixi run build
pixi run test
进入 Pixi 环境
1
pixi shell
退出环境
1
exit
更新依赖
1
pixi update
pixi install、pixi add 和 pixi update 的区别
| 命令 | 作用 |
|---|---|
pixi add | 添加新的依赖 |
pixi install | 根据现有配置安装环境 |
pixi update | 更新已有依赖 |
示例:
添加依赖:
1
pixi add eigen
根据配置安装环境:
1
pixi install
更新依赖:
1
pixi update
一般使用流程是:
1
2
3
4
pixi init
pixi add cmake ninja eigen
pixi install
pixi run build
Conda 包和 PyPI 包
Pixi 可以同时管理 Conda 包和 PyPI 包。
Conda 包写在:
1
2
3
4
[dependencies]
python = "3.12.*"
numpy = "*"
cmake = "*"
PyPI 包写在:
1
2
[pypi-dependencies]
requests = "*"
添加 Conda 包:
1
pixi add numpy
添加 PyPI 包:
1
pixi add --pypi requests
一般建议:
- NumPy、SciPy、PyTorch、OpenCV 等底层依赖复杂的包,优先使用 Conda 包;
- 纯 Python 包可以使用 PyPI 包。
Pixi 和 Conda 的区别
Pixi 和 Conda 都使用 Conda 包生态,但使用方式不同。
Conda 常见方式:
1
2
conda create -n planner python=3.12 cmake eigen
conda activate planner
Pixi 常见方式:
1
2
3
cd path_planner
pixi install
pixi run build
对比:
| 对比项 | Conda | Pixi |
|---|---|---|
| 环境组织方式 | 命名环境 | 项目环境 |
| 配置文件 | environment.yml | pixi.toml |
| 锁文件 | 通常需要额外工具 | 原生支持 pixi.lock |
| 任务系统 | 无内置任务系统 | 内置 [tasks] |
| 使用方式 | 偏环境管理 | 偏项目管理 |
Pixi 和 apt 的区别
| 对比项 | Pixi | apt |
|---|---|---|
| 安装范围 | 项目级或用户级 | 系统级 |
| 是否需要 sudo | 通常不需要 | 通常需要 |
| 版本隔离 | 支持 | 较弱 |
| 锁文件 | 支持 | 通常没有 |
| 跨平台 | Linux、Windows、macOS | 主要是 Debian/Ubuntu |
| 环境复现 | 强 | 较弱 |
系统驱动、内核模块、USB 规则、系统服务等仍然应该使用系统包管理器。
Pixi 和 pip 的区别
| 对比项 | Pixi | pip |
|---|---|---|
| Python 包 | 支持 | 支持 |
| C/C++ 系统库 | 支持 | 通常不适合 |
| 编译器 | 支持 | 不支持 |
| 多语言项目 | 支持 | 主要面向 Python |
| 锁文件 | 支持 | 需要额外工具 |
| 二进制依赖管理 | 较强 | 取决于 wheel |
Pixi 和 Conan / vcpkg 的关系
Pixi、Conan 和 vcpkg 都可以管理 C/C++ 相关依赖,但定位不同。
Conan / vcpkg 更关注:
- C/C++ 库依赖
- ABI 管理
- 编译选项
- 源码构建
- 与 CMake 集成
Pixi 更关注:
- 整个开发环境
- 编译器
- CMake / Ninja
- Python
- 预编译 C/C++ 库
- 任务运行
可以组合使用:
1
2
Pixi 管理编译器、CMake、Python、Conan
Conan 管理项目中的 C++ 库
示例:
1
2
3
4
5
6
7
8
[dependencies]
cmake = "*"
ninja = "*"
cxx-compiler = "*"
python = "3.12.*"
[pypi-dependencies]
conan = "*"
Pixi 在 CMake 项目中的用法
对于 C++ / CMake 项目,可以使用如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[workspace]
name = "path-planner"
channels = ["conda-forge"]
platforms = ["linux-64"]
[dependencies]
cmake = ">=3.28"
ninja = "*"
cxx-compiler = "*"
eigen = "*"
assimp = "*"
[tasks.configure]
cmd = """
cmake -S . -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
"""
[tasks.build]
cmd = "cmake --build build --parallel"
depends-on = ["configure"]
[tasks.clean]
cmd = "cmake -E remove_directory build"
使用流程:
1
2
pixi install
pixi run build
CMake 中查找 Pixi 安装的库
在 CMakeLists.txt 中可以正常使用:
1
2
find_package(Eigen3 REQUIRED)
find_package(assimp REQUIRED)
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cmake_minimum_required(VERSION 3.20)
project(path_planner LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Eigen3 REQUIRED)
find_package(assimp REQUIRED)
add_executable(path_planner
src/main.cpp
)
target_link_libraries(path_planner
PRIVATE
Eigen3::Eigen
assimp::assimp
)
如果 CMake 找不到库,可以查看 Pixi 环境路径:
1
pixi run echo $CONDA_PREFIX
查找 CMake 配置文件:
1
pixi run find "$CONDA_PREFIX" -iname "*config.cmake"
查找 FCL 配置文件:
1
pixi run find "$CONDA_PREFIX" -iname "*fcl*config*.cmake"
C/C++ 编译器配置
跨平台项目推荐使用:
1
2
3
[dependencies]
c-compiler = "*"
cxx-compiler = "*"
如果明确要求 Linux 下的 GCC,可以使用:
1
2
3
[dependencies]
gcc_linux-64 = "13.*"
gxx_linux-64 = "13.*"
一般建议:
| 场景 | 推荐写法 |
|---|---|
| 跨平台 C/C++ 项目 | c-compiler、cxx-compiler |
| 明确要求 GCC 版本 | gcc_linux-64、gxx_linux-64 |
| 明确要求 Clang | 使用对应的 clang 包 |
FCL 项目示例
如果项目使用 CMake、Eigen、Assimp 和 FCL,可以尝试如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[workspace]
name = "path-planner"
channels = ["conda-forge"]
platforms = ["linux-64"]
[dependencies]
cmake = ">=3.28"
ninja = "*"
cxx-compiler = "*"
eigen = ">=3.4"
assimp = "*"
fcl = "*"
[tasks.configure]
cmd = """
cmake -S . -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
"""
[tasks.build]
cmd = "cmake --build build --parallel"
depends-on = ["configure"]
[tasks.run]
cmd = "./build/path_planner"
depends-on = ["build"]
[tasks.clean]
cmd = "cmake -E remove_directory build"
使用:
1
2
3
pixi install
pixi run build
pixi run run
CMake 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cmake_minimum_required(VERSION 3.20)
project(path_planner LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Eigen3 REQUIRED)
find_package(assimp REQUIRED)
find_package(fcl REQUIRED)
add_executable(path_planner
src/main.cpp
)
target_link_libraries(path_planner
PRIVATE
Eigen3::Eigen
assimp::assimp
fcl
)
FCL 的 CMake target 名称可能因包而异,可能是:
1
fcl
也可能是:
1
FCL::fcl
可以通过下面命令检查:
1
pixi run find "$CONDA_PREFIX" -iname "*fcl*config*.cmake"
Pixi 的优点
Pixi 的主要优点:
- 项目环境隔离,不容易污染系统;
- 支持锁文件,方便环境复现;
- 不只管理 Python,也能管理 C/C++ 工具和库;
- 通常不需要 sudo;
- 支持 Linux、Windows、macOS;
- 内置 task 系统,方便统一构建命令;
- 适合团队协作和 CI 构建。
Pixi 的局限
Pixi 的局限:
- Conda 仓库中不一定有所有库;
- 某些库的包名、CMake 名称和系统包名可能不同;
- 预编译包不一定满足特殊编译需求;
- 不能替代系统包管理器;
- 对嵌入式交叉编译、内核驱动等场景不一定合适。
例如 Eigen 的名称可能不同:
1
2
3
apt: libeigen3-dev
conda-forge: eigen
CMake: Eigen3
推荐使用场景
Pixi 适合:
- C++ 与 Python 混合项目
- CMake 项目
- 机器人路径规划项目
- 科学计算项目
- 需要复现环境的项目
- 多平台开发项目
- 团队协作项目
- CI 自动化构建
Pixi 不一定适合:
- 只安装一个简单系统软件
- 对编译参数有复杂定制的项目
- 所需依赖不在 Conda 生态中
- 嵌入式交叉编译项目
- 内核模块或驱动开发
总结
Pixi 是一个面向项目的开发环境管理工具。
它的核心作用是:
1
依赖隔离 + 环境复现 + 跨平台 + 任务管理
对于 CMake / C++ / Python 混合项目,Pixi 可以管理:
1
编译器、CMake、Ninja、Eigen、Assimp、FCL、Python、NumPy
典型使用流程:
1
2
3
pixi init
pixi add cmake ninja cxx-compiler eigen assimp
pixi run build
推荐提交:
1
2
pixi.toml
pixi.lock
推荐忽略:
1
2
.pixi/
build/
其他人克隆项目后,只需要执行:
1
2
pixi install
pixi run build
即可复现环境并构建项目。