本页内容包含了在Unix/Linux中用源码包编译的通用的结构

可能不仅仅适用于ffmpeg

为啥使用源码包编译

  • 编译源码可以扩展功能,
  • 实现相对于自己平台的最优化,
  • 还可以自定义的修改

概述

大部分源码包编译安装包含下面几个步骤:

  • 配置(./configure
  • 编译(make
  • 安装((sudo) make install

配置的过程就是找找编译时候需要的啥程序有没有安装上,然后配置安装路径和需要安装的组件,在安装包里会有这么一个配置脚本,解决了怎么安装的问题

配置完成后开始编译,这个过程生成需要的库文件和二进制程序,解决了安装啥的问题

安装过程就是将库文件和二进制程序安装到在配置时指定的文件夹,当然如果不需要修改路径,那在编译的文件夹下也是可以使用的

一般安装到/usr/local/中,但可能需要管理员权限

安装路径

在配置的时候可以使用configure --prefix=PREFIX来指定安装到哪里。这里的PREFIX一般是/usr/local/

一般有如下几种文件夹需要安装:

  • PREFIX/bin:包含了一般的程序;像ffmpeg,ffplay,ffprobe之类的
  • PREFIX/include:存放着一些头文件,在编译与链接到此库的应用程序时用得着;像libavutil/avstring.h, libavcodec/avcodec.h, libavformat/avformat.h之类的
  • PREFIX/lib:包含了编译生成的库文件;像libavutil, libavcodec, libavformat之类的
  • PREFIX/share:包含了多种多样的不和系统相关的组件,尤其是帮助文件或者实例

通过指定prefix可以自己规划安装的布局

安装到/usr/local/中时,不同的包也会安装到这个文件夹下面,一般来讲这样不有利于恢复安装

如果我们安装到一个像/opt/PROJECT/这样的文件中时,只需要从系统路径中删除这个路径就可以起到删除安装的作用,但这也需要我们在安装的时候把它添加到路径当中

环境变量

有几个系统变量也会影响安装。尤其是在指定了安装的prefix之后,就需要更新一些变量,是系统能够找到你的程序,不然在控制台上输入就会说你没有安装

使用env命令可以显示环境变量

其中对我们安装有影响的包括:

  • PATH:这个参数是一些用:分割的路径,什么作用呢?当我们在终端中输入一个命令之后,系统会在这些路径当中根据这个命令查找对应的程序。可以使用export PATH=/opt/PROJECT/:$PATH来添加路径
  • LD_LIBRARY_PATH:顾名思义,这个是库文件的PATH,也可是使用相同的方法来添加。但有时不使用它而是使用ldconfig(动态库管理命令)
  • CFLAGS:指定C编译器使用的flag,像:预处理指令如-IPREFIX/include,或编译标志。自定义的CFLAGS使用源码包指定的编译系统。有些编译系统允许指定配置选项-extra-cflags。
  • LDFLAGS:指定linker使用的指令,通常包括链接指令,如-LPREFIX/lib(用于查找自定义路径中安装的库)。自定义的LDFLAGS作用于源码包指定的编译系统。或者,许多编译系统允许指定configure选项-extra-ldflags。
  • PKG_CONFIG_PATH:包含一些使用:分割的路径。许多编译系统使用pkg-config来获取作用在特定的库中的CFLAGS/LDFLAGS,这些flags包含在这些路径中的pkg-config文件里。

安装到非常规的位置或者./configure依赖于其他的动态库、头文件或者工具时,都要更新上述变量

环境变量通常存放在profile文件中。例如:用户文件夹下的.profile或者/etc/profile。可以编辑这些文件永久改变环境变量,或者使用脚本或者终端修改。

导出环境变量到子进程,可以使用export命令。更多内容请查看帮助文档。

LD_LIBRARY_PATH 和 ldconfig

当你在链接一个依赖于其他的库的库文件时,它会在系统设置的路径下和一个自定义的路径列表中查找这个依赖的库文件。有些系统使用LD_LIBRARY_PATH制定这个路径列表。当然我们也可以自己用ldconfig工具设置绝对路径,其实它编辑了/etc/ld.so.conf文件

请注意,在某些系统上,出于安全原因,shell配置文件中定义的LD_LIBRARY_PATH变量被重置了。因此可能需要重新设置每个会话或每个脚本。

配置的要求和发布版

当配置一个包时,需要检测依赖的库和头文件是否存在。很多发行版会提供所欲要库文件的二进制安装包,这样你就不会全都从头编译安装了。

一般来讲,对于一个库,可能需要这个库包和相对应的开发包。库包之中仅包含库,开发包中包含依赖于这个库的其它包在编译时需要的各种文件,像头文件和其他文件啥的。Debian的发布系中开发包使用-dev后缀,在RedHat发布系中使用-devel后缀,在Arch Linux中库包不分开包含着这两个包。

例如,在Debian发布系中,如果你要使用--enable-libmp3lame参数配置ffmpeg以支持mp3的编解码,那你就需要安装libmp3lame-dev的包

你还需要确认系统提供的库包与配置源码包所需的版本是兼容的。当所需的库包版本比提供的要新,那可能需要使用源码安装新的版本

安装后故障排除

首先确认二进制文件,头文件和库是否都在要安装到的位置了。然后验证命令是否可以执行,使用which -a加命令的名字获取命令安装到路径。

为了避免冲突,要小心不要多次安装相同的包