🎬 第一章 编译FFmpeg源码并搭建开发环境
📄 一句话概括

Qt 的 .pro 里只要写三行:头文件路径、库路径、库名。 三行里三个坑:-l 前缀、-L 顺序、工具链一致。

📝 本节和前面几节的关系

1.3 把库装好了,这一篇让 Qt 认得它。 下一篇 1.5 是同一件事的 VS 版本。

一、三行就能编,但三行都能写错

Qt 的工程文件是 .pro,本质是一堆变量赋值。 变量 写什么 作用


INCLUDEPATH 头文件目录 让 #include 找得到 LIBS -L 库目录 -l 库名 让链接器找得到 DEPENDPATH 头文件目录 改头文件时触发重编

三行都写对才编得过。 少 INCLUDEPATH,报「找不到头文件」;少 LIBS,报「未定义引用」; 少 DEPENDPATH 不报错,但你改了头文件它不重编,查半天以为是代码问题。

二、坑一:-lavcodec 不是 -llibavcodec

-l 后面的名字要去掉 lib 前缀与 .so/.a 后缀。 库文件 正确的写法 错误的写法


libavcodec.so -lavcodec -llibavcodec libavformat.so -lavformat -llibavformat avcodec.lib 不能这样写 Qt 不认 MSVC 库

写 -llibavcodec,链接器会去找 liblibavcodec.so。 报错信息是 cannot find -llibavcodec, 看着像装错了库,其实是名字多写了三个字母。

三、坑二:-L 必须在 -l 前面

链接器从左往右扫,遇到 -l 当场就要找到它。 所以 -lavcodec -L/path 这种写法,-L 等于没写——扫到 -lavcodec 时它还不知道去哪找。 写法 结果


-L/path -lavcodec 对 -lavcodec -L/path 错的,找不到库

这条规则跟「先声明再使用」是一个意思,只是链接器不报语法错,只报「找不到这个库」。 看见 cannot find -lavcodec,先看 -L 是不是写在后面了。

四、坑三:构建套件要与库同一工具链

Qt 的「构建套件」决定用哪个编译器,它必须与编 FFmpeg 的那个一致。 Qt 套件 能链哪种 FFmpeg 混了会怎样


MinGW 版 Qt MinGW 编的 报 undefined reference MSVC 版 Qt MSVC 编的 报 LNK2019

这两套 Qt 装在同一台机器上很常见,装的时候不觉得,编的时候才发现套件选错了。 判断方法: Qt Creator 的「构建套件」里能看到编译器名字,gcc 就是 MinGW, cl.exe 就是 MSVC。 本机验不了这一节:没有 Qt、没有 Qt Creator、qmake 不在 PATH。 上面三个坑是规则,不依赖环境。

五、动手 Demo:Qt 开发环境——.pro 里三行写错,编译就找不到库

本机没有 Qt,所以这一段做的是:生成 .pro 片段、检查三处规则、查路径在不在。 路径检查会全报「不在」,规则检查全过。

pro = ["INCLUDEPATH += C:/ffmpeg/include",
       "LIBS += -LC:/ffmpeg/lib -lavcodec -lavformat -lavutil"]

print(pro[1].index("-L") < pro[1].index("-lavcodec"))

实跑输出:

--------------------------------------------------------------------
Qt 开发环境——.pro 里三行写错,编译就找不到库
--------------------------------------------------------------------

**① Qt 的工程文件只要三样东西**

`.pro` 里写 `INCLUDEPATH`(头文件在哪)、`LIBS`(导入库在哪)、
`DEPENDPATH`(改头文件时重编的依赖)。少一样就编不过。

**② 本课生成的 .pro 片段**

`INCLUDEPATH += C:/ffmpeg/include`
`LIBS += -LC:/ffmpeg/lib -lavcodec -lavformat -lavutil`
`LIBS += -lavfilter -lswscale -lswresample`
`DEPENDPATH += C:/ffmpeg/include`

**③ 三行里有三个坑,用代码验一遍**

  检查项                          结果
  ----------------------------------------
  路径存在:C:/ffmpeg/include     不在
  路径存在:C:/ffmpeg/lib         不在
  -L 在 -l 前面                   对
  库名带 -l 前缀、不带扩展名      对

**第一个坑:`-lavcodec` 不是 `-llibavcodec`。** `-l` 后面跟的是去掉 `lib` 前缀、去掉扩展名的名字,
写 `-llibavcodec` 链接器会去找 `liblibavcodec.so`。

**第二个坑:`-L` 必须写在用到它的 `-l` 前面。** 链接器是从左往右扫的,先看见 `-l` 再去记 `-L`,
那条路径等于没写。

**第三个坑:Windows 上 `LIBS` 里的库名要跟着工具链变。** MSVC 的导入库叫 `avcodec.lib`,
MinGW 的叫 `libavcodec.dll.a`,Qt 的 `-l` 规则只认后者。
用 MSVC 编 FFmpeg、再用 MinGW 的 Qt 链,必然失败。

**④ 本机验到哪一步**:上面两行路径检查全报「不在」,因为这台机器没编过 FFmpeg。
但**三个坑是规则,不是环境**——路径换对了,规则照样成立。

-L 在前、-l 在后,这一条过了;路径检查两条全不在。 路径不在只说明本机没编过 FFmpeg,不影响规则成立。

30 秒实验

  1. qmake -query QT_INSTALL_PREFIX 看 Qt 装在哪,再对一对构建套件的编译器。
  2. 故意把 -L 写到 -l 后面,看链接器报什么。
  3. pkg-config --libs libavcodec 看看它给出的顺序,跟自己手写的对一下。

常见误区

  1. 写 -llibavcodec。 链接器会去找 liblibavcodec.so,永远找不到。
  2. 把 -L 写在 -l 后面。 链接器扫到 -l 时还不知道去哪找。
  3. 用 MinGW 版 Qt 链 MSVC 编的 FFmpeg。 两套 ABI 不通用,一个符号都链不上。
自测三问(点开对答案) 1. `-lavcodec` 里的 `-l` 是什么意思,后面的名字怎么来的? —— `-l` 表示链接库,后面的名字是库文件名去掉 `lib` 前缀与扩展名。 2. 为什么 `-L` 必须写在 `-l` 前面? —— 链接器从左往右扫,扫到 `-l` 时就要立刻找到库,后面的 `-L` 来不及起作用。 3. 怎么判断 Qt 套件与 FFmpeg 是不是同一工具链? —— 看套件里的编译器名:gcc 对应 MinGW 编的库,cl.exe 对应 MSVC 编的库。

相关笔记