跳转至

构建 C++ 包
Building a C++ Package

此示例展示如何使用 CMake 和 pixi-build 构建 C++ 包。要了解更多关于如何使用 Pixi 构建包的信息,请参阅入门指南。您可能还想查看 pixi-build-cmake 后端的文档

我们将首先创建一个使用 nanobind 构建 Python 绑定的工作区(workspace)。 我们也可以使用 Pixi 对其进行测试。稍后我们将此示例与 Python 包结合使用。

Warning

pixi-build 是一个预览功能,在稳定之前可能会发生变化。 请在为您的工作区(workspace)使用它时牢记这一点。

创建新工作区(workspace)#

首先,使用 Pixi 创建一个新工作区(workspace):

pixi init cpp_math

这应该会给您一个基本的 pixi.toml 以开始使用。

现在我们将创建以下源目录结构:

cpp_math/
├── CMakeLists.txt
├── pixi.toml
├── .gitignore
└── src
    └── math.cpp

创建工作区文件#

接下来我们将创建:

  • pixi.toml 文件,用于配置 Pixi
  • CMakeLists.txt 文件,用于构建绑定
  • src/math.cpp 文件,包含绑定代码

pixi.toml 文件#

使用以下 pixi.toml 文件,您可以将鼠标悬停在注释上查看添加每个步骤的原因。

[workspace]
channels = ["https://prefix.dev/conda-forge"]
platforms = ["osx-arm64", "linux-64", "osx-64", "win-64"]
preview = ["pixi-build"]                                  # (1)!

[dependencies] # (2)!
cpp_math = { path = "." }
python = "*"

[tasks]
start = "python -c 'import cpp_math as b; print(b.add(1, 2))'" # (3)!

[package] # (4)!
name = "cpp_math"
version = "0.1.0"

[package.build]
backend = { name = "pixi-build-cmake", version = "0.*" }

[package.build.config]
extra-args = ["-DCMAKE_BUILD_TYPE=Release"] # (9)!

[package.host-dependencies]
cmake = "3.20.*"   # (8)!
nanobind = "2.4.*" # (6)!
python = "3.12.*"  # (7)!
  1. 添加启用 Pixi 构建包的 preview 功能 pixi-build
  2. 这些是工作区(workspace)依赖项。我们添加我们自己的包以及 Python,以便稍后可以运行我们的包
  3. 让我们添加一个将运行我们的测试的任务
  4. 这是我们指定包名称和版本的地方。 此部分表示此 pixi.toml 文件同时定义了工作区(workspace)和包
  5. 我们使用 pixi-build-cmake 作为构建系统,以便获得构建 cmake 包的后端
  6. 我们使用 nanobind 包来构建我们的绑定
  7. 我们需要 python 来构建绑定,因此我们在 python 包上添加一个 host 依赖项
  8. 我们覆盖 cmake 版本以确保它与我们的 CMakeLists.txt 文件匹配
  9. (可选)我们可以向 CMake 调用添加额外参数(例如 -DCMAKE_BUILD_TYPE=Release-DUSE_FOOBAR=True)。这完全取决于特定的工作区(workspace)/CMakeLists.txt 文件

CMakeLists.txt 文件#

接下来让我们添加 CMakeList.txt 文件:

cmake_minimum_required(VERSION 3.20...3.27)
project(cpp_math)

find_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED) # (1)!

execute_process(
  COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
  OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT
) # (2)!

execute_process(
    COMMAND ${Python_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_path('purelib'))"
    OUTPUT_VARIABLE PYTHON_SITE_PACKAGES
    OUTPUT_STRIP_TRAILING_WHITESPACE
) # (3)!

find_package(nanobind CONFIG REQUIRED) # (4)!

nanobind_add_module(${PROJECT_NAME} src/math.cpp) # (5)!

install( # (6)!
    TARGETS ${PROJECT_NAME}
    EXPORT ${PROJECT_NAME}Targets
    LIBRARY DESTINATION ${PYTHON_SITE_PACKAGES}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${BINDIR}
)

  1. 查找 python,这实际上找到任何高于 3.8 的版本,但我们使用 3.8 作为最低版本
  2. 因为我们在 conda 环境中使用 python,我们需要查询 python 解释器来查找 nanobind
  3. 因为我们希望安装目录独立于 python 版本,我们查询 python 的 site-packages 目录
  4. 查找已安装的 nanobind 包
  5. 使用我们的绑定文件作为源文件
  6. 将绑定安装到指定的环境前缀(prefix)

src/math.cpp 文件#

接下来让我们添加 src/math.cpp 文件,这个相当简单:

#include <nanobind/nanobind.h>

int add(int a, int b) { return a + b; } // (1)!

NB_MODULE(cpp_math, m)
{
    m.def("add", &add); // (2)!
}
  1. 我们定义一个用于将两个数字相加的函数
  2. 我们使用 nanobind 包将此函数绑定到 python 模块

测试一切是否正常#

现在我们已经创建了文件,我们可以测试一切是否正常:

$ pixi run start
3

此命令构建绑定,安装它们,然后运行 test 任务。

结论#

在本教程中,我们创建了一个使用 C++ 的 Pixi 包。 它可以按原样使用,上传到 conda 通道(channel)。 在另一个教程中,我们将学习如何将多个 Pixi 包添加到同一工作区(workspace)并让一个 Pixi 包使用另一个。

感谢阅读!快乐编程 🚀

有任何问题?请随时在 X 上联系或分享本教程,加入我们的 Discord发送电子邮件给我们或关注我们的 GitHub