ffmpeg_dir 是首选方式,因其直接指定含 ffmpegconfig.cmake 的目录,优先级最高且避免 fallback 到不可靠的模块查找;必须加 config required 以强制使用 config 模式并及时报错。

直接用 ffmpeg_DIR 变量指定路径最可靠,比改 CMAKE_MODULE_PATH 或硬塞 HINTS 更少出错。
为什么 ffmpeg_DIR 是首选方式
FFmpeg 官方不提供标准的 Findffmpeg.cmake,多数系统里 find_package(ffmpeg) 实际依赖的是第三方或发行版提供的 ffmpegConfig.cmake(比如 Ubuntu 的 /usr/lib/x86_64-linux-gnu/cmake/ffmpeg/ffmpegConfig.cmake)。这个文件只会在 ffmpeg_DIR 指向的目录下被主动查找,且优先级高于所有默认路径。
-
ffmpeg_DIR必须指向包含ffmpegConfig.cmake的目录,不是库文件目录,也不是头文件目录 - 常见错误是把
ffmpeg_DIR设成/usr/lib或/usr/include—— 这些路径下没有 Config 文件,find_package会静默失败或 fallback 到模块模式(然后大概率找不到) - 如果 FFmpeg 是自己编译安装的,确认
make install后是否生成了share/cmake/ffmpeg/ffmpegConfig.cmake或类似结构;没生成就说明没启用 CMake config 支持,此时不能用CONFIG模式
find_package(ffmpeg CONFIG REQUIRED) 必须加 CONFIG
不加 CONFIG,CMake 会先尝试找 Findffmpeg.cmake —— 但绝大多数环境根本没有这个文件,结果就是报 By not providing "Findffmpeg.cmake" in CMAKE_MODULE_PATH 警告,然后失败。
- 加
CONFIG强制走 Config 模式,跳过 Find 模块查找逻辑 -
REQUIRED避免静默跳过,让缺失时立刻报错,而不是留到链接阶段才崩 - 如果你确实只有头文件和 .so 文件,没 Config 文件,那就别用
find_package,改用find_library+find_path手动拼接(见下一条)
没 ffmpegConfig.cmake 时怎么手动定位
常见于自编译 FFmpeg、交叉编译、或某些精简发行版。这时 find_package 不适用,得退回到原始定位方式:
- 用
find_path找头文件:find_path(FFMPEG_INCLUDE_DIR avcodec.h HINTS /path/to/ffmpeg/include) - 用
find_library找每个库:find_library(AVCODEC_LIBRARY avcodec HINTS /path/to/ffmpeg/lib)(注意顺序:avcodec、avformat、avutil、swscale、swresample、avfilter) - 必须显式
target_include_directories和target_link_libraries,不能依赖${ffmpeg_LIBRARIES}这类变量(它们不会自动产生) - 避免用
link_directories()—— 它作用域不明确,容易在多 target 项目中误连错库
容易被忽略的兼容性细节
FFmpeg 库名在不同系统上可能不一致:Ubuntu 的 libavcodec.so 在 macOS 上可能是 libavcodec.dylib,而某些嵌入式平台甚至用 libavcodec.a 静态链接。这些差异不会被 find_package 自动抹平。
-
find_library的NAMES参数要覆盖常见变体:find_library(AVCODEC_LIBRARY NAMES avcodec libavcodec HINTS ...) - FFmpeg 5.0+ 移除了部分旧符号,如果链接时报
undefined reference to 'avcodec_free_frame',说明头文件和库版本不匹配 ——find_package不检查 ABI 兼容性,得靠你人工对齐 - 交叉编译时,
ffmpeg_DIR必须指向目标平台的 install 树,不能复用宿主机路径;否则 Config 文件可能包含错误的find_library搜索路径











