# When is ${catkin_EXPORTED_TARGETS} needed This is basically a follow-up to #q285772 During my use of ROS, I adopted to call the following line on any (C++) target that I try to build: add_dependencies(MYTARGET${${PROJECT_NAME}_EXPORTED_TARGETS}${catkin_EXPORTED_TARGETS})


using ${${PROJECT_NAME}_EXPORTED_TARGETS} only when building msg/srv/actions/dynamic_reconfigure in the package I am workin on, and ${catkin_EXPORTED_TARGETS} always. This is a constant source of error, as well in the above cited question. Thus, I always adviced People to follow the same strategy. In a comment to the above question, @gvdhoorn described the approach to always use ${catkin_EXPORTED_TARGETS} as "cargo-cultish" (nice term :-D)

re: adding catkin_EXPORTED_TARGETS: that's a bit cargo cult-ish. I wouldn't add that unless it's needed.

Checking the documentation (e.g. wiki, catkin docs 1 or catkin docs 2) I'm not quite sure when to use it.

The wiki suggest that:

If you have a target which (even transitively) depends on some other target that needs messages/services/actions to be built, you need to add an explicit dependency on target catkin_EXPORTED_TARGETS, so that they are built in the correct order. This case applies almost always, unless your package really doesn't use any part of ROS. Unfortunately, this dependency cannot be automatically propagated. (some_target is the name of the target set by add_executable()):

add_dependencies(some_target ${catkin_EXPORTED_TARGETS})  This is basically saying: You Need it always (solution 1). The catkin docs rather say, if you Need any msg/srv/action/dynamic_reconfigure from another catkin package (solution 2). Which is the right way to go? I'd be happy for any insights. edit retag close merge delete ## 1 Answer Sort by » oldest newest most voted Afaik, the main difference between catkin_EXPORTED_TARGETS and ${PROJECT_NAME}_EXPORTED_TARGETS is that the former contains the exported targets (ie: message, service, action generation targets, dynamic_reconfig, etc) of all your build dependencies, while the latter contains those targets for just the current package (see ros/catkin/cmake/catkinConfig.cmake).

By making a target depend on catkin_EXPORTED_TARGETS, that specific target will only be built after all its build dependencies have been built (ie: all the exported targets in all the build dependencies).

By adding a dependency on ${PROJECT_NAME}_EXPORTED_TARGETS, a target will be built after the targets in just that set have been built. It's rarely the case that ${catkin_EXPORTED_TARGETS} == ${${PROJECT_NAME}_EXPORTED_TARGETS}, so this can affect the build order significantly. As an extreme example: a node that needs a single header for a custom message that it provides itself, but does have 10 other build dependencies (but none that don't exist already), would be prevented from building until all 10 build dependencies have had all their targets completely built, even though it doesn't actually depend on any of those.

See also the Catkin documentation's section on Extracted CMake API reference - catkin_package(..).

more

Note that this may not actually be such a big problem, after all: waiting for everything to complete >= waiting for just your specific dependencies. But your question was slightly academic, so the answer is as well.

( 2018-03-23 05:16:28 -0500 )edit

Thanks @gvdhoorn for the detailed answer (and I agree that this is rather academic and of less practical relevance). I've been aware about most parts. Basically, catkin_EXPORTED_TARGETS contains ALL targets (i.e. msg/srv/action/dyn_reconf/libraries etc.) right? This could obviously lead ...

( 2018-03-23 07:13:47 -0500 )edit

to a slow-down of the build process. Even though it should be pretty reproducable then.

What I don't get is: How can ${catkin_EXPORTED_TARGETS} ==${${PROJECT_NAME}_EXPORTED_TARGETS} except for the obvious case of both being empty. Doesn't this mean we have some cyclic dependency then? ( 2018-03-23 07:15:30 -0500 )edit And even then, to my understanding, this would only mean that ${${PROJECT_NAME}_EXPORTED_TARGETS} is only a subset of ${catkin_EXPORTED_TARGETS}, and not completely equal. Or am I missing something?

( 2018-03-23 07:16:35 -0500 )edit