# Adjust RPATH for cross-compilation target

Hi all,

right now I'm successfully using eros to build ROS nodes for my gumstix hardware, but there is only one minor issue:

ROS host installation is located here: /home/phil/ros/cturtle

ROS target installation is located here: /opt/ros/cturtle

Now I've got the problem of not finding ROS related dynamic libraries when executing the nodes on my target. All RPATHs in my binaries refer to /home/phil/ros/cturtle instead of /opt/ros/cturtle. Is there any convenient way of setting a different RPATH prefix during cross-compilation instead of adding all local lib/ directories within the ROS tree on the target system? I'm not too familiar with the ROS build system nor am I with cmake in general. That's the reason why I bother to ask here ;)

Any feedback is much appreciated!

Cheers Phil

edit retag close merge delete

Sort by » oldest newest most voted

Right now I'm just replacing the RPATH prefixes in the freshly created binaries by this little script which is part of the deployment. call it this way

> script /path/to/ros_node1 /path/to/ros_node2

and your executables will be replaced with new rpaths.

SEARCH_PATH="/home/phil/ros/cturtle"
REPLACE_PATH="/opt/ros/cturtle"

which chrpath > /dev/null
if [ $? != 0 ]; then echo "Couldn't find the program 'chrpath'. Maybe it's existant but not found in the PATH searchpath" echo "exit..." exit 1 fi if [$# -lt 1 ]; then
echo "Please specifiy a list of files which you want to work on..."
echo "e.g: \$replace_rpath program1 program2" exit 1 fi for FILE in$@ ; do
echo "-- Preparing $FILE" if [ ! -e "$FILE" ] || [ ! -f "$FILE" ]; then echo "'$FILE' is either not a file or doesn't exist!"
else
chrpath -l $FILE | sed -e "s+.*=++g" -e "s+${SEARCH_PATH}+${REPLACE_PATH}+g" | xargs -I {} chrpath -r {}$FILE
if [ \$? != 0 ]; then
echo "chrpath failed!"
fi
fi
done


Not nice, but at least a starting point. I'm still looking forward for other - not so brutal - solutions.

more

I had a similar script a while ago. Could extend this with a python tree crawling script (slow). Or drop in a replacement for some of the rosbuild cmake to fix paths (faster).
( 2011-04-18 11:54:12 -0600 )edit
1
Ultimately both of those still feel hackish. I do think the use case scenario (cross-compiling) is sufficient to propose a small working environment change to your colleagues. Long term I find its always easier and far more comfortable to find ways to work with a system rather than fight it.
( 2011-04-18 11:55:24 -0600 )edit
I fully agree on calling this approach "hackish" ;) however there is no nice and sophisticated solution in my mind, yet. you mentioned that troy is working on rosbuild2. i'm looking forward for seeing a more generic approach to build software with ROS where cross compilation and target deployment is only a usecase not a special treatment.
( 2011-04-18 22:20:41 -0600 )edit
FWIW, we do something similar when building binary debs. The script that does the RPATH-fixing is: https://code.ros.org/svn/ros/stacks/ros_release/trunk/rosdeb/resources/source_deb/fixrpath.py. It's prety much a Python version of your bash script.
( 2011-04-20 03:36:47 -0600 )edit

I initially tried rejigging rpaths and then installing everything in the standard *nix directories, but ended up finding it easier (and with no real disadvantage except from my initial preconceptions) to just install a trimmed tree on the robot. Troy is working on rosbuild2 at the moment, so this will hopefully make this problem go away as rosbuild2 has a proper install step.

Only thing to make sure of when installing trees is those rpaths - need them the same on the robot as on the pc. I typically rosinstall a tree for each robot on my pc (and one or two for native pc development/testing). This is especially important if you're configuring the global rostoolchain.cmake (toolchains) or rosconfig.cmake (cpu flags). e.g. my pc is something like

/opt/diamondback       : my test/dev tree
/opt/waykook           : robot
/opt/skelly            : robot
/opt/iclebo            : robot
/opt/cafero            : robot
/opt/winmaster         : ros for windoze (mingw)
/opt/building_manager  : app dev environment


Just tarball the tree or synchronise via unison or rsync with your robot. Whatever method, just make sure to set alot of appropriate excludes/ignores (see that link for an example of some of the things you can drop safely, its by no means exhaustive). Even when size isn't important, it will speed up transfer.

If you haven't set aside space for this to work on /opt, then you can symbolically link to somewhere else and all the rpaths will be oblivious of the fact that you're using a symbolic link rather than a real dir, e.g.

mkdir /home/phil/ros/cturtle
sudo ln -s /home/phil/ros/cturtle /opt/ros/cturtle
rosinstall /opt/ros/cturtle myinstaller.rosinstall

more

Unfortunately this approach doesn't work very well as we deploy software in the same /opt/ros/cturtle folders on different architectures (x86/arm) whereas /opt/ros/cturtle is also used on the working machines for a global x86 ROS installation. Right now I discovered the handy tool "patchelf"....
( 2011-04-15 01:48:30 -0600 )edit
You could just as easily have two trees still, and use a symbolic link in /opt/ros/cturtle with a script to switch between the two (aka update-alternatives in ubuntu). Nonetheless, curious as to how you will fare with patchelf, let me know if you get a working solution and we'll post it on eros.
( 2011-04-16 14:47:07 -0600 )edit
The problem is that /opt/ros/cturtle on my working machine is a global network-wide installation which is used by many other colleagues. Although I'm the maintainer with write-permissions within /opt/ros I don't want to make any changes to this directory at all. See my current approach in the answer below
( 2011-04-17 21:17:18 -0600 )edit