Ask Your Question
1

migrating to catkin: undefined reference from header file

asked 2014-02-25 08:45:43 -0500

updated 2014-02-26 05:33:28 -0500

I'm trying to catkinize the people stack, and am getting undefined references to things in a header file in the face_detector package.

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)
project(face_detector)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  geometry_msgs
  std_srvs
  cv_bridge
  stereo_msgs
  sensor_msgs
  tf
  rosbag
  image_transport
  people_msgs
  image_geometry
  genmsg
  actionlib_msgs)

find_package(Boost REQUIRED COMPONENTS signals system thread)
find_package(OpenCV)

include_directories(
  include
  ${Boost_INCLUDE_DIRS}
  ${OpenCV_INCLUDE_DIRS}
  ${catkin_INCLUDE_DIRS})

#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

add_action_files(
  DIRECTORY action
  FILES FaceDetector.action
)
generate_messages(DEPENDENCIES actionlib_msgs people_msgs)

add_executable(face_detector
                       src/face_detection.cpp 
                       src/faces.cpp)
target_link_libraries(${PROJECT_NAME}
  ${catkin_LIBRARIES}
  ${Boost_LIBRARIES}
  ${OpenCV_LIBRARIES})

catkin_package(INCLUDE_DIRS include
  CATKIN_DEPENDS people_msgs geometry_msgs)

Errors:

CMakeFiles/face_detector.dir/src/face_detection.cpp.o: In function `people::FaceDetector::FaceDetector(std::string)':
face_detection.cpp:(.text._ZN6people12FaceDetectorC2ESs[_ZN6people12FaceDetectorC5ESs]+0xd49): undefined reference to `people::Faces::FACE_SIZE_MIN_M'
face_detection.cpp:(.text._ZN6people12FaceDetectorC2ESs[_ZN6people12FaceDetectorC5ESs]+0xdb6): undefined reference to `people::Faces::FACE_SIZE_MAX_M'
face_detection.cpp:(.text._ZN6people12FaceDetectorC2ESs[_ZN6people12FaceDetectorC5ESs]+0xe23): undefined reference to `people::Faces::MAX_FACE_Z_M'
face_detection.cpp:(.text._ZN6people12FaceDetectorC2ESs[_ZN6people12FaceDetectorC5ESs]+0xe90): undefined reference to `people::Faces::FACE_SEP_DIST_M'
collect2: error: ld returned 1 exit status
make[2]: *** [/home/lazewatd/people_ws/devel/lib/face_detector/face_detector] Error 1
make[1]: *** [people/face_detector/CMakeFiles/face_detector.dir/all] Error 2
make: *** [all] Error 2
Invoking "make" failed

A few things to note:

  • this worked fine with rosbuild in hydro
  • I know it can find the header file - if I remove/change include from include_directories, it complains about not being able to find it way earlier

UPDATE:

Now I'm even more confused. The first example works, but the second leads to the linker errors above:

namespace people {
    //works
    double fsmm = Faces::FACE_SIZE_MIN_M;
    local_nh.param("face_size_min_m",face_size_min_m,fsmm);

    //doesn't work
    local_nh.param("face_size_min_m",face_size_min_m,Faces::FACE_SIZE_MIN_M);
}
edit retag flag offensive close merge delete

Comments

Those are linker errors. Where are the symbols in the header file defined? Is there a missing library?

joq gravatar image joq  ( 2014-02-25 13:35:24 -0500 )edit

It's referring to a few constants defined in faces.h, which is in the package which I'm trying to catkin_make. faces.h is in include/face_detector.

Dan Lazewatsky gravatar image Dan Lazewatsky  ( 2014-02-25 13:55:00 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
3

answered 2014-02-26 05:38:27 -0500

ahendrix gravatar image

You're defining FACE_SIZE_MIN_M in the header as:

  static const double FACE_SIZE_MIN_M=0.1;

And the compiler later expects you to define it in your implementation (.cpp file) as:

double Faces::FACE_SIZE_MIN_M = 0.1;

because a static const variable is in reality a global variable, and you have to allocate the storage for it somewhere in your implementation.

I suspect that this was working in the past because the compiler had optimizations turned on by default in rosbuild, and was able to optimize out all of the references to Faces::FACE_SIZE_MIN_M before the linker ever saw them. Now that catkin doesn't enable release mode by default, you're seeing errors that have been there all along.

edit flag offensive delete link more

Comments

Good catch! I looked at that code too, but could not figure out how it had ever worked.

joq gravatar image joq  ( 2014-02-26 05:52:25 -0500 )edit

Thanks, that was the problem. Oddly, the various stackexchange posts on this topic suggest that static consts in header files should be usable this way. Anyway, I just #define'd them rather than declare them in the implementation file, which works.

Dan Lazewatsky gravatar image Dan Lazewatsky  ( 2014-02-26 07:15:58 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2014-02-25 08:45:43 -0500

Seen: 1,054 times

Last updated: Feb 26 '14