# Request for assistance on ament/cargo interop plugin

**URL:** <https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943>\
**Category:** ROS General\
**Tags:** ros2, rust, wg-rust\
**Created:** [April 16, 2021, 12:07pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943 "2021-04-16T12:07:49Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jhdcs](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/jhdcs/32/8074_2.png) [@jhdcs](https://discourse.openrobotics.org/u/jhdcs)\
**Post date:** [April 16, 2021, 12:07pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/1 "2021-04-16T12:07:49Z")

</div>

As part of the effort to get Rust working with ROS 2, I’ve been trying to design a package that will allow things generated by Cargo to get written to the Ament index (see [the ament\_cargo\_plugin project](https://github.com/ros2-rust/ament_cargo_plugin)). Unfortunately, I’m getting stymied by both by not knowing _exactly_ how Ament operates and wants everything organized, and also by Cargo’s opinions on the order everythign should be done during a build process.

From what I understand, Ament wants empty files placed at certain areas of a directory in order to indicate package availability? And I think it wants it done _after_ compilation has been done? This would come into slight conflict with how Cargo build scripts work, since the build script is executed before compilation.

Would any Ament and/oror Cargo/Rust enthusiasts be willing to work with me on this project? I feel like it’s one of the missing components for getting Rust support for Ros 2. Being able to trigger Rust builds via Colcon would be very important, I feel.

And I apologize if this should have been on Ros Answers instead. I put it here so that a discussion could be formed. And so that other people might be able to wander by here and see the nitty-gritty of Ament and Cargo.

---

<div class="post-metadata">

**Author:** ![kristoferB](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/kristoferb/32/2895_2.png) [@kristoferB](https://discourse.openrobotics.org/u/kristoferB)\
**Post date:** [April 16, 2021, 1:05pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/2 "2021-04-16T13:05:06Z")

</div>

Hello,  
We are using rust and ros2 extensively in our research and tools. We have written rust bindings [GitHub - sequenceplanner/r2r: Minimal ROS 2 Rust bindings](https://github.com/sequenceplanner/r2r), that you can use both standalone without colcon (only cargo) or with colcon. We are using cmake to help with the colcon - cargo integration, instead of writing a plugin. You can see an example here: [dorna\_example/src/dorna\_example/control\_box/control\_box\_simulator at master · sequenceplanner/dorna\_example · GitHub](https://github.com/sequenceplanner/dorna_example/tree/master/src/dorna_example/control_box/control_box_simulator).

For us this works great and we are not so dependent on ament/colcon. Hope that helps

---

<div class="post-metadata">

**Author:** ![jhdcs](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/jhdcs/32/8074_2.png) [@jhdcs](https://discourse.openrobotics.org/u/jhdcs)\
**Post date:** [April 16, 2021, 1:09pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/3 "2021-04-16T13:09:51Z")

</div>

From the readme on the `sequenceplanner/r2r` project, it says that this is for " Minimal bindings for ROS2 that do _not_ require hooking in to the ROS2 build infrastructure. If you want a more ROS-oriented approach, see [https://github.com/ros2-rust/ros2\_rust.](https://github.com/ros2-rust/ros2_rust.)" The project that I’m working on above is being developed to help `ros2_rust` interoperate with Colcon in a slightly more “Rust-y” way. But thank you for your suggestion! I’ll still be taking a look at your examples!

---

<div class="post-metadata">

**Author:** ![kristoferB](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/kristoferb/32/2895_2.png) [@kristoferB](https://discourse.openrobotics.org/u/kristoferB)\
**Post date:** [April 16, 2021, 1:12pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/4 "2021-04-16T13:12:16Z")

</div>

We are using ament-cmake to integrate with colcon, like in the example in my reply. We should probably update the readme to higlight that also, since that is how we usually do it now.

---

<div class="post-metadata">

**Author:** ![wjwwood](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/wjwwood/32/13715_2.png) [@wjwwood](https://discourse.openrobotics.org/u/wjwwood)\
**Post date:** [April 16, 2021, 7:31pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/5 "2021-04-16T19:31:57Z")

</div>

> [@jhdcs](#):
>
> From what I understand, Ament wants empty files placed at certain areas of a directory in order to indicate package availability? And I think it wants it done _after_ compilation has been done?

If you want to understand why these files exist, there is a pretty decent design document here:

> <https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md>

I don’t think it necessarily has to be done after compilation, but there might be a period of time after the build script was run, but before the build has been preformed, where the files in the index might point to resources that do not exist yet (maybe executables or libraries).

* * *

I haven’t looked at it at all, but I would have thought the bigger issue was that you typically do not mix cargo with FHS style install targets, but I could be wrong about that. I am no expert with cargo.

---

<div class="post-metadata">

**Author:** ![jhdcs](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/jhdcs/32/8074_2.png) [@jhdcs](https://discourse.openrobotics.org/u/jhdcs)\
**Post date:** [April 19, 2021, 12:14pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/6 "2021-04-19T12:14:37Z")

</div>

> [@wjwwood](#):
>
> I haven’t looked at it at all, but I would have thought the bigger issue was that you typically do not mix cargo with FHS style install targets, but I could be wrong about that. I am no expert with cargo.

Sorry, I’m sort of new to this, but what is an FHS install target?

---

<div class="post-metadata">

**Author:** ![wjwwood](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/wjwwood/32/13715_2.png) [@wjwwood](https://discourse.openrobotics.org/u/wjwwood)\
**Post date:** [April 19, 2021, 4:22pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/7 "2021-04-19T16:22:16Z")

</div>

Sorry, it’s a standard that defines the layout that things like Linux use and where files should go into the layout:

> **[Filesystem Hierarchy Standard](https://en.m.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)**
>
> The Filesystem Hierarchy Standard (FHS) is a reference describing the conventions used for the layout of Unix-like systems. It has been made popular by its use in Linux distributions, but it is used by other Unix-like systems as well. It is maintained by the Linux Foundation. The latest version is 3.0, released on 3 June 2015.
> In the FHS, all files and directories appear under the root directory /, even if they are stored on different physical or virtual devices. Some of these directories only...

It’s what you’re implicitly following most times when you do `make install`.

---

<div class="post-metadata">

**Author:** ![jhdcs](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/jhdcs/32/8074_2.png) [@jhdcs](https://discourse.openrobotics.org/u/jhdcs)\
**Post date:** [April 19, 2021, 5:20pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/8 "2021-04-19T17:20:23Z")

</div>

Ah, okay. It doesn’t _look_ like something Cargo would have a problem with, but I may not be reading into this correctly. Cargo’s structure for packages looks like [this](https://doc.rust-lang.org/cargo/guide/project-layout.html).

The tricky thing I’ve been running into is that Cargo _really_ doesn’t like working outside of the package. Meaning, that if I want to write a file to some external directory, it’s going to be painful to get Cargo to do it. Not necessarily impossible, but painful. However, while digging through the Cargo documentation, I noticed that you can actually put metadata in a table in the manifest. [See here for details](https://doc.rust-lang.org/cargo/reference/manifest.html#the-metadata-table).

Perhaps we can leverage this in some way? Perhaps I’m looking at this incorrectly? Maybe we don’t need Cargo to create the Ament files during/before compilation. Perhaps this plugin should be the thing that _calls Cargo_, and then takes care of the filesystem stuff it doesn’t want to handle? Am I making sense?

---

<div class="post-metadata">

**Author:** ![wjwwood](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/wjwwood/32/13715_2.png) [@wjwwood](https://discourse.openrobotics.org/u/wjwwood)\
**Post date:** [April 20, 2021, 9:40pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/9 "2021-04-20T21:40:42Z")

</div>

> [@jhdcs](#):
>
> Perhaps we can leverage this in some way? Perhaps I’m looking at this incorrectly? Maybe we don’t need Cargo to create the Ament files during/before compilation. Perhaps this plugin should be the thing that _calls Cargo_ , and then takes care of the filesystem stuff it doesn’t want to handle? Am I making sense?

Sounds logical to me, but I don’t have time to investigate further. There is also this:

[https://github.com/colcon/colcon-cargo](https://github.com/colcon/colcon-cargo)

Which sounds kind of like what you described, but I haven’t used it, so I’m not sure.

---

<div class="post-metadata">

**Author:** ![esteve](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/esteve/32/12_2.png) [@esteve](https://discourse.openrobotics.org/u/esteve)\
**Post date:** [April 21, 2021, 1:31pm UTC](https://discourse.openrobotics.org/t/request-for-assistance-on-ament-cargo-interop-plugin/19943/10 "2021-04-21T13:31:07Z")

</div>

> [@jhdcs](#):
>
> Perhaps we can leverage this in some way? Perhaps I’m looking at this incorrectly? Maybe we don’t need Cargo to create the Ament files during/before compilation. Perhaps this plugin should be the thing that _calls Cargo_ , and then takes care of the filesystem stuff it doesn’t want to handle? Am I making sense?

The purpose of `ament_cargo_plugin` is not to call Cargo (that’s what `ament_cargo` does), but get any ROS-specific variables passed by `ament_cargo` to Cargo.

For example, Cargo does not know anything about ROS dependencies that are in `package.xml`, so it needs to be told what those dependencies are, and in that case, it’s `ament_cargo` the one responsible for passing any info from the ROS world to the Cargo world.

The workflow once everything is set up would be:

- `colcon` detects that a package is of type `ament_cargo` (e.g. like `ament_cmake`, `ament_python`, `ament_gradle`, etc.)
- `ament` builds the ROS dependency graph for the current package
- `ament_cargo` passes any ROS metadata to Cargo by setting [`cargo:rustc-env=VAR=VALUE`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-envvarvalue) or [`cargo:rustc-link-search=[KIND=]PATH` ](https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-searchkindpath) to set the search path for dependencies
- `ament_cargo_plugin` is a Rust crate that runs as a Cargo build script and gathers environment variables that were set by `ament_cargo`

Why is all this necessary? Because some ROS packages (namely messages), need to be exported to downstream Rust projects so that the latter can import them. For example, a `ros2-rust` application that uses `std_msgs`, needs to know where the `.rs` files are in the `colcon` workspace, but also how to link against the native libraries built by colcon.

`ament_cargo_plugin` and the `ament_cargo` build type are only needed for `ros2-rust` applications, `rclrs` itself needs to be built by `CMake` (and thus declared as an `ament_cmake` build type), like [`rclpy`](https://github.com/ros2/rclpy/blob/master/rclpy/package.xml#L48), [`rcljava`](https://github.com/ros2-java/ros2_java/blob/master/rcljava/package.xml#L50), etc. to have access to the full `ament` infrastructure.
