0
$\begingroup$

Rosanswers logo

I want to make an executable in a package referencing a library in another package. I succeeded making library(named test_utility), but failed to link with executable(named test_using_utility). I don't know what the problem is.

Here is my header and source files to make a library in test_utility package.


// ros_workspace/test_utility/include/test_utility/test_utility.hpp
#ifndef _TEST_UTILITY_
#define _TEST_UTILITY_

class Utility 
{
public:
    float dosomething(float);
};

#endif

// ros_workspace/test_utility/src/test_utility.cpp
#include <test_utility/test_utility.hpp>

float Utility::dosomething(float p)
{
    return p/2;
}

I added this comment in CMakeLists.txt


rosbuild_add_library(test_utility src/test_utility.cpp)

and it's manifest.xml


<package>
  <description brief="test_utility">

     test_utility

  </description>
  <author>babchol</author>
  <license>BSD</license>
  <eview status="unreviewed" notes=""/>
  <url>http://ros.org/wiki/test_utility</url>
  <depend package="roscpp"/>
  <depend package="std_msgs"/>
  <export>
    <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -ltest_utility"/> 
  </export>
</package>

Here is my source file in executable in test_using_utility package.


// ros_workspace/test_using_utility/src/test_using_utility.cpp
#include <ros/ros.h>
#include <test_utility/test_utility.hpp>
#include <iostream>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "test");
    ros::NodeHandle nh;

    Utility u;
    float x = u.dosomething(32);

    std::cout 

I added in CMakeLists.txt


rosbuild_add_executable(test_using_utility src/test_using_utility.cpp)

also, it's manifest.xml


<package>
  <description brief="test_using_utility">

     test_using_utility

  </description>
  <author>babchol</author>
  <license>BSD</license>
  <review status="unreviewed" notes=""/>
  <url>http://ros.org/wiki/test_using_utility</url>
  <depend package="roscpp"/>
  <depend package="std_msgs"/>
  <depend package="test_utility"/>
</package>

Finally, I got an link error like this when rosmaking in test_using_utility package.

[ rosmake ] rosmake starting...                                                 
[ rosmake ] No package specified.  Building ['test_using_utility']              
[ rosmake ] Packages requested are: ['test_using_utility']                      
[ rosmake ] Logging to directory /home/babchol/.ros/rosmake/rosmake_output-20120512-092758
[ rosmake ] Expanded args ['test_using_utility'] to:
['test_using_utility']     
[rosmake-0] Starting >>> roslang [ make ]                                       
[rosmake-1] Starting >>> std_msgs [ make ]                                      
[rosmake-0] Finished >> roscpp [ make ]                                        
[rosmake-1] Finished >> test_utility [ make ]                                  
[rosmake-0] Finished >> test_using_utility [ make ]                            
[ rosmake ] Last 40 linesst_using_utility: 1.5 sec ]   [ 1 Active 4/5 Complete ]
{-------------------------------------------------------------------------------
    source dir.  Run "cmake --help-policy CMP0015" for policy details.  Use the
    cmake_policy command to set the policy and suppress this warning.
  Call Stack (most recent call first):
    CMakeLists.txt:12 (rosbuild_init)
  This warning is for project developers.  Use -Wno-dev to suppress it.
  
  [rosbuild] Including /opt/ros/fuerte/share/roslisp/rosbuild/roslisp.cmake
  [rosbuild] Including /opt/ros/fuerte/share/rospy/rosbuild/rospy.cmake
  [rosbuild] Including /opt/ros/fuerte/share/roscpp/rosbuild/roscpp.cmake
  -- Configuring done
  -- Generating done
  CMake Warning:
    Manually-specified variables were not used by the project:
  
      CMAKE_TOOLCHAIN_FILE
  
  
  -- Build files have been written to: /home/babchol/ros_workspace/test_using_utility/build
  cd build && make -l2
  make[1]: Entering directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[2]: Entering directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[3]: Entering directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[3]: Leaving directory `/home/babchol/ros_workspace/test_using_utility/build'
  [  0%] Built target rospack_genmsg_libexe
  make[3]: Entering directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[3]: Leaving directory `/home/babchol/ros_workspace/test_using_utility/build'
  [  0%] Built target rosbuild_precompile
  make[3]: Entering directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[3]: Leaving directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[3]: Entering directory `/home/babchol/ros_workspace/test_using_utility/build'
  Linking CXX executable ../bin/test_using_utility
  /usr/bin/ld: cannot find -ltest_utility
  collect2: ld returned 1 exit status
  make[3]: *** [../bin/test_using_utility] Error 1
  make[3]: Leaving directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[2]: *** [CMakeFiles/test_using_utility.dir/all] Error 2
  make[2]: Leaving directory `/home/babchol/ros_workspace/test_using_utility/build'
  make[1]: *** [all] Error 2
  make[1]: Leaving directory `/home/babchol/ros_workspace/test_using_utility/build'
-------------------------------------------------------------------------------}
[ rosmake ] Output from build of package test_using_utility written to:
[ rosmake ]    /home/babchol/.ros/rosmake/rosmake_output-20120512-092758/test_using_utility/build_output.log
[rosmake-0] Finished 

It might be an easy question. However, I failed although I followed similar answer(write depend and export in manifest.xml) I'd appreciate for your answer.


Summary(problem solved)

I can solve my problem with help of Lorenz. I sum up the method here to reference other package's library for other people like me.

The situation is that 'A' package already exists for library, and I want to reference it in 'B' package. I have to follow this procedure.

In 'A' package

1. assume already made library. (do same in CMakeLists.txt when you make library) 2. add this in manifest.xml : this exports cflags and lflags that have 'A' package's directory or library information,

(in-my-example)

  
    <export>
      <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -ltest_utility"/>
    </export>
  

In 'B' package,

1. do same in CMakeLists.txt when you make executable. 2. add this in manifest.xml : this indicates 'B' depends 'A'

(in-my-example)

<depend package="test_utility"/>

Originally posted by Hancheol Choi on ROS Answers with karma: 43 on 2012-05-11

Post score: 4

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

The export in your manifest file should be:

 <export>
   <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -ltest_utility"/>
 </export>

This will add your library to the list of libraries to link against.

Edit: It looks like you have a typo in your manifest export, a { is missing after -L. Make sure that it looks exactly as my code above.


Originally posted by Lorenz with karma: 22731 on 2012-05-11

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by Hancheol Choi on 2012-05-13:
Wow! It's my terrible mistake. Anyway, thank you. all solved.

$\endgroup$
0
$\begingroup$

Rosanswers logo

The manifest export provides linking instructions for packages which depend on your package. If you are still inside the same package as the library you need to use the cmake command to link the library:

target_link_library(test_using_utility test_utility)

Originally posted by tfoote with karma: 58457 on 2012-05-11

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by Hancheol Choi on 2012-05-11:
I already tested this in same package, and succeeded. But I want to reference library in other package.

$\endgroup$

Your Answer

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