Skip to content

Commit 556fce3

Browse files
feat: add tutorial for pixi build rattler build (#3330)
Co-authored-by: Hofer-Julian <30049909+Hofer-Julian@users.noreply.github.com> Co-authored-by: Julian Hofer <julianhofer@gnome.org>
1 parent b3411b3 commit 556fce3

13 files changed

+1061
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
source: crates/pixi_build_type_conversions/src/project_model.rs
3+
expression: project_model
4+
---
5+
{
6+
"version": "1",
7+
"data": {
8+
"name": "python_bindings",
9+
"version": "0.1.0",
10+
"description": null,
11+
"authors": null,
12+
"license": null,
13+
"licenseFile": null,
14+
"readme": null,
15+
"homepage": null,
16+
"repository": null,
17+
"documentation": null,
18+
"targets": {
19+
"defaultTarget": {
20+
"hostDependencies": {},
21+
"buildDependencies": {},
22+
"runDependencies": {}
23+
},
24+
"targets": {}
25+
}
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
source: crates/pixi_build_type_conversions/src/project_model.rs
3+
expression: project_model
4+
---
5+
{
6+
"version": "1",
7+
"data": {
8+
"name": "rich_example",
9+
"version": "0.1.0",
10+
"description": null,
11+
"authors": null,
12+
"license": null,
13+
"licenseFile": null,
14+
"readme": null,
15+
"homepage": null,
16+
"repository": null,
17+
"documentation": null,
18+
"targets": {
19+
"defaultTarget": {
20+
"hostDependencies": {},
21+
"buildDependencies": {},
22+
"runDependencies": {}
23+
},
24+
"targets": {}
25+
}
26+
}
27+
}

docs/build/advanced_cpp.md

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Tutorial: Building a C++ Package with rattler-build and recipe.yaml
2+
3+
4+
In this tutorial, we will show you how to build the same C++ package as from [Building a C++ Package](cpp.md) tutorial using [`rattler-build`](https://rattler.build).
5+
In this tutorial we assume that you've read the [Building a C++ Package](cpp.md) tutorial.
6+
If you haven't read it yet, we recommend you to do so before continuing.
7+
The project structure and the source code will be the same as in the previous tutorial, so we may skip explicit explanations of some parts.
8+
9+
This approach may be useful when no build backend for your language or build system exists.
10+
Another reason to use it is when you would like to have more control over the build process.
11+
At the time of writing this tutorial, `pixi-build-cmake` will always build in `Release` mode.
12+
By using `rattler-build`, you have full control of the build process and can build your package in `Debug` mode instead.
13+
14+
15+
To illustrate this, we will use the same C++ package as in the previous tutorial, but this time we will use `rattler-build` to build it.
16+
This will unveil the hidden complexity of the build process, and give you a better grasp of how backends work.
17+
18+
!!! warning
19+
`pixi-build` is a preview feature, and will change until it is stabilized.
20+
Please keep that in mind when you use it for your workspaces.
21+
22+
!!! hint
23+
Prefer using a backend if it exists. This will give you a more streamlined and unified build experience.
24+
25+
## Workspace structure
26+
27+
To get started, please recreate the structure of the workspace from the previous tutorial [Building a C++ Package](cpp.md).
28+
29+
30+
### The `pixi.toml` file
31+
32+
We are now using the `pixi-build-rattler-build` backend instead of the `pixi-build-cmake` backend.
33+
34+
```toml hl_lines="20-21"
35+
--8<-- "docs/source_files/pixi_workspaces/pixi_build/advanced_cpp/pixi.toml"
36+
```
37+
38+
## The `recipe.yaml` file
39+
40+
Next lets add the `recipe.yaml` file that describes how `rattler-build` builds the package.
41+
You can find the reference on the `rattler-build` documentation [web page](https://rattler.build/latest/reference/recipe_file/).
42+
43+
44+
```yaml
45+
--8<-- "docs/source_files/pixi_workspaces/pixi_build/advanced_cpp/recipe.yaml"
46+
```
47+
48+
1. Because we are specifying the current directory as the source directory, `rattler-build` may skip files that are not tracked by git. If your files are already tracked by git, you can remove this configuration.
49+
2. This build script configures and builds a `CMake` project using the `Ninja` build system. It sets various options such as the build type to `Release`, the installation prefix to `$PREFIX`, and enables shared libraries and compile commands export. The script then builds the project in the specified build directory `($SRC_DIR/../build)` and installs the built files to the installation directory.
50+
3. For build dependencies we need compilers and the build systems `cmake` and `ninja`. Make sure that `cmake` version matches the one from `CMakeLists.txt` file.
51+
4. For `python` bindings, we need `nanobind` and `python` itself. They are set in `host` dependencies section as we link them to the `python` where the bindings will be installed, not built.
52+
53+
## Testing if everything works
54+
55+
Now that we've defined a `pixi` task which allows us to check that our package can properly add `1` and `2`:
56+
57+
```toml
58+
[tasks]
59+
start = "python -c 'import python_bindings as b; print(b.add(1, 2))'"
60+
```
61+
62+
Executing the tasks works as expected
63+
64+
```bash
65+
$ pixi run start
66+
3
67+
```
68+
69+
This command builds the bindings, installs them and then runs the `test` task.
70+
71+
## Conclusion
72+
73+
In this tutorial, we created a Pixi package using `rattler-build` and a `recipe.yaml` file. Using this approach, we had more control over the build process. For example, we could changed the build type to `Debug` using `CMAKE_BUILD_TYPE`, use `Make` instead of `Ninja` by removing the `-GNinja` configuration.
74+
Or we could use `make -j$(nproc)` to specify the number of jobs to run in parallel when building the package.
75+
76+
At the same time, we lost all the benefit of heavy lifting that is done by language build backend.
77+
78+
Thanks for reading! Happy Coding 🚀
79+
80+
Any questions? Feel free to reach out or share this tutorial on [X](https://twitter.com/prefix_dev), [join our Discord](https://discord.gg/kKV8ZxyzY4), [e-mail](mailto:hi@prefix.dev) us or follow our [GitHub](https://github.com/prefix-dev).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SCM syntax highlighting & preventing 3-way merges
2+
pixi.lock merge=binary linguist-language=YAML linguist-generated=true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# pixi environments
3+
.pixi
4+
*.egg-info
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
cmake_minimum_required(VERSION 3.20...3.27)
2+
project(python_bindings)
3+
4+
find_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED) # (1)!
5+
6+
execute_process(
7+
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
8+
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT
9+
) # (2)!
10+
11+
execute_process(
12+
COMMAND ${Python_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_path('purelib'))"
13+
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES
14+
OUTPUT_STRIP_TRAILING_WHITESPACE
15+
) # (3)!
16+
17+
find_package(nanobind CONFIG REQUIRED) # (4)!
18+
19+
nanobind_add_module(${PROJECT_NAME} src/bindings.cpp) # (5)!
20+
21+
install( # (6)!
22+
TARGETS ${PROJECT_NAME}
23+
EXPORT ${PROJECT_NAME}Targets
24+
LIBRARY DESTINATION ${PYTHON_SITE_PACKAGES}
25+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
26+
RUNTIME DESTINATION ${BINDIR}
27+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"conda_pkg_format_version":2}

0 commit comments

Comments
 (0)