0
$\begingroup$

Rosanswers logo

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?


Originally posted by ijnek on ROS Answers with karma: 460 on 2022-09-01

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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.


Originally posted by gvdhoorn with karma: 86574 on 2022-09-01

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by gvdhoorn on 2022-09-01:
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.

Comment by tfoote on 2022-09-01:
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.

Comment by ijnek on 2022-09-01:
Thanks @gvdhoorn!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.