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

Linux 上编 FFmpeg 比 Windows 简单:一条 apt 装依赖,两条命令编完。 难的是编完之后:装到哪、怎么让程序找到它,两条都得处理。

📝 本节和前面几节的关系

前面两篇在 Windows 上折腾工具链,这一篇换到 Linux,简单得多。 1.6 会接着用这一篇装好的库,编一个自己的程序。

一、装依赖:一条 apt 解决

Ubuntu 上是 apt install,把 dev 包一次装齐。 包 作用


build-essential gcc g++ make 三件套 yasm nasm 汇编器,x264 要用 pkg-config configure 找库用 libx264-dev libx265-dev 两个编码器的开发包 libvpx-dev libmp3lame-dev VP8/VP9 与 MP3

注意包名的 -dev 后缀。 Ubuntu 把运行时库与开发文件分成两个包:libx264-163 是运行时, libx264-dev 才有头文件与 .so 链接。只装前者,configure 会说找不到 x264。 这条规律在 Linux 上通用:能跑不等于能编。 跟 Windows 上「装了 DLL 不等于有头文件」是同一条道理,只是换了名字。

二、configure:三组参数与一个 prefix

Linux 上的参数比 Windows 少两组,因为没有交叉编译的问题。 组 参数 作用


路径 --prefix=/usr/local/ffmpeg 装到哪 产物 --enable-shared 出 .so 外部库 --enable-libx264 --enable-gpl 开 H.264 编码

--prefix 是这一节最关键的一个参数。 它决定三件事:头文件装到哪、库装到哪、 .pc 文件里写的路径是什么。 .pc 文件就是 pkg-config 的数据库。 里面写死了 prefix, 所以装完再改目录名,pkg-config 就全错了——它给的还是老路径。 别装到 /usr。 系统自带的库也在那儿,覆盖了会让别的软件跟着坏。 装到 /usr/local/ffmpeg 这种独立目录,删的时候干净。

三、make:核数决定等多久

make -j 后面那个数字,取核数或核数加一最划算。 写法 并行度 说明


make 1 最慢,调试时用 make -j4 4 保守,内存小就用它 make -j$(nproc) 自动 脚本里的标准写法

本机 os.cpu_count() 报 16。 按这个数取 -j16,在真机上大约几分钟编完;单核要半小时以上。 但并行度不是越大越好。 每个编译进程都要几百兆内存,十六核开到 32 会把内存打满, 系统开始换页,反而更慢。内存 8 GB 的机器,-j8 就是上限。

四、装完之后:让系统找到它

make install 只是把文件拷过去,系统还不知道有这套库。 现象 原因 怎么修


pkg-config 找不到 .pc 不在 PKG_CONFIG_PATH export PKG_CONFIG_PATH 运行时找不到 .so 不在 ld 的搜索路径 ldconfig 或 LD_LIBRARY_PATH 编译能找到、运行找不到 只设了编译期路径 两个都要设

这三种现象是新手最容易混的。 第一种发生在 configure 阶段,第二种发生在跑程序的时候, 第三种最坑——编的时候一切正常,一运行就报 error while loading shared libraries。 记住一句话:编译期靠 -I 与 -L,运行期靠 LD_LIBRARY_PATH。 两套机制互不相干。 本机是 Windows,没有 apt、没有 make、没有 nproc。这一节的数字里只有核数是真的,其余是清单。

五、动手 Demo:Linux 平台编 5.0——apt 一条命令,make 一条命令

本机是 Windows,跑不了 apt 与 make。 这一段取真实核数,算一遍 -j 该取多少,再把依赖清单摆出来。

import os

cpu = os.cpu_count() or 1
print("核数 =", cpu)
print("建议 -j =", cpu)
print("核数", cpu, "核数加一", cpu + 1)

实跑输出:

--------------------------------------------------------------------
Linux 平台编 5.0——apt 一条命令,make 一条命令
--------------------------------------------------------------------

**① Ubuntu 上的依赖,一条 apt 装完**

  包                              作用
  ---------------------------------------------------------
  build-essential                 gcc、g++、make 三件套
  yasm  nasm                      汇编器
  pkg-config                      configure 找库用
  libx264-dev  libx265-dev        编码器开发包
  libvpx-dev  libfdk-aac-dev      VP8/VP9 与 AAC
  libmp3lame-dev  libopus-dev     MP3 与 Opus

**② configure 之后的 make,核数决定等多久**

  写法                并行数     说明
  -----------------------------------------------------
  make                1          单核,最慢
  make -j4            4          保守
  make -j8            8          本机核数,通常最快
  make -j$(nproc)     自动       脚本里的标准写法

本机 `os.cpu_count()` 报 **8**。
按经验 `-j` 取核数或核数加一都行,再大反而因为内存不够来回换页而变慢。

**③ 三条命令的顺序不能乱**

`./configure` 生成 Makefile 与 config.h;`make` 编;
`make install` 把库和头文件拷到 `--prefix` 指定的地方。
**跳过 configure 直接 make,报错是「没有 Makefile」。** configure 挂了还硬 make,
报的错跟真正的原因差着十万八千里。

**④ 一条判断 configure 成没成的规矩**

别去看前面滚过的几百行,只看最后 20 行。
里面有 `License:`、`Enabled programs:`、`Enabled decoders:` 这几段,
再看 `WARNING:` 后面跟的是不是你能接受的。
**configure 失败不会半途退出,它会带着残缺的配置往下走**,所以要自己回头查。

**⑤ 本机是 Windows**,`os.name` 报 `nt`,没有 apt、没有 make、没有 nproc。
所以这一节的数字只有核数是真的,其余是清单。

本机 16 核,建议 -j16。 但内存决定上限,8 GB 内存的机器 -j8 就到头了。 nproc 与 os.cpu_count() 取的是同一个数,脚本里用前者更省事。

30 秒实验

  1. nproc 与 nproc --all 的差别:前者是可用核数,后者是物理核数。
  2. pkg-config --modversion libavcodec 报不出号时,先 echo $PKG_CONFIG_PATH。
  3. ldd 你的程序 | grep avcodec 看运行时能不能找到库。

常见误区

  1. 装到 /usr 覆盖系统库。 别的软件跟着坏,删都删不干净。
  2. 只设 -I -L 不设运行期路径。 编得过,一跑就报找不到 .so。
  3. -j 开到核数两倍。 内存打满开始换页,比单核还慢。
自测三问(点开对答案) 1. 为什么 Linux 上要装 `-dev` 包而不是运行时包? —— 开发文件(头文件、.so 链接)在 -dev 包里。只装运行时,configure 找不到库。 2. `--prefix` 除了决定装到哪,还影响什么? —— 影响 `.pc` 文件里写死的路径。装完再改目录名,pkg-config 给的就是错路径。 3. 编译能找到库、运行却报找不到 .so,是什么原因? —— 编译期用 -I/-L,运行期用 LD_LIBRARY_PATH 或 ldconfig,两套机制独立。

相关笔记