source

从源码开始编译项目的一些通用说明

为什么从源码编译

二进制文件通常由第三方打包程序提供,但在某些情况下,由于以下几个原因,它们不是一种选择:

  • 二进制文件已过时或包含严重错误或缺少软件更高版本中提供的必需功能。
  • 你需要自定义构建,例如以支持特定的安装布局、获取特定于平台的优化或链接到二进制包中不支持的特定库。
  • 你想通过编辑源码来定制软件

在所有这些情况下,从源码构建看起来是最好的解决方案。

概述

大多数源码的安装都假定以下步骤:

  • 配置 (使用配置脚本, configure
  • 编译 (使用 make
  • 安装 (使用 make install

配置可以创建下一步编译所需的文件,通常通过源软件包提供的 configure 脚本完成。
在配置过程中,可以定义安装前缀和启用的组件。

编译通常包括在配置步骤完成后运行 make
在此阶段会生成所需的库和二进制文件。

安装将在配置步骤中指定的路径中安装二进制文件和库。
请注意,此步骤实际上不是必需的,因为您可以使用编译路径中编译的二进制文件。

对于原始编译和安装,通常会运行以下命令:

1
2
3
./configure
make
make install

这将编译源码目录中的项目文件,并将库安装到 /usr/local
第三步可能需要管理员权限(因此可能需要用 sudo make install 代替),因为普通用户无法修改 /usr/local

安装路径

一个软件包由多个相关文件组成,这些文件被安装在多个文件夹中。
配置步骤通常允许用户指定所谓的安装前缀,通常通过 configure 选项 configure --prefix=PREFIX 指定,其中 PREFIX 通常默认为 /usr/local
前缀指定安装所有组件的公共文件夹。

安装中通常会涉及以下文件夹:

  • PREFIX/bin 包含生成的可执行文件
  • PREFIX/include 包含库的头文件
  • PREFIX/lib 包含生成的库
  • PREFIX/share 包含各种独立于系统的组件;特别是文档文件和示例

通过指定前缀可以自定义安装文件夹。

通过使用像 /usr/local/ 这样的共享前缀,不同的包将安装在同一文件夹中,因此通常还原安装会更加困难。

使用 /opt/PROJECT/ 这样的前缀,项目将被安装在一个专用目录中,要从系统中移除,只需移除 /opt/PREFIX 路径即可。
另一方面,这种安装方式需要编辑所有环境变量,使其指向自定义路径。

环境变量

环境中定义的几个变量会影响软件包的安装。
特别是,根据您的安装前缀,您可能需要更新其中一些变量,以确保系统工具能找到安装的组件。

可以通过命令 env 显示环境变量列表。

受影响变量的列表如下:

  • PATH 定义系统查找可执行文件的文件夹,使用 : 分隔路径列表。
    例如,将可执行文件安装在了 /usr/local ,需要 export PATH=/usr/local/bin:$PATH 来添加该路径(一般来说系统都会包含该路径)。
  • LD_LIBRARY_PATH 定义系统查找库的文件夹,使用 : 分隔路径列表。
    有时候不推荐使用此变量,而改用 ldconfig
  • CFLAGS 包含 C 编译器使用的标志,通常包括预处理指令(如 -IPREFIX/include )或编译标志。
    自定义 CFLAGS 通常由源包构建系统作为源包编译器标志的前缀。
    或者,许多构建系统允许指定配置选项 -extra-cflags
  • LDFLAGS 这些是链接器使用的指令,通常包括查找安装在自定义路径中的库所需的链接指令(如 -LPREFIX/lib )。
    自定义 LDFLAGS 通常由源包构建系统作为源包链接器标志的前缀。
    或者,许多构建系统允许指定配置选项 -extra-ldflags
  • PKG_CONFIG_PATH 包含 pkg-config 使用的 : 分隔路径,用于检测许多构建系统使用的 pkg-config 文件,以检测特定库使用的自定义 CFLAGS/LDFLAGS

如果软件包安装在非标准路径下,则需要更新这些环境库,以便系统工具能够检测到软件包组件。
当运行依赖于其他已安装库/头文件/工具的软件包的配置脚本时,尤其需要这样做。

环境变量通常在配置文件中定义,例如在 sh/bash 用户的用户文件夹和 /etc/profile 中定义的 .profile
可以通过编辑该文件来永久设置自定义环境。
或者,也可以在脚本或特定 shell 会话中设置变量。

记得将变量导出到子进程,例如使用 export 命令。

LD_LIBRARY_PATH 和 ldconfig

当您链接依赖于其他库的库时,工具将在标准路径列表(通常为 /usr/lib )和系统中设置的其他路径中查找要链接的库。
一些系统依赖于 LD_LIBRARY_PATH 库。
或者,你可以通过 ldconfig 程序设置全局路径,该程序通过编辑 /etc/ld.so.conf 系统配置文件完成。

配置前提条件和分发包

配置软件包时,可能需要检查是否存在某些必需的库和头文件。
许多发行版会为所需库提供二进制软件包,因此您可以依赖这些软件包,而不必从头开始编译和安装。

一般来说,对于一个库,你需要与该库相关的库包和开发包。
库包只包含库,开发包还包含头文件和其他文件,这些文件是编译依赖于这些库的软件包所必需的。
在基于 Debian 的发行版系统中,开发包的后缀是 -dev,而在基于 RedHat 的发行版系统中,开发包的后缀是 -devel。
有些发行版(如 Arch Linux)并不将软件包分开,标准软件包也包含必要的开发文件。

例如在 Debian 上,如果您想使用 --enable-libmp3lame 配置 FFmpeg,则需要安装名为 libmp3lame-devlibmp3lame 开发包。

你还应确保发行版提供的库版本与配置的源码包所需的版本兼容。
如果所需的软件包比发行版提供的库版本更新,则可能需要从源码安装。

安装后故障排除

首先要确认二进制文件、头文件和库是否已安装到指定位置(沿 PREFIX 路径)。
要验证二进制文件的安装情况,只需运行一个包含工具名称的命令,然后用 which -a 命令验证完整路径,系统中所有包含给定名称的工具都会显示出来。

如果您安装多个相同的包,则必须格外小心,以避免发生冲突。