【发布时间】:2013-12-21 14:48:42
【问题描述】:
我正在编写一个包含 2 个内部库并依赖于更多 2 个外部库(ffmpeg 和 opencv)的应用程序。我还使用 CMake 来生成 UNIX makefile。问题是当我尝试构建源时,它编译但根本不与 ffmpeg 链接,并且链接器给出的下一个输出:
../../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
这真是我不想看到的。
共有三个 Cmake 文件:两个用于内部库(使用
add_library(Decoder ${SOURCES_DECODER})
and
add_library(Detector ${SOURCES_DETECTOR})
在其中)和一个用于主要可执行文件(使用
add_executable(Tool ${SOURCES_TOOL})
and
target_link_libraries (Tool Decoder avutil avcodec swscale avformat Detector ${OpenCV_LIBS})
在里面)。
据我从 CMake 手册和示例中了解到,这应该使链接器将这些库链接在一起,但没有效果。
我一直在尝试很多事情,例如:
1) 添加link_directories() 和库路径(对我来说是/usr/lib/x86_64-linux-gnu/),只要有可能,没有任何改变。
2)分别链接每个库,我的意思是我尝试在我的内部库 CMake 文件中做这样的事情:target_link_libraries (Decoder avutil avcodec swscale avformat)。然后将库链接到我的 Tool CMake 文件中:target_link_libraries (Tool Decoder Detector).
3) 编辑输出生成文件。
4)编译简单的单文件应用程序只是为了测试我是否可以做到。我能。 g++ -lavcodec -o out mysource.cpp 完美运行。
5)手动编译ffmpeg并安装。
事实上,我真的不知道我该怎么办。我不知道。非常感谢您的每一个回答。
UPD1: 设置 CMAKE_VERBOSE_MAKEFILE 时的输出
! /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/lib opencv_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 示例看起来是这样的。
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)
【问题讨论】:
-
你也可以给我们代码吗?
-
@arc_lupus:抱歉,您有应用程序还是 CMake 代码?应用程序和主要事实有很多来源 - 它建立在 Windows 上。所以我认为这对他们来说没问题。我可以发布一些你想要的 CMake 文件。
-
请尝试将 CMAKE_VERBOSE_MAKEFILE 设置为 true,并发布错误链接的命令行。
-
@SirDarius:好了,完成了!
-
如果 FFmpeg 库确实是
Decoder的依赖项,您应该将它们链接到那里。然后,CMake 将始终将它们链接到依赖于Decoder的任何其他目标。 (如果适用,Detector也是如此)。但这并不能解决您的问题。我认为这可能是与 FFmpeg 库的顺序有关的问题。您可以尝试在Decoder的CMakeLists.txt 中添加target_link_libraries(Decoder avformat avcodec swscale avutil),我猜是在Detector中添加target_link_libraries(Detector ${OpenCV_LIBS}),然后在顶层添加target_link_libraries(Tool Decoder Detector)?
标签: c++ linux linker ffmpeg cmake