[prev in list] [next in list] [prev in thread] [next in thread] 

List:       orocos-users
Subject:    [Orocos-users] rosmake linker order
From:       peter () thesourceworks ! com (Peter Soetens)
Date:       2012-02-15 20:25:11
Message-ID: CAMYDobUS3y422xUnDONYZurdu34e9ss307ipQAm54NNgcXizsA () mail ! gmail ! com
[Download RAW message or body]

Hi Dustin,

On Fri, Feb 10, 2012 at 5:07 PM, Gooding, Dustin R. (JSC-ER411)
<dustin.r.gooding at nasa.gov> wrote:
> Hey folks,
> 
> We've run into a very interesting problem. ?First, where it makes sense,
> we've decided to make "libraries" of code that are independently testable,
> and then components that link against those libraries for functionality
> (either via an isA or hasA relationship to library classes). ?In one case,
> our library (cleverly named "Robot") requires KDL, so the library's CMake
> file goes off and finds the orocos_kdl component and builds against that.
> 
> Here's how we do that, in case anyone's curious. ?Yes, it's hackish, but it
> seems to work.
> 
> /**
> # Begin KDL Setup
> find_program(ROSPACK_CMD NAMES rospack PATHS /opt/ros/electric/ros/bin)
> execute_process(COMMAND ${ROSPACK_CMD} find orocos_kdl RESULT_VARIABLE
> KDL_FOUND_ERROR OUTPUT_VARIABLE KDL_PATH_UGLY ERROR_VARIABLE
> KDL_ERROR_STRING)
> if (NOT KDL_FOUND_ERROR)
> string(STRIP ${KDL_PATH_UGLY} KDL_PATH)
> message(STATUS "KDL Component Found.")
> message(STATUS "? Path:? ? ? ${KDL_PATH}")
> set(KDL_INCLUDE_DIRS ${KDL_PATH}/install_dir/include)
> include_directories(${KDL_INCLUDE_DIRS})
> message(STATUS "? Include: ? ${KDL_INCLUDE_DIRS}")
> set(KDL_LIBRARY_DIRS ${KDL_PATH}/install_dir/lib)
> link_directories(${KDL_LIBRARY_DIRS})
> message(STATUS "? Lib: ? ? ? ${KDL_LIBRARY_DIRS}")
> find_library(KDL_LIBRARY NAMES orocos-kdl HINTS ${KDL_LIBRARY_DIRS})
> if (NOT KDL_LIBRARY MATCHES "KDL_LIBRARY-NOTFOUND")
> set(KDL_LIBRARIES ${KDL_LIBRARY})
> message(STATUS "? Libraries: ${KDL_LIBRARIES}")
> else (NOT KDL_LIBRARY MATCHES "KDL_LIBRARY-NOTFOUND")
> message("KDL Library Not Found.")
> message("? Something's wrong that defies explanation.")
> endif (NOT KDL_LIBRARY MATCHES "KDL_LIBRARY-NOTFOUND")
> 
> set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${KDL_PATH}/config)
> find_package(Eigen3)
> include_directories(${EIGEN3_INCLUDE_DIR})
> message(STATUS "? Eigen: ${EIGEN3_INCLUDE_DIR}")
> else (NOT KDL_FOUND_ERROR)
> message("KDL Not Found.")
> message("? Error: ${KDL_FOUND_ERROR}")
> message("? Output: ${KDL_ERROR_STRING}")
> message("? Please add /trunk/ThirdParty/components to your ROS_PACKAGE_PATH,
> and rosmake the orocos_kinematics_dynamics component.")
> endif (NOT KDL_FOUND_ERROR)
> # End KDL Setup
> **/

But are you linking Robot with kdl  ??

> 
> We can build, link and test the library code without any problems. ?Now,
> since our underlying library requires KDL, therefore so does our component
> (named "RobotKDState"). ?For the component, though, we're using ROS's
> component dependency mechanism:
> 
> /**
> <depend package="orocos_kdl">
> **/
> 
> And in the component's CMake file, we find where the library is and add it
> to the target_link_libraries() command.
> 
> /**
> orocos_component(RobotKDState?RobotKDState-component.hpp
> RobotKDState-component.cpp)
> target_link_libraries(RobotKDState Robot ${TINYXML_LIBRARY})
> **/
> 
> When we go to build the component, though, it fails. ?The error lead us to
> believe it was due to a linking issue. ?So, running rosmake again with
> verbosity enabled, we see that this is the linking command being used:
> 
> /**
> /usr/bin/c++? -fPIC -O2 -g
> -Wl,-rpath,/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dynamics/orocos_kdl/install_dir/lib
>                 
> -Wl,-rpath,/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dynamics/orocos_kdl/install_dir/lib
>                 
> -pthread -Wl,-z,defs?? -shared -Wl,-soname,libRobotKDState-gnulinux.so -o
> ../lib/orocos/gnulinux/libRobotKDState-gnulinux.so
> CMakeFiles/RobotKDState.dir/RobotKDState-component.cpp.o
> -L/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dynamics/orocos_kdl/install_dir/lib
>                 
> -L/home/user/projects/r2/trunk/code/components/RobotKDState/../../../install/lib
> -L/opt/ros/electric/stacks/orocos_toolchain/rtt/install/lib -L/usr/local/lib
> -lorocos-kdl
> /opt/ros/electric/stacks/orocos_toolchain/rtt/install/lib/liborocos-rtt-gnulinux.so.2.5.0?-lRobot?/usr/local/lib/libtinyxml.a
>                 
> -lboost_filesystem-mt -lboost_system-mt -lboost_serialization-mt -lpthread
> -lrt -ldl
> -Wl,-rpath,/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dyna \
> mics/orocos_kdl/install_dir/lib:/home/user/projects/r2/trunk/code/components/RobotKD \
> State/../../../install/lib:/opt/ros/electric/stacks/orocos_toolchain/rtt/install/lib:::::::
>                 
> **/
> 
> Notice how -lorocos_kdl comes before -lRobot? ? I'm assuming rosmake is
> putting the manifest.xml dependencies before the CMake dependencies.
> ?Trouble is, this fails?.. ?So we tried a different order by hand:
> 
> /**
> /usr/bin/c++? -fPIC -O2 -g
> -Wl,-rpath,/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dynamics/orocos_kdl/install_dir/lib
>                 
> -Wl,-rpath,/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dynamics/orocos_kdl/install_dir/lib
>                 
> -pthread -Wl,-z,defs?? -shared -Wl,-soname,libRobotKDState-gnulinux.so -o
> ../lib/orocos/gnulinux/libRobotKDState-gnulinux.so
> CMakeFiles/RobotKDState.dir/RobotKDState-component.cpp.o
> -L/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dynamics/orocos_kdl/install_dir/lib
>                 
> -L/home/user/projects/r2/trunk/code/components/RobotKDState/../../../install/lib
> -L/opt/ros/electric/stacks/orocos_toolchain/rtt/install/lib -L/usr/local/lib
> -lRobot -lorocos-kdl
> /opt/ros/electric/stacks/orocos_toolchain/rtt/install/lib/liborocos-rtt-gnulinux.so.2.5.0
>                 
> /usr/local/lib/libtinyxml.a -lboost_filesystem-mt -lboost_system-mt
> -lboost_serialization-mt -lpthread -lrt -ldl
> -Wl,-rpath,/home/user/projects/r2/trunk/ThirdParty/components/orocos_kinematics_dyna \
> mics/orocos_kdl/install_dir/lib:/home/user/projects/r2/trunk/code/components/RobotKD \
> State/../../../install/lib:/opt/ros/electric/stacks/orocos_toolchain/rtt/install/lib:::::::
>                 
> **/
> 
> This time, -lRobot is before -lorocos_kdl? ?and this command links without
> any trouble. ? Unfortunately, I'm not aware of any way to define which
> specific order libraries are linked using either rosmake or CMake.
> 
> So, my question is either a) what are we doing wrong with regard to linking
> against KDL, or b) what are we doing wrong with regard to using libraries?

My guess is that the order is not the real problem, but that Robot
itself is not linked with orocos_kdl, hence leading to undefined
symbols later on by users of Robot. What you can do to check if the
'Robot' library is correctly linked, is by adding the -Wl,-z,defs flag
to the linker options of libRobot.so  and see if it still wants to
link it. If not, there's your true error, link libRobot.so with the
kdl library, then come back to your component makefile, where it
probably will be fixed 'automagically'.

Peter


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic