ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Listing dependencies in package.xml that are also dependency of dependency

asked 2022-09-01 07:26:14 -0500

ijnek gravatar image

I'm interested in hearing about best practice of listing a dependency in package.xml that is already a dependency of another dependency.

Let's say I have two packages:

  • foo_interfaces - with a dependency on builtin_interfaces
  • foo_core - with a dependency on foo_interfaces

In foo_core, I fill out a message defined in foo_interfaces, and in doing so, I import builtin_interfaces. So, a file in foo_core would look like this for example:

import builtin_interfaces
import foo_interfaces

bar = foo_interfaces.msg.Bar()
bar.header.stamp = builtin_interfaces.msg.Time()

In this case, builtin_interfaces is a dependency of foo_interfaces, so it should be available as long as foo_core depends on foo_interfaces. So, having builtin_interfaces in foo_core's package.xml would be redundant.

Is it better practice to add builtin_interfaces to foo_core's package.xml, and why (or not) would that be better?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2022-09-01 10:06:25 -0500

gvdhoorn gravatar image

updated 2022-09-01 10:14:43 -0500

You are basically asking how to deal with transitive dependencies (or whether you could benefit from them in any way), and this is not necessarily specific to ROS, nor to any programming language.

(I'm not saying this because I believe your question is off-topic for this website. I'm just trying to clarify what I'm writing below is not specific to ROS, how it manages dependencies or which particular programming language is being used)

Is it better practice to add builtin_interfaces to foo_core's package.xml, and why (or not) would that be better?

In almost all cases I've heard and seen this discussed, the rule is: explicitly declare a dependency on everything you directly #include, import or whatever the specific idiom in the language you're using is.

Rationale: if, in your example, foo_interfaces ever removes or changes its dependency on builtin_interfaces, and foo_core doesn't declare that dependency itself, foo_core now has a problem, as there's nothing bringing in that dependency any more.

A different way of thinking about this is: it is foo_core's responsibility to make sure it has access to its dependencies. It's not foo_interfaces' responsibility to keep track of those. foo_interfaces' responsibility is to keep track of its own dependencies.

Yet another way: the fact foo_interfaces depends on builtin_interfaces is an implementation detail of foo_interfaces, and not something you should make assumptions about in foo_core. If you do, you're increasing coupling between these packages unnecessarily, which not a-good-thing to do in a component based system.

edit flag offensive delete link more


There is some nuance to be added which comes down to which parts of foo_interfaces could be considered part of its public API when it comes to dependencies and changing them, but in general I believe what I write here also holds for messages, services and actions.

gvdhoorn gravatar image gvdhoorn  ( 2022-09-01 11:02:22 -0500 )edit

Yeah there's always nuances, but the primary thing that should drive the logic is that if no one else depends on it and your code will break you should have a dependency on it.

tfoote gravatar image tfoote  ( 2022-09-01 13:32:10 -0500 )edit

Thanks @gvdhoorn!

ijnek gravatar image ijnek  ( 2022-09-01 18:02:55 -0500 )edit

Question Tools

1 follower


Asked: 2022-09-01 07:26:14 -0500

Seen: 144 times

Last updated: Sep 01 '22