Skip to content

Remove references to rclrs not being on crates.io #379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 1 addition & 43 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ mkdir src
git clone https://github.com/ros2-rust/ros2_rust.git src/ros2_rust
```

*Note: Once `rclrs` is published on crates.io, it's not technically needed anymore to clone the `ros2_rust` repo, and this section will be modified to reflect that.*


## Environment setup

Expand Down Expand Up @@ -151,47 +149,7 @@ The plugin to build `cargo` projects with `colcon` currently has the issue that
Rust packages for ROS 2 can also be built with pure `cargo`, and still integrate with ROS 2 tools like `ros2 run`.


### Learning by doing

*Note: The following needs to be adapted once we publish `rclrs` on crates.io.*

If you `cd` into e.g. `rclrs` before ever having built it with `colcon` and try to `cargo build` it, you'll see an error like

```
Updating crates.io index
error: no matching package named `rosidl_runtime_rs` found
location searched: registry `crates-io`
required by package `rclrs v0.2.0 (/workspace/ros2_rust/rclrs)`
```

Why is that? It's because `rclrs/Cargo.toml` contains `rosidl_runtime_rs = "*"` instead of `rosidl_runtime_rs = { path = "../rosidl_runtime_rs" }`, even though the package at that path is the one that is meant. If that's confusing, please read on. The reason is that it is a principle of ROS 2 and `colcon` for packages to reference their dependencies only by their _name_, and not by their path. This allows packages to be moved around freely in a workspace, or replaced by versions installed through `apt`, with no changes to the source code.

Unfortunately, referring to a package only by its name makes `cargo` assume that it should download that package from `crates.io`. `colcon-ros-cargo` works around this with a little hack: At build-time, it resolves these names to concrete paths to the local package, which are then written into `.cargo/config.toml`. The entries in that file override the original locations on `crates.io`, and therefore the _local_ packages will be used instead.

So, the problem above is fixed by doing one initial build of the package, or the whole workspace, with `colcon`. This creates the `.cargo/config.toml` file, and `cargo` will now use it to find `rosidl_runtime_rs`. Of course, if you don't want to install/use `colcon` for some reason, you can also create that file yourself, or replace the name-only dependencies in `rclrs/Cargo.toml` with paths.

Running `cargo build` in `rclrs` will now work, as well as `cargo doc`, `cargo test` and all the other `cargo` commands. Unfortunately, `cargo` may sometimes print messages saying

> warning: Patch `rclrs v0.1.0 (/workspace/install/rclrs/share/rclrs/rust)` was not used in the crate graph.

This can be ignored.

To summarize:

```shell
# Initial build of the package with colcon
# The --lookup-in-workspace flag is recommended for a cargo-based workflow
# Compare .cargo/config.toml with and without it to see its effect
colcon build --packages-up-to examples_rclrs_minimal_pub_sub --lookup-in-workspace
cd src/ros2_rust/examples/minimal_pub_sub
# Run cargo build, or cargo check, cargo doc, etc.
cargo build
```

If you'd like to not have any of that "overriding dependencies through `.cargo/config.toml`", you can do that too of course. You just need to use concrete paths for any dependency that isn't published on `crates.io`, such as message packages. For instance, you might have to write `std_msgs = {path = '/workspace/install/std_msgs/share/std_msgs/rust'}`.


### Integration with ROS 2 tools
## Integration with ROS 2 tools

How can a binary created in Rust be made available to `ros2 run`, `ros2 launch` etc.? And how can other ROS 2 packages use a `cdylib` created in Rust? For that to work, the correct files must be placed at the correct location in the install directory, see [REP 122](https://www.ros.org/reps/rep-0122.html).

Expand Down