【问题标题】:Ffmpeg linking problems using CMake使用 CMake 的 Ffmpeg 链接问题
【发布时间】: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


【解决方案1】:

似乎这个解决方案应该有效:Findavutil.cmake & CMakeLists.txt

【讨论】:

    【解决方案2】:

    您的问题似乎是您忘记为 ffmpeg 库添加 LINK_DIRECTORIES

    如果没问题,请尝试更改 target_link_libraries 中链接库的顺序以获得可执行文件,或为使用外部库的内部库添加 target_link_libraries。

    【讨论】:

    • 正如我所写,我尝试尽可能添加 link_directories() 语句。并以各种可能的方式更改了链接库的顺序。没有改变。如果需要,我可以发布我的 CMake 文件示例。我注意到的另一件事是,在 ConverterAVFrameToRGB.cpp 中,我在 av_frame_free() 之前使用了 sws_getContext 函数,并且它没有在链接器输出中列出。这是否意味着 swscale 库链接到可执行文件和 avutil - 不是?
    • 你在 add_library(Decoder ${SOURCES_DECODER}) 之后尝试了 target_link_libraries(Decoder ${NEEDED_LIBS}) 吗?
    • 是的,我做到了。好吧,我会发布我的cmake代码。有没有办法把它隐藏在扰流板或其他东西下?
    • 哦,vok1980!这么大的帮助!真的行!非常感谢!我认为将其发布为答案是有道理的。
    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多