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

Overlaying multiple catkin devel-spaces at the same time

asked 2013-06-10 08:58:10 -0600

updated 2013-06-10 09:00:43 -0600

Is it possible to create a rosbuild or catkin workspace, that overlays two or more independent catkin workspaces at the same time? I would like to keep the workspaces of different, independent projects A and B separated, but there may be a third project C which uses packages from A and B. In other words: Can I source two catkin-generated scripts one after another, so that rospack and cmake's find_package() architecture will find packages from both workspaces A and B?

Here is a simple example setup with empty workspaces, which hopefully clarifies what I mean:

source /opt/ros/groovy/setup.bash

mkdir /tmp/catkin_overlay_test
cd /tmp/catkin_overlay_test

mkdir -p catkin_workspace_a/src     # create empty workspace A
mkdir -p catkin_workspace_b/src     # create empty workspace B

catkin_make -C catkin_workspace_a       # This will create catkin_workspace_a/devel
catkin_make -C catkin_workspace_b       # This will create catkin_workspace_b/devel

Now I would assume that I can use packages (if there were any) from both workspaces after having sourced both setup scripts or by merging them to a rosbuild workspace:

# Alternative 1: Source both setup scripts
source catkin_workspace_a/devel/setup.bash
source catkin_workspace_b/devel/setup.bash

# Alternative 2: Merge A and B in another rosbuild workspace C
rosws init rosbuild_workspace_c
cd rosbuild_workspace_c
rosws merge ../catkin_workspace_a/devel
rosws merge ../catkin_workspace_b/devel
source setup.bash

Both alternatives lead to the same result, namely that the setup script in workspace B overrides the environment variables set by A and packages in A are not visible:

$ env | grep catkin_overlay_test

Is this a bug in catkin or is it simply not possible to build upon multiple devel spaces? I did not try, but I assume there is no difference when using the install spaces instead. Does catkin only support a linear hierarchy of "parent workspaces"?

edit retag flag offensive close merge delete


Why not just order the overlays hierarchically: C overlays B which overlays A?

joq gravatar image joq  ( 2013-06-10 12:09:03 -0600 )edit

B does not depend from A in my case. Of course it is possible to overlay them linearly, but I did not get the point why depending from two workspaces should be bad until now. In any case I would like to avoid having multiple working copies of the same repo in different workspaces.

Johannes Meyer gravatar image Johannes Meyer  ( 2013-06-10 13:06:29 -0600 )edit

@Johannes Meyer, what I do some times is use symbolic links to construct workspaces, so rather than having a working copy of catkin, for instance, in every workspace, I clone it once and symbolically link it into each workspace I am using.

William gravatar image William  ( 2013-06-10 13:08:53 -0600 )edit

@Johannes Meyer, I understand that B does not depend upon A. But, unless it actually redefines packages in A, the linear approach provides an easy way for C to overlay them both without repeating anything.

joq gravatar image joq  ( 2013-06-10 13:14:29 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2013-06-10 10:39:59 -0600

William gravatar image

updated 2013-06-10 10:51:50 -0600

Short answer is "yes", longer answer is "it can be dangerous".

You can call any setup.bash/zsh/sh with the --extend option which will "extend" your current environment. If you do not do this then the setup.bash/zsh/sh will overwrite your current environment to restore the environment which existed when it was generated (the setup.bash/zsh/sh).

So you can do something like this:

  • source /opt/ros/groovy/setup.bash
  • catkin_make # In A_ws
  • # open a new terminal
  • source /opt/ros/groovy/setup.bash
  • catkin_make # In B_ws
  • # open a new terminal
  • source A_ws/devel/setup.bash
  • source B_ws/devel/setup.bash --extend
  • catkin_make # In C_ws (this builds on both A and B and /opt/ros/groovy)

BUT this can be dangerous, read on if you care:

catkin workspaces do not support multiple inheritance of workspaces by default in order to prevent inconsistent build and run environments. For example:

Consider that you have some binary debians installed, and you want to build workspace A, you would do so like this:

  • source /opt/ros/groovy/setup.bash
  • catkin_make # In A_ws

Then you separately build B (in a new terminal):

  • source /opt/ros/groovy/setup.bash
  • catkin_make # In B_ws

Now you have a workspace C which you want to use A and B, so you try:

  • source /opt/ros/groovy/setup.bash
  • source A_ws/devel/setup.bash
  • source B_ws/devel/setup.bash
  • catkin_make # In C_ws

The C_ws will likely fail to build if it relies on packages which only exist in workspace A. Why? because the setup.bash files overwrite each other. In fact when if I build workspace A like this:

  • ./src/catkin/bin/catkin_make # In A_ws (assuming catkin is in that workspace)

And then do this:

  • source /opt/ros/groovy/setup.bash
  • source A_ws/devel/setup.bash

Then you will not find the /opt/ros/groovy/ install space in your environment.

This is the rule you have to remember:

The setup.bash/zsh/sh file generated by catkin has the current environment plus the workspace which was just built.

That means that each time you source a setup.bash file which was generated by catkin it is reconstructing the environment in which it was created. The reason for this is to provide a consistent build and run environment for your packages. It in fact does not make sense to build packages in one environment and run them in another.

If you want to build workspace C on top of A and B, then you should follow this pattern:

  • source /opt/ros/groovy/setup.bash
  • catkin_make # In A_ws
  • # open a new terminal (this isn't required, but it is good to keep a clean environment)
  • source A_ws/devel/setup.bash # This contains /opt/ros/groovy AND A_ws's packages
  • catkin_make # In B_ws
  • # open a new terminal
  • source B_ws/devel/setup.bash # This contains /opt/ros/groovy, A_ws, and B_ws
  • catkin_make # In C_ws

In this way you are always building your current workspace on top of exactly one other workspace ... (more)

edit flag offensive delete link more


Thanks, William, for your detailed response. I think I understand your caveats. On the other side I would assume that most users will not overlay workspaces in order to redefine packages/libs, but just to "use" distinct packages from A and B. In this simple case multiple inheritance would be okay?

Johannes Meyer gravatar image Johannes Meyer  ( 2013-06-10 13:29:44 -0600 )edit

One additional question: Is there a simple way to specify --extend when sourcing the catkin setup script from rosbuild workspaces via rosws merge/setup-file as in the example alternative 2?

Johannes Meyer gravatar image Johannes Meyer  ( 2013-06-10 13:31:17 -0600 )edit

Perhaps. The danger comes in when people intend to just use packages from A and B, but end up causing weird build problems without realizing why. I didn't make the decision to setup workspaces like this, but I understand why it was designed this way.

William gravatar image William  ( 2013-06-10 13:33:34 -0600 )edit

That I do not know. I would assume the answer is no, I would use the sequential chaining as a work around to that, or maybe someone else knows if that is possible.

William gravatar image William  ( 2013-06-10 13:39:41 -0600 )edit

answered 2016-11-16 09:01:01 -0600

peci1 gravatar image

Check out the catkin tools package. It allows you to specify explicit workspaces to extend:

catkin config --extend /opt/ros/indigo
catkin build

makes sure that you always build the workspace with only /opt/ros/indigo as parent workspace (regardless of your current environment).

edit flag offensive delete link more

Question Tools



Asked: 2013-06-10 08:58:10 -0600

Seen: 7,386 times

Last updated: Nov 16 '16