Ask Your Question
0

catkin, linking order, undefined reference to symbol

asked 2014-05-28 16:43:20 -0500

mechanicalmanb gravatar image

What controls the linking order in a catkin_make build? I am trying to link to ffmpeg, but I am getting a strange "undefined reference to symbol" error, not a normal undefined reference error that would happen if I forgot to include the library in target_link_libraries( ). Everything I can find about that sort of error is related to incorrectly putting command line linking flags (e.g. -lavcodec) before the object that uses them, i.e. incorrect linking order. But I don't know how to control that with the CMakeLists.txt file.

If I add the library avutil to the target_link_libraries( ), the error switches to a normal undefined reference error. But avutil is the library with those functions, so I have no idea why it still thinks I'm not linking to it. The avcodec library includes avutil, and when I built standalone applications (not ROS) of my own I never had to link to avutil explicitly if I linked to avcodec.

Any ideas?

The catkin_make error:

 Linking CXX executable /home/jason/ROS/ARDrone/devel/lib/ardrone_2/h264_decoder_node
[  0%] [  0%] Built target gensrv_eus
Built target genmanifest_eus
[  0%] [  1%] Built target genmsg_eus
Built target at_controller_node
[  3%] [  4%] Built target video_client_node
Built target navdata_client_node
[ 98%] Built target ardrone_2_ALL_GEN_OUTPUT_FILES_eus
/usr/bin/ld: CMakeFiles/h264_decoder_node.dir/src/h264_decoder.cpp.o: undefined reference to symbol 'av_frame_free@@LIBAVUTIL_52'
/usr/local/lib/libavutil.so.52: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [/home/jason/ROS/ARDrone/devel/lib/ardrone_2/h264_decoder_node] Error 1
make[1]: *** [ardrone_2/CMakeFiles/h264_decoder_node.dir/all] Error 2
make: *** [all] Error 2
Invoking "make" failed

The CMakeLists.txt file:

cmake_minimum_required(VERSION 2.8.3)
project(ardrone_2)
find_package(catkin REQUIRED COMPONENTS 
                roscpp 
                message_generation 
                std_msgs
                image_transport)

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES ardrone_2
#  CATKIN_DEPENDS other_catkin_pkg
#  DEPENDS
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
# include_directories(include)
include_directories(include ${catkin_INCLUDE_DIRS} /usr/local/include)

## Declare a cpp library
# add_library(ardrone_2
#   src/${PROJECT_NAME}/ardrone_2.cpp
# )

## Declare a cpp executable
add_executable(navdata_client_node src/navdata_client.cpp)
add_executable(at_controller_node src/at_controller.cpp)
add_executable(video_client_node src/video_client.cpp)
add_executable(h264_decoder_node src/h264_decoder.cpp)

## Add cmake target dependencies of the executable/library
## as an example, message headers may need to be generated before nodes
# add_dependencies(ardrone_2_node ardrone_2_generate_messages_cpp)

## Specify libraries to link a library or executable target against
# target_link_libraries(ardrone_2_node
#   ${catkin_LIBRARIES}
# )
target_link_libraries(navdata_client_node ${catkin_LIBRARIES})
target_link_libraries(at_controller_node ${catkin_LIBRARIES})
target_link_libraries(video_client_node ${catkin_LIBRARIES})
target_link_libraries(h264_decoder_node ${catkin_LIBRARIES} avcodec avformat swscale)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2014-05-29 15:21:18 -0500

mechanicalmanb gravatar image

updated 2014-05-30 02:29:11 -0500

Found the answer in some loosely related topics. I can't explain WHY this works, but it does.

You need to use a package finding .cmake module for ffmpeg. You can find one here:

https: //code.google.com/r/kyberneticist-webport/source/browse/cmake_modules/FindFFMPEG.cmake

After the find_package( ) for catkin, set the CMAKE_MODULE_PATH variable to where you put the FindFFMPEG.cmake file, assuming your project is "ardrone_2":

set(CMAKE_MODULE_PATH ${ardrone_2_SOURCE_DIR})

Then use find_package on FFMPEG:

find_package(FFMPEG)

The FindFFMPEG.cmake file sets the FFMPEG_LIBRARIES variable:

set(FFMPEG_LIBRARIES
  ${FFMPEG_LIBAVCODEC}
  ${FFMPEG_LIBAVFORMAT}
  ${FFMPEG_LIBAVUTIL}
)

Setting the CMAKE_MODULE_PATH messes up the whatever directory cmake thinks it's in, so you need to specify absolute paths when you use add_executable( ), assuming your package is "ardrone_2":

add_executable(h264_decoder_node ${ardrone_2_SOURCE_DIR}/src/h264_decoder.cpp)

Then link using that variable:

target_link_libraries(h264_decoder_node ${catkin_LIBRARIES} ${FFMPEG_LIBRARIES} swscale)
edit flag offensive delete link more

Comments

1

Perhaps you should append to the CMAKE_MODULE_PATH instead of overriding it. Not sure, but it could help with the rest of the issues you are seeing.

gvdhoorn gravatar imagegvdhoorn ( 2014-06-02 05:53:51 -0500 )edit

Also: perhaps you could suggest including FindFFMPEG.cmake in the cmake_modules package. See https://github.com/ros/cmake_modules.

gvdhoorn gravatar imagegvdhoorn ( 2014-06-02 05:55:44 -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-05-28 16:43:20 -0500

Seen: 2,442 times

Last updated: May 30 '14