Skip to content

Commit 5759a20

Browse files
authored
chore: improve pixi config ros (#392)
* chore: improve pixi config ros * chore: error on clippy warnings * fix: config usage * misc: package map test changes * docs: add the mapping logic to the documentation * docs: use simplified version of the mapping structure
1 parent ea0b95d commit 5759a20

File tree

10 files changed

+357
-39
lines changed

10 files changed

+357
-39
lines changed

.github/workflows/python-bindings.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
- name: Run clippy
3939
run: |
4040
cd py-pixi-build-backend
41-
pixi run -e ci lint-rust
41+
pixi run -e ci lint
4242
- name: Run tests
4343
run: |
4444
cd py-pixi-build-backend

backends/pixi-build-ros/pixi.lock

Lines changed: 278 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backends/pixi-build-ros/pixi.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ channels = [
66
platforms = ["osx-arm64", "win-64", "linux-64"]
77
preview = ["pixi-build"]
88

9+
[activation.env]
10+
CARGO_TARGET_DIR = "target/pixi"
11+
12+
[target.linux-64.dependencies]
13+
clang = ">=21.1,<21.2"
14+
mold = ">=2.33.0,<3.0"
15+
patchelf = "==0.18.0"
16+
17+
[target.linux-64.activation]
18+
scripts = ["../../scripts/activate.sh"]
19+
920
[dependencies]
1021
pydantic = ">=2.8.2,<3"
1122
py_rattler = ">=0.15.0,<0.16"

backends/pixi-build-ros/src/pixi_build_ros/config.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ def _parse_package_mappings(
105105
"""Parse additional package mappings if set."""
106106
if input_value is None:
107107
return []
108-
109-
base_path = Path(os.getcwd())
110108
if info.context and "manifest_root" in info.context:
111109
base_path = Path(info.context["manifest_root"])
112110

backends/pixi-build-ros/src/pixi_build_ros/ros_generator.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ def generate_recipe(
141141

142142
def extract_input_globs_from_build(self, config: dict[str, Any], workdir: Path, editable: bool) -> list[str]:
143143
"""Extract input globs for the build."""
144-
ros_config = ROSBackendConfig.model_validate(config)
145-
return get_build_input_globs(ros_config, editable)
144+
return get_build_input_globs(config, editable)
146145

147146
def default_variants(self, host_platform: Platform) -> dict[str, Any]:
148147
"""Get the default variants for the generator."""

backends/pixi-build-ros/src/pixi_build_ros/utils.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pixi_build_backend.types.platform import Platform
1212
from pixi_build_ros.distro import Distro
1313
from rattler import Version
14-
from .config import PackageMapEntry, PackageMappingSource, ROSBackendConfig
14+
from .config import PackageMapEntry, PackageMappingSource
1515

1616

1717
@dataclasses.dataclass
@@ -23,7 +23,7 @@ class PackageNameWithSpec:
2323

2424

2525
# Any in here means ROSBackendConfig
26-
def get_build_input_globs(config: ROSBackendConfig, editable: bool) -> list[str]:
26+
def get_build_input_globs(config: dict[str, Any], editable: bool) -> list[str]:
2727
"""Get build input globs for ROS package."""
2828
base_globs = [
2929
# Source files
@@ -50,8 +50,8 @@ def get_build_input_globs(config: ROSBackendConfig, editable: bool) -> list[str]
5050
python_globs = [] if editable else ["**/*.py", "**/*.pyx"]
5151

5252
all_globs = base_globs + python_globs
53-
if config.extra_input_globs:
54-
all_globs.extend(config.extra_input_globs)
53+
if config.get("extra_input_globs"):
54+
all_globs.extend(config["extra_input_globs"])
5555
return all_globs
5656

5757

@@ -260,7 +260,5 @@ def package_xml_to_conda_requirements(
260260
cond.host = build_requirements
261261
cond.build = build_requirements
262262
cond.run = run_requirements
263-
if "navigator" == pkg.name:
264-
raise Exception(cond)
265263

266264
return cond

backends/pixi-build-ros/tests/data/other_package_map.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
alsa-oss:
22
conda: [other-alsa-oss]
33
new_package:
4-
conda: [new-package]
4+
conda: new-package
55
multi_package:
66
conda: [multi-package-a, multi-package-b]
77
ros_package:

backends/pixi-build-ros/tests/test_package_map.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_package_loading(test_data_dir: Path):
2020
]
2121
)
2222
assert "new_package" in result
23-
assert result["new_package"]["conda"] == ["new-package"], "Should be added"
23+
assert result["new_package"]["conda"] == "new-package", "Should be added"
2424
assert result["alsa-oss"]["conda"] == ["other-alsa-oss"], "Should be overwritten"
2525
assert "robostack" not in result["alsa-oss"], "Should be overwritten due to priority of package maps"
2626
assert "zlib" in result, "Should still be present"
@@ -38,8 +38,8 @@ def test_package_loading_with_inline_mappings(test_data_dir: Path, distro_noetic
3838
"distro": distro_noetic,
3939
"noarch": False,
4040
"extra-package-mappings": [
41-
{"file": str(test_data_dir / "other_package_map.yaml")},
42-
{"mapping": inline_entries},
41+
"other_package_map.yaml",
42+
inline_entries,
4343
robostack_file,
4444
],
4545
}
@@ -112,12 +112,8 @@ def test_generate_recipe_with_inline_package_mappings(package_xmls: Path, test_d
112112
"distro": distro_noetic,
113113
"noarch": False,
114114
"extra-package-mappings": [
115-
{
116-
"mapping": {
117-
"ros_package": {"ros": ["ros-custom2", "ros-custom2-msgs"]},
118-
}
119-
},
120-
{"file": str(test_data_dir / "other_package_map.yaml")},
115+
{"ros_package": {"ros": ["ros-custom2", "ros-custom2-msgs"]}},
116+
str(test_data_dir / "other_package_map.yaml"),
121117
],
122118
}
123119

docs/backends/pixi-build-ros.md

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,24 @@ It would be equivalent to the following `pixi.toml`:
104104
name = "my_ros_package"
105105
version = "1.0.0"
106106
description = "A useful ROS package for navigation"
107-
maintainers = ["John Doe <developer@@example.com"]
107+
maintainers = ["John Doe <developer@example.com"]
108108
homepage = "https://github.com/user/my_ros_package"
109109
repository = "https://github.com/user/my_ros_package"
110110
```
111111

112112
The backend will automatically use the metadata from `package.xml` to generate a complete conda package named `ros-jazzy-my-ros-package`.
113113
The fields in the `pixi.toml` will override the values from `package.xml` if they are explicitly set.
114114

115+
### Automatic Dependency Resolution
116+
117+
Because the definition of a dependency in a `package.xml` file is not similar to a conda package name, the backend needs to map ROS dependencies to conda packages.
118+
119+
- **Known dependencies**: Mapped using the [`robostack.yaml`](https://github.com/prefix-dev/pixi-build-backends/blob/main/backends/pixi-build-ros/robostack.yaml).
120+
- **Custom mappings**: You can provide additional mappings in your `pixi.toml` under [`[package.build.config.extra-package-mappings]`](#extra-package-mappings)
121+
- **Other packages**: Mapped to `ros-<distro>-<package-name>` format.
122+
123+
The `<distro>` part of the package name is automatically generated based on the `distro` configuration.
124+
115125
## Configuration Options
116126

117127
You can customize the ROS backend behavior using the `[package.build.config]` section in your `pixi.toml`. The backend supports the following configuration options:
@@ -151,7 +161,7 @@ env = { ROS_VERSION = "2", AMENT_CMAKE_ENVIRONMENT_HOOKS_ENABLED = "1" }
151161

152162
If specified, internal build state and debug information will be written to this directory. Useful for troubleshooting build issues.
153163

154-
```toml
164+
```toml title="pixi.toml"
155165
[package.build.config]
156166
debug-dir = ".build-debug"
157167
```
@@ -164,7 +174,7 @@ debug-dir = ".build-debug"
164174

165175
Additional glob patterns to include as input files for the build process. These patterns are added to the default input globs that include ROS-specific files.
166176

167-
```toml
177+
```toml title="pixi.toml"
168178
[package.build.config]
169179
extra-input-globs = [
170180
"launch/**/*.py",
@@ -179,6 +189,48 @@ Default input globs include:
179189
- ROS configuration: `package.xml`, `setup.py`, `setup.cfg`, `pyproject.toml`
180190
- Build files: `CMakeLists.txt`
181191

192+
### `extra-package-mappings`
193+
194+
- **Type**: `List<Map<String, Map<String, List<String> | RelativeFileName>>>`
195+
- **Default**: `[]`
196+
197+
Additional dependency mappings to apply to the dependency mapping process.
198+
These mappings are used to extend the usage of the dependencies in the `package.xml` file.
199+
200+
```toml title="pixi.toml"
201+
[package.build.config]
202+
extra-package-mappings = [
203+
{"ros-custom" = { ros = ["ros-custom-msgs"] }},
204+
"mapping.yml"
205+
]
206+
```
207+
208+
Or using a toml array of tables:
209+
210+
```toml title="pixi.toml"
211+
[[package.build.config.extra-package-mappings]]
212+
custom_msgs = { ros = ["custom-messages"] }
213+
```
214+
215+
Or you can use a file directly in the list:
216+
217+
```toml title="pixi.toml"
218+
[package.build.config]
219+
extra-package-mappings = ["mapping.yml"]
220+
```
221+
222+
The mapping file can contain the following:
223+
224+
```yaml title="mapping.yml"
225+
package_name: # The name of the package in the package.xml
226+
conda: conda-package-name # Maps to a conda package, e.g. from `conda-forge`
227+
package_name2: # The name of the package in the package.xml
228+
conda: [package1, package2] # Maps to a list of conda packages
229+
ros_package: # The name of the package in the package.xml
230+
ros: ros_package # Maps to a RoboStack style package name, e.g. `ros-<distro>-ros-package`
231+
```
232+
233+
182234
## Build Process
183235
184236
The ROS backend follows this build process:
@@ -217,20 +269,6 @@ For ROS1 packages using catkin build system:
217269
</export>
218270
```
219271

220-
## Dependency Mapping
221-
222-
The backend automatically maps ROS dependencies to conda packages using the RoboStack project mappings. Dependencies in `package.xml` are converted as follows:
223-
224-
- **ROS packages**: Mapped to `ros-<distro>-<package-name>` format
225-
- **Known dependencies**: Mapped using the `robostack.yaml` configuration file.
226-
- **Unknown dependencies**: Passed through as-is.
227-
228-
Example dependency mapping:
229-
230-
- `ament_cmake``ros-jazzy-ament-cmake`
231-
- `std_msgs``ros-jazzy-std-msgs`
232-
- `opencv2``libopencv` (via `robostack.yaml` mapping)
233-
234272
## Limitations
235273

236274
- **Version constraints**: Dependency versions from `package.xml` are currently ignored

py-pixi-build-backend/pixi.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fmt-rust = "cargo fmt --all"
6868

6969
lint = { depends-on = ["lint-python", "lint-rust"] }
7070
lint-python = "ruff check ."
71-
lint-rust = "cargo clippy --all"
71+
lint-rust = "cargo clippy --all -- -D warnings"
7272

7373
[environments]
7474
# Development environment with all tools (including rust-src for IDE support)

0 commit comments

Comments
 (0)