You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake项目链接OpenCV失败:libopencv_highgui.so引用FFmpeg符号未解析

问题描述

项目链接OpenCV库时出现未解析符号错误,系统中OpenCV依赖libavcodec-*系列库,已通过target_link_libraries添加这些库的完整路径,且确认库包含所需符号,但仍报错:

/usr/lib/aarch64-linux-gnu/libopencv_highgui.so.2.4.9: undefined reference to `av_malloc@LIBAVUTIL_FFMPEG_54'
/usr/lib/aarch64-linux-gnu/libopencv_highgui.so.2.4.9: undefined reference to `av_register_all@LIBAVFORMAT_FFMPEG_56'
/usr/lib/aarch64-linux-gnu/libopencv_highgui.so.2.4.9: undefined reference to `avcodec_close@LIBAVCODEC_FFMPEG_56'

通过cmake --build . --verbose查看的链接命令如下:

/usr/bin/c++ \
CMakeFiles/myproject.dir/imgproc.cc.o \
-o \
myproject \
 \
/usr/lib/aarch64-linux-gnu/libQt5Widgets.so.5.6.1 \
/usr/lib/aarch64-linux-gnu/libopencv_features2d.so.2.4.9 \
/usr/lib/aarch64-linux-gnu/libopencv_photo.so.2.4.9 \
_deps/oatpp-build/src/liboatpp.a \
/usr/lib/aarch64-linux-gnu/libavcodec-ffmpeg.so \
/usr/lib/aarch64-linux-gnu/libavformat-ffmpeg.so \
/usr/lib/aarch64-linux-gnu/libavutil-ffmpeg.so \
/usr/lib/aarch64-linux-gnu/libswscale-ffmpeg.so \
/usr/lib/aarch64-linux-gnu/libQt5Gui.so.5.6.1 \
/usr/lib/aarch64-linux-gnu/libQt5Core.so.5.6.1 \
/usr/lib/aarch64-linux-gnu/libopencv_flann.so.2.4.9 \
/usr/lib/aarch64-linux-gnu/libopencv_highgui.so.2.4.9 \
/usr/lib/aarch64-linux-gnu/libopencv_imgproc.so.2.4.9 \
/usr/lib/aarch64-linux-gnu/libopencv_core.so.2.4.9 \
-lpthread \
-latomic

更新:已检查库文件信息:

file /usr/lib/aarch64-linux-gnu/libavcodec-ffmpeg.so.56.60.100 
/usr/lib/aarch64-linux-gnu/libavcodec-ffmpeg.so.56.60.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e534adc24d3ba924851e5a11dc9eee87d5008d36, stripped
file /usr/lib/aarch64-linux-gnu/libopencv_highgui.so.2.4.9 
/usr/lib/aarch64-linux-gnu/libopencv_highgui.so.2.4.9: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=2a6d6bf1318da7a8593b96359b3c8a66008744ee, stripped

咨询问题

  1. version 1 (SYSV)与version 1 (GNU/Linux)是否与链接失败有关?
  2. 如何在CMake构建中保持库的链接顺序?OpenCV库通过find_package获取,而avcodec-ffmpeg无CMake配置文件,当前用find_library获取,如何在CMake中控制LINK_LIBS的链接顺序?

解答

问题1:ELF版本标识与链接失败的关系

version 1 (SYSV)和version 1 (GNU/Linux)仅为ELF文件的版本标识差异,不会导致链接失败。SYSV是标准ELF格式的版本标记,GNU/Linux是GNU对ELF的扩展标记,两者在aarch64架构下兼容性无问题,链接器可正常处理这两种标识的库文件。当前未解析符号问题的核心原因是链接顺序错误,而非ELF版本标识差异。

问题2:CMake中控制链接顺序的方法

链接器处理库的顺序为从左到右,依赖库必须放在被依赖库的后面。从现有链接命令可见,libavcodec-ffmpeg.so等FFmpeg库位于libopencv_highgui.so之前,而libopencv_highgui.so依赖FFmpeg库,导致链接器处理libopencv_highgui.so时无法找到FFmpeg的符号。

具体解决方法:

  1. 直接调整target_link_libraries的顺序
    确保FFmpeg库在OpenCV库之后链接。假设通过以下方式获取库:

    find_package(OpenCV REQUIRED)
    find_library(AVCODEC_LIB avcodec-ffmpeg PATHS /usr/lib/aarch64-linux-gnu)
    find_library(AVFORMAT_LIB avformat-ffmpeg PATHS /usr/lib/aarch64-linux-gnu)
    find_library(AVUTIL_LIB avutil-ffmpeg PATHS /usr/lib/aarch64-linux-gnu)
    find_library(SWSCALE_LIB swscale-ffmpeg PATHS /usr/lib/aarch64-linux-gnu)
    set(FFMPEG_LIBS ${AVCODEC_LIB} ${AVFORMAT_LIB} ${AVUTIL_LIB} ${SWSCALE_LIB})
    

    则target_link_libraries需按如下顺序编写:

    target_link_libraries(myproject
        PRIVATE
        Qt5::Widgets
        ${OpenCV_LIBS}
        ${FFMPEG_LIBS}
        oatpp
        Qt5::Gui
        Qt5::Core
        pthread
        atomic
    )
    

    修改后生成的链接命令中,FFmpeg库会出现在OpenCV库之后,链接器即可正确找到libopencv_highgui.so依赖的符号。

  2. 用INTERFACE库封装FFmpeg依赖(可选)
    若需更清晰的依赖管理,可创建INTERFACE库封装FFmpeg依赖,再让OpenCV依赖该库:

    add_library(ffmpeg INTERFACE)
    target_link_libraries(ffmpeg INTERFACE ${FFMPEG_LIBS})
    target_link_libraries(myproject PRIVATE Qt5::Widgets ${OpenCV_LIBS} ffmpeg oatpp Qt5::Gui Qt5::Core pthread atomic)
    

    CMake会自动处理依赖顺序,核心仍是保证被依赖的FFmpeg库在OpenCV之后链接。

  3. 验证链接顺序
    修改后重新执行cmake --build . --verbose,检查链接命令中libavcodec-ffmpeg.so等库是否位于libopencv_highgui.so之后,确保顺序正确。


内容的提问来源于stack exchange,提问作者Michaelzh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 04:01:03