1
votes

I'm writing an application containig 2 internal libraries and depends on more 2 external libraries (ffmpeg and opencv). I'm also using CMake to produce UNIX makefiles. And the problem is when i'm trying to build sources, it compiles but don't link with ffmpeg at all and the next output the linker gives:

../../Decoder/libDecoder.a(ConverterAVFrameToRGB.cpp.o): In function `FaceVideo::ConverterAVFrameToRGB::to_rgb_conversion(std::vector<AVFrame*, std::allocator<AVFrame*> >&, int, int, int)':
ConverterAVFrameToRGB.cpp:(.text+0x990): undefined reference to `av_frame_free'
../../Decoder/libDecoder.a(FfmpegDecoder.cpp.o): In function `FaceVideo::FfmpegDecoder::destroy()':
FfmpegDecoder.cpp:(.text+0xa30): undefined reference to `av_frame_free'
../../Decoder/libDecoder.a(FfmpegDecoder.cpp.o): In function `FaceVideo::FfmpegDecoder::decode_next_chunk(int)':
FfmpegDecoder.cpp:(.text+0xb6b): undefined reference to `av_frame_clone'
FfmpegDecoder.cpp:(.text+0xc13): undefined reference to `av_frame_free'
../../Decoder/libDecoder.a(FfmpegEncoder.cpp.o): In function `FaceVideo::FfmpegEncoder::destroy()':
FfmpegEncoder.cpp:(.text+0x132): undefined reference to `avcodec_free_frame'
../../Decoder/libDecoder.a(FfmpegEncoder.cpp.o): In function `FaceVideo::FfmpegEncoder::encode()':
FfmpegEncoder.cpp:(.text+0x4c4): undefined reference to `avcodec_encode_video2'
FfmpegEncoder.cpp:(.text+0x592): undefined reference to `avcodec_encode_video2'
../../Decoder/libDecoder.a(FrameSaver.cpp.o): In function `FaceVideo::FrameSaver::saver(std::vector<AVFrame*, std::allocator<AVFrame*> >&, int, int, int)':
FrameSaver.cpp:(.text+0x869): undefined reference to `av_frame_free'
collect2: ld returned 1 exit status

That's excatly what i don't want to see.

There are three Cmake files: two for internal libraries (use

add_library(Decoder ${SOURCES_DECODER})
             and 
add_library(Detector ${SOURCES_DETECTOR})

in them) and one for main executable (use

add_executable(Tool ${SOURCES_TOOL})
             and
target_link_libraries (Tool Decoder avutil avcodec swscale avformat Detector ${OpenCV_LIBS})

in it).

As far as i understand from CMake manuals and examples, this should make linker link this libraries together, but no effect.

I've been trying lot of things such as:
1) Adding link_directories() with path to libraries (/usr/lib/x86_64-linux-gnu/ for me) wherever it's possile, nothing changed.
2) Linking every library separately, i mean i tried do something like this in my internal libraries CMake files: target_link_libraries (Decoder avutil avcodec swscale avformat). And then link library together into my Tool CMake file: target_link_libraries (Tool Decoder Detector).
3) Editing output makefiles.
4) Compiling simple one-file application just to test whether i can do it or not. I can. g++ -lavcodec -o out mysource.cpp works perfectly.
5) Compling ffmpeg manually and installing it.

The fact is i realy don't know what should i do. I have no idea. And i would very appreciate your every answer.

UPD1: Output when CMAKE_VERBOSE_MAKEFILE is set

! /usr/bin/c++ -march=x86-64 -Wall -fPIC -pthread -std=c++0x -D__STDC_CONSTANT_MACROS -march=x86-64 -fPIC CMakeFiles/FaceDetectorTool.dir/home/anton/Programming/facevideo/branches/Stream_Prototype/src/tools/FaceDetectorTool/facedetector.cpp.o -o FaceDetectorTool -rdynamic ../../Detector/libDetector.a ../../Decoder/libDecoder.a -lavutil -lavcodec -lswscale -lavformat /usr/local/lib/libopencv_videostab.so.2.4.7 /usr/local/lib/libopencv_video.so.2.4.7 /usr/local/lib/libopencv_ts.a /usr/local/lib/libopencv_superres.so.2.4.7 /usr/local/lib/libopencv_stitching.so.2.4.7 /usr/local/lib/libopencv_photo.so.2.4.7 /usr/local/lib/libopencv_ocl.so.2.4.7 /usr/local/lib/libopencv_objdetect.so.2.4.7 /usr/local/lib/libopencv_nonfree.so.2.4.7 /usr/local/lib/libopencv_ml.so.2.4.7 /usr/local/lib/libopencv_legacy.so.2.4.7 /usr/local/lib/libopencv_imgproc.so.2.4.7 /usr/local/lib/libopencv_highgui.so.2.4.7 /usr/local/lib/libopencv_gpu.so.2.4.7 /usr/local/lib/libopencv_flann.so.2.4.7 /usr/local/lib/libopencv_features2d.so.2.4.7 /usr/local/lib/libopencv_core.so.2.4.7 /usr/local/lib/libopencv_contrib.so.2.4.7 /usr/local/lib/libopencv_calib3d.so.2.4.7 -ldl -lm -lpthread -lrt /usr/local/lib/libopencv_nonfree.so.2.4.7 /usr/local/lib/libopencv_ocl.so.2.4.7 /usr/local/lib/libopencv_gpu.so.2.4.7 /usr/local/lib/libopencv_photo.so.2.4.7 /usr/local/lib/libopencv_objdetect.so.2.4.7 /usr/local/lib/libopencv_legacy.so.2.4.7 /usr/local/lib/libopencv_video.so.2.4.7 /usr/local/lib/libopencv_ml.so.2.4.7 /usr/local/lib/libopencv_calib3d.so.2.4.7 /usr/local/lib/libopencv_features2d.so.2.4.7 /usr/local/lib/libopencv_highgui.so.2.4.7 /usr/local/lib/libopencv_imgproc.so.2.4.7 /usr/local/lib/libopencv_flann.so.2.4.7 /usr/local/lib/libopencv_core.so.2.4.7 -Wl,-rpath,/usr/local/lib

UPD2 Cmake example looks like that.

cmake_minimum_required (VERSION 2.8)
project (Decoder)
include(../CMakeInit.cmake)
include_directories(${FFMPEG_INCLUDE_DIR})
include_directories(${Stream_Facevideo_SOURCE_DIR}/../src/kernel/decoder/)
include_directories(${Stream_Facevideo_SOURCE_DIR}/../src/kernel/stuff/)
set(SOURCES_VIDEODECODER
            *sources*
  )

if(WINDOWS)
    set(SOURCES_VIDEODECODER    ${SOURCES_VIDEODECODER} 
            *headers*                           
    )
endif(WINDOWS)

set (SOURCES_DECODER
    ${SOURCES_VIDEODECODER}
)

add_library(Decoder ${SOURCES_DECODER})
link_directories("/usr/lib/x86_64-linux-gnu/")
target_link_libraries(Decoder swscale avformat avcodec avutil)
2
Can you give us the code, too? - arc_lupus
@arc_lupus: Sorry, do you wnat application or CMake code? There are lot sources in application and the main fact - it builts on Windows. So i think that is all OK with them. I can post some CMake files you want. - Zoellick
Please try setting CMAKE_VERBOSE_MAKEFILE to true, and post the command line for the faulty linking. - SirDarius
@SirDarius: Well, done! - Zoellick
If the FFmpeg libs are really dependencies of Decoder, you should link them there. CMake will then always link them to any other target which depends on Decoder. (Same goes for Detector if applicable). That doesn't fix your problem though. I think this may be an issue related to the order of the FFmpeg libs. Can you try adding target_link_libraries(Decoder avformat avcodec swscale avutil) in Decoder's CMakeLists.txt, I guess target_link_libraries(Detector ${OpenCV_LIBS}) in Detector's, and just target_link_libraries(Tool Decoder Detector) in the top-level one? - Fraser

2 Answers

0
votes

Seems this solution should work: Findavutil.cmake & CMakeLists.txt

0
votes

Your problem looks like you forget to add LINK_DIRECTORIES for ffmpeg lib.

If it's ok then try to change order of linking libs in target_link_libraries for executable or add target_link_libraries for your internal libs, that use external ones.