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

编译启用libx264的FFmpeg后,本地C++项目链接出现未定义引用错误的求助

解决本地Ubuntu 22+下FFmpeg+x264+VAAPI链接错误问题

我帮你梳理下这个问题的核心原因和解决步骤——云端环境干净所以能正常编译,本地出问题基本是CMake配置逻辑错误或者系统残留库干扰导致的,咱们一步步来解决:

一、先排查本地环境残留问题

虽然你卸载了系统FFmpeg,但可能还有残留的库或者配置文件干扰:

  • 检查系统目录里的FFmpeg库:
    ls /usr/lib/x86_64-linux-gnu/libav*.so*
    ls /usr/local/lib/libav*.so*
    
    如果发现/usr/lib下还有旧的FFmpeg库,直接删除(注意备份,避免误删);
  • 清理pkg-config残留配置:
    sudo rm -rf /usr/lib/pkgconfig/libav*.pc /usr/local/lib/pkgconfig/libav*.pc
    
  • 重新更新共享库缓存:
    sudo ldconfig
    

二、修复CMakeLists.txt的核心错误

你的CMake配置有几个明显的逻辑问题,这是导致链接错误的主要原因:

  1. 错误地在add_definitions里放链接参数:add_definitions是用来添加编译宏的,-lxxx这类链接参数放在这里不会生效,反而会干扰编译;
  2. 重复查找库:AVCODEC_INCLUDE_DIR和AVCODEC_LIBRARY被查找了两次,容易导致混淆;
  3. 库链接顺序错误:GCC链接器要求被依赖的库放在后面,比如avcodec依赖x264,x264要放在avcodec之后链接,手动写链接参数很容易搞反顺序;
  4. 未优先查找自己编译的FFmpeg库:默认的find_library可能先找到系统残留的库,而不是你编译的/usr/local/lib下的库。

修改后的CMakeLists.txt示例

cmake_minimum_required(VERSION 3.7)
project(Renderer C CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)

# 仅保留编译宏定义,编译选项单独设置
add_definitions(-DGL_SILENCE_DEPRECATION)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") # 将调试符号选项放在编译flags里

# 设置pkg-config路径,优先查找本地编译的FFmpeg配置文件
set(PKG_CONFIG_PATH "/usr/local/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}")

# 使用pkg-config自动查找依赖(比手动find更可靠,能自动处理链接顺序)
find_package(PkgConfig REQUIRED)
pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET
    libavformat
    libavcodec
    libavutil
    libswscale
    libswresample
    libavdevice
)
pkg_check_modules(X264 REQUIRED IMPORTED_TARGET libx264)
pkg_check_modules(VA REQUIRED IMPORTED_TARGET libva libva-drm libva-x11)

# 查找线程库
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

# 查找OpenGL、X11等图形依赖
find_package(OpenGL REQUIRED)
find_package(X11 REQUIRED)

# 替换为你实际的源文件列表
list(APPEND SOURCES 
    # 这里写你的源文件,比如 src/xxx.cpp
)

add_executable(Renderer src/main.cpp src/Application.cpp src/Application.h ${SOURCES})

# 设置头文件包含路径
target_include_directories(Renderer PRIVATE
    ${OPENGL_INCLUDE_DIR}
    ${X11_INCLUDE_DIR}
)

# 链接库,严格遵循"依赖多的在前,被依赖的在后"的顺序
target_link_libraries(Renderer PRIVATE
    Threads::Threads
    ${OPENGL_LIBRARIES}
    ${X11_LIBRARIES}
    PkgConfig::FFMPEG
    PkgConfig::X264
    PkgConfig::VA
    -lz -lm -lbz2 -llzma -lrt -lvdpau
)

关键修改点说明

  • 用pkg-config管理依赖:自己编译的FFmpeg会生成.pc配置文件,pkg-config能自动获取正确的头文件路径、库路径和链接顺序,彻底避免手动配置的错误;
  • 分离编译和链接选项:把-g这类编译选项放到CMAKE_CXX_FLAGS,链接参数全部放到target_link_libraries;
  • 指定PKG_CONFIG_PATH:确保优先找到你编译的FFmpeg的配置文件,而不是系统残留的;
  • 规范链接顺序:pkg-config生成的目标已经处理了FFmpeg内部的依赖顺序,只需要把外部依赖(比如x264、VAAPI)放在FFmpeg之后即可。

三、重新编译验证

  1. 删除旧的build目录(如果有的话):
    rm -rf build && mkdir build && cd build
    
  2. 生成CMake配置,注意查看输出,确认找到的是/usr/local/lib下的FFmpeg库:
    cmake ..
    
    比如你应该看到类似Found libavcodec: /usr/local/lib/libavcodec.so的输出;
  3. 编译项目:
    make -j$(nproc)
    
  4. 验证链接是否正确:
    ldd ../bin/Renderer
    
    检查输出里的FFmpeg、x264、VAAPI库是否都指向/usr/local/lib或者正确的路径。

四、额外排查点(如果还是有问题)

  • 检查FFmpeg编译配置:重新运行./configure --enable-shared --enable-libx264 --enable-gpl,确认输出里有libx264: yes和VAAPI: yes,确保这些功能真的被编译进去了;
  • 对比云端和本地的gcc版本:如果云端是gcc10,本地是gcc12,可能存在ABI差异,可以尝试安装对应版本的gcc;
  • 确认libx264-dev安装正确:检查/usr/lib/x86_64-linux-gnu/libx264.so和/usr/include/x264.h是否存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:32:30