
开发工具CLI包管理器任务调度【免费下载链接】pixiPowerful system-level package manager for Linux, macOS and Windows written in Rust – building on top of the Conda ecosystem.项目地址https://gitcode.com/gh_mirrors/pi/pixi点击查看免费下载本教程承接 Building a C Package演示在 Pixi 中改用pixi-build-rattler-build后端通过手写recipe.yaml构建同一个基于 CMake 与 nanobind 的 C 包。读完本文你将掌握如何为 workspace 配置 rattler-build 后端、如何编写一份可运行的 rattler-build recipe、recipe 中各 section 的职责与坑点以及如何用pixi run一步完成「构建 → 安装 → 运行验证」的完整闭环。适用前提pixi-build属于 preview 功能接口在稳定之前可能发生变化用于生产 workspace 时请注意跟踪版本变更见 backend 文档 中的相关说明。同时只要存在对应的语言级后端如pixi-build-cmake官方建议优先使用后端以获得更统一、更流畅的构建体验rattler-build方案适合没有现成后端的语言/构建系统或需要对构建过程有更细粒度控制的场景。为什么需要手写 recipepixi-build-cmake等语言级后端会替你完成大量「隐形工作」探测构建系统、生成编译命令、处理依赖分组与安装位置。但当出现以下情况时rattler-build方案更有价值目标语言或构建系统没有对应的 Pixi 后端你需要精确控制编译选项、构建目录、依赖注入方式等细节项目里已经存在recipe.yaml例如从 conda-forge 迁移希望直接复用。用rattler-build构建同一个包等于把构建过程的隐藏复杂性摊开在你面前让你更深刻地理解后端究竟做了什么。1. 工作区结构沿用前一篇教程 Building a C Package 的目录骨架cpp_math/ ├── CMakeLists.txt ├── pixi.toml ├── recipe.yaml ├── .gitignore └── src └── math.cpp与之前唯一的差异是把构建后端从pixi-build-cmake换成pixi-build-rattler-build并新增recipe.yaml。仓库中完整的可运行示例位于 docs/source_files/pixi_workspaces/pixi_build/advanced_cpp/包含 pixi.toml、recipe.yaml、CMakeLists.txt 与 src/math.cpp以及一份已求解的 pixi.lock。1.1pixi.toml[workspace] channels [https://prefix.dev/conda-forge] platforms [osx-arm64, osx-64, linux-64, win-64] preview [pixi-build] [dependencies] cpp_math { path . } python 3.12.* [tasks] start python -c import cpp_math as b; print(b.add(1, 2)) [package] name cpp_math version 0.1.0 [package.build] backend { name pixi-build-rattler-build, version 0.* }逐项说明preview [pixi-build]开启构建预览特性。pixi-build仍是 preview 标志需要显式 opt-in后续接口可能会变化。[dependencies]中cpp_math { path . }声明本目录是一个源码包source dependencypython 3.12.*是运行时依赖用于之后直接执行绑定模块。[tasks].start定义验证任务——导入构建出的cpp_math模块并调用add(1, 2)。[package.build]指定后端pixi-build-rattler-build版本约束0.*。对比前一篇使用pixi-build-cmake的 cpp/pixi.toml那里还多了[package.build.config] extra-args以及[package.host-dependencies]cmake、nanobind、python因为语言级后端需要你在清单里显式声明这些构建参数与宿主依赖而使用 rattler-build 后端时这些信息全部下沉到recipe.yaml中清单只保留后端选择与运行依赖。1.2src/math.cpp与CMakeLists.txt源码与前一篇完全相同math.cpp用 nanobind 暴露一个add函数#include nanobind/nanobind.h int add(int a, int b) { return a b; } NB_MODULE(cpp_math, m) { m.def(add, add); }CMakeLists.txt的关键点完整内容见 CMakeLists.txtfind_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED)——在 conda 环境中定位 Python 解释器与开发模块通过python -m nanobind --cmake_dir查询 nanobind 的 CMake 配置目录保证链接到同一个Python 环境中的 nanobind用sysconfig.get_path(purelib)查询 site-packages 路径使安装目录与 Python 版本解耦nanobind_add_module(cpp_math src/math.cpp)生成绑定模块install(TARGETS ... LIBRARY DESTINATION ${PYTHON_SITE_PACKAGES} ...)将产物安装进前缀的 site-packages。注意cmake的版本必须与CMakeLists.txt中cmake_minimum_required(VERSION 3.20...3.27)声明的范围匹配这一约束现在要在 recipe 的依赖中落实。2.recipe.yaml构建的全部真相recipe.yaml是rattler-build的构建清单其格式参考rattler-build官方 recipe 文档。本教程使用的完整示例package: name: cpp_math version: 0.1.0 source: path: . use_gitignore: true # (1)! build: number: 0 script: | # (2)! cmake $CMAKE_ARGS \ -GNinja \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX$PREFIX \ -DCMAKE_EXPORT_COMPILE_COMMANDSON \ -DBUILD_SHARED_LIBSON \ -B $SRC_DIR/../build \ -S . cmake --build $SRC_DIR/../build --target install requirements: build: # (3)! - ${{ compiler(cxx) }} - cmake - ninja host: # (4)! - python 3.12.* - nanobind2.1source以当前目录为源码注解 1source.path: .直接把当前目录作为源码目录。这里的.gitignore语义值得注意当源码目录是本地路径时rattler-build只打包被 git 跟踪tracked的文件use_gitignore: true意味着同时遵循.gitignore规则过滤文件如果项目文件已经全部被 git 跟踪可以去掉use_gitignore这一配置。2.2build.script构建脚本注解 2脚本配置并构建一个 CMake 工程核心参数参数作用$CMAKE_ARGSrattler-build 注入的标准 CMake 参数平台相关原样透传给 cmake-GNinja指定 Ninja 生成器-DCMAKE_BUILD_TYPERelease构建类型为 Release-DCMAKE_INSTALL_PREFIX$PREFIX安装前缀指向 rattler-build 提供的$PREFIX环境-DCMAKE_EXPORT_COMPILE_COMMANDSON导出 compile_commands.json便于 IDE/工具消费-DBUILD_SHARED_LIBSON生成共享库-B $SRC_DIR/../build -S .源码目录为当前目录$SRC_DIR构建目录放在其上一级的build随后执行cmake --build $SRC_DIR/../build --target install完成编译与安装。这里出现一个与后端增量编译相关的关键细节pixi-build-rattler-build为每个构建使用干净的根目录以保证与默认假设「根目录是全新」的 recipe 兼容因此如果希望复用之前构建的产物实现增量编译增量缓存必须把构建目录放到根目录之外。本教程把构建目录放在$SRC_DIR/../build源码目录之外正是这个原因——在编写自己的构建脚本时应保持同样的习惯例如先在脚本里cd ../build_dir再开始构建或把../build_dir作为参数传给构建系统。2.3requirements.build构建期依赖注解 3${{ compiler(cxx) }}rattler-build 的 Jinja 函数按平台注入对应的 C 编译器Linux 为 gxx、macOS 为 clangxx 等避免手工硬编码编译器cmake构建工具版本需与CMakeLists.txt的cmake_minimum_required范围一致本示例工作区使用 3.20…3.27ninja配合-GNinja使用的构建系统。2.4requirements.host宿主依赖注解 4python 3.12.*与nanobind放在host分组而不是 build 分组——因为绑定模块在运行时链接的是安装目标环境里的 Python即宿主环境而不是构建环境里的 Python。这是 conda 三通道build / host / run依赖模型的关键区分build 依赖只服务于编译阶段host 依赖决定最终产物链接的对象。3. 验证运行定义好任务后直接执行$ pixi run start 3pixi run start会按需完成「构建绑定模块 → 安装进环境 → 运行start任务」整条链路最终打印3证明add(1, 2)正确返回。仓库的集成测试对这一点做了自动化验证tests/integration_python/pixi_build/test_docs_examples.py 中advanced_cpp工作区被期望输出3\n测试通过pixi run --locked --manifest-path ... start校验每个文档工作区的真实运行结果——也就是说本教程的示例不是纸面配置而是被 CI 持续验证的可运行项目。4. 深入后端实现recipe 是如何被执行的理解「后端做了什么」有助于排查问题与定制行为。pixi-build-rattler-build的入口在 crates/pixi_build_rattler_build/src/main.rs它通过pixi_build_backend::cli::main启动随后由 crates/pixi_build_rattler_build/src/protocol.rs 中的RattlerBuildBackend实现与 Pixi 主进程之间的 JSON-RPC 协议核心能力包括conda_outputs解析 recipe探测其产出output与依赖分组conda_build_v1真正执行构建。从源码protocol.rs可以看到完整流程Recipe 发现优先使用config.recipe指定的路径否则按recipe.yaml、recipe.yml、recipe/recipe.yaml、recipe/recipe.yml顺序查找对应实现见 rattler_build.rs 中的RattlerBuildBackend::new解析与渲染将 recipe 解析为 stage0 结构用RenderConfig含目标平台、构建平台、宿主平台配合变体配置variant渲染出最终 recipe依赖转换把 recipe 的requirements.build/host/run分组转换为 conda 输出依赖并在变体与子包映射中解析${{ compiler(...) }}、pin_subpackage等 Jinja 表达式虚拟包检测自动检测系统虚拟包如__glibc、__osx等可见于示例 pixi.lock 中每个平台段的virtual-packages列表构建执行调用 rattler-build 核心的run_build并设置keep_build truePixi 支持增量构建与environments_externally_managed true环境由 Pixi 预先准备等关键开关产物打包按 recipe 规范生成 conda 包并把可变的路径型源码加入输入 globs用于后续增量触发。4.1 后端的配置项pixi-build-rattler-build支持在[package.build.config]中配置解析逻辑见 crates/pixi_build_rattler_build/src/config.rs配置项类型默认值说明recipeString路径按recipe.yaml、recipe.yml、recipe/recipe.yaml、recipe/recipe.yml顺序查找recipe 文件路径仅允许在根级设置不允许 target 级覆盖experimentalBooleanfalse开启 rattler-build 实验特性如多输出 recipe 的cache:功能仅允许根级设置extra-input-globsArrayString[]额外纳入构建输入文件的 glob 模式叠加到默认输入 globstarget 级配置会整体替换基础配置debug-dirString已弃用后端现在总会把 JSON-RPC 请求/响应日志与生成的中间 recipe 写到工作目录的debug子目录该旧配置被忽略若仍在清单中设置会触发警告例如指定自定义 recipe 路径[package.build.config] recipe ../template/recipe.yaml以及为平台补充输入文件[package.build.config] extra-input-globs [patches/**/*, scripts/*.sh, *.md]4.2 依赖的“单一事实来源”使用该后端时有一条重要约束项目清单pixi.toml中只允许源码依赖workspace 包不允许二进制依赖原因在 backend 文档 中有明确说明recipe.yaml是二进制依赖的唯一事实来源——它已经精确指定了版本、构建变体以及依赖归属 build/host/run 哪个分组若两处都能声明二进制依赖会产生重复与潜在冲突例如 recipe 说python 3.10项目模型却说python 3.9源码依赖workspace 包不同——recipe 只能按名字引用它们却不知道它们在工作区中的路径这个映射关系必须由项目模型提供。对应地[package.run-exports]在该后端下不受支持应改用 recipe 的requirements.run_exports声明pin-compatible、pin-subpackage也不允许出现在清单中需改用 recipe 里的${{ pin_compatible(...) }}、${{ pin_subpackage(...) }}Jinja 语法。这些校验与报错逻辑都在 protocol.rs 的initialize阶段实现。工作区源码依赖则在清单中用[package.build-dependencies]、[package.host-dependencies]或[package.run-dependencies]声明[package.build-dependencies] a { path ../a }4.3 自定义变体注入环境变量配合[workspace.build-variants]凡不是语言类已知键如python、numpy、r等的变体键都会在构建期间自动导出为环境变量用于在不修改 recipe 的前提下向构建脚本传参。例如覆盖 macOS 编译所用的 sysroot[workspace.target.osx.build-variants] CONDA_BUILD_SYSROOT [/Library/Developer/CommandLineTools/SDKs/MacOSX15.4.sdk]也可以在 recipe 模板里通过 Jinja 引用自定义变体build: script: env: MY_FLAG: ${{ my_custom_flag }}[workspace.build-variants] my_custom_flag [enabled]5. 后端能力的单元验证仓库为pixi-build-rattler-build提供了专门的单元测试位于 protocol.rs 的 tests 模块test_conda_outputs对tests/recipe下的每个recipe.yaml跑conda_outputs并做快照对比test_variant_files_are_applied与test_variant_configuration_is_applied验证变体文件与变体配置都能正确作用于 recipe 渲染test_variant_configuration_overrides_variant_files验证显式传入的变体配置优先级高于变体文件config.rs中的test_merge_with_target_config等验证extra_input_globs的 target 级整体替换、experimental/recipe禁止 target 级设置的合并规则。这些测试直接印证了上文提到的配置约束与渲染行为是理解后端边界条件的第一手资料。6. 结论收益与代价通过本教程我们用rattler-buildrecipe.yaml构建了同一个 C 包获得的是对构建过程的完全掌控可以随手把-DCMAKE_BUILD_TYPERelease改成Debug切换构建类型可以删除-GNinja改回默认的Make生成器可以用make -j$(nproc)显式控制并行任务数。付出的代价是失去了语言级后端提供的「重活」依赖分组推断、构建参数预设、安装路径管理等都需要自己在 recipe 中显式声明与维护。因此优先选择存在的后端只有当后端缺失或需要细粒度控制时才考虑rattler-build方案。二者的取舍正是理解 Pixi 构建后端抽象层次的最佳切入点。赞分享开发工具CLI包管理器任务调度【免费下载链接】pixiPowerful system-level package manager for Linux, macOS and Windows written in Rust – building on top of the Conda ecosystem.项目地址https://gitcode.com/gh_mirrors/pi/pixi点击查看免费下载相关推荐使用 Pixi 将 ROS 包构建为 conda 包pixi-build-ros 后端实战指南使用 Pixi 将 ROS 包构建为 conda 包pixi build ros 后端实战指南 本文讲解如何在 Pixi基于 Conda 生态的 Rust开发工具CLI包管理器任务调度Escrcpy 安卓屏幕镜像到电脑完整指南3 分钟 USB 投屏 无线配对步骤教程Escrcpy 安卓屏幕镜像到电脑完整指南3 分钟 USB 投屏 无线配对步骤教程 Escrcpy 是一款基于 scrcpyAndroid 屏幕投射与操开发工具CLI包管理器任务调度pixi-build-mojo 后端详解使用 Pixi 将 Mojo 项目构建为 Conda 包pixi build mojo 后端详解使用 Pixi 将 Mojo 项目构建为 Conda 包 pixi build mojo 是 Pixi 生态中专门为开发工具CLI包管理器任务调度上一篇群晖百度网盘套件终极指南快速搭建私有云存储方案下一篇PCSX2模拟器VC运行时库问题终极解决指南5分钟彻底修复启动崩溃创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考