Skip to content

从源码安装软件

Linux 的优势之一就是提供了全的软件仓库,可以使用内置的软件包管理工具来一键安装。但是有时候我们还是需要从源码来安装应用程序。

获取源码

对于开源项目,通常都会在其官网或者 github 等代码管理上下载源码。以 nodejs 8.1.1 这个不存在于 Debian 仓库的老版本为例:

Bash
wget https://github.com/nodejs/node/archive/v8.1.1.zip
unzip v8.1.1.zip
cd node-8.1.1/

# git clone 存储库也是一个好的选择
git clone --depth 1 \
              --branch v8.1.1 \
              https://github.com/nodejs/node

cd node/

源码文件中通常会提供一个 README 文件来介绍如何安装,并且还会提供一个 Makefile configure 等编译相关的文件:

nodejs folder

构建系统

编译是一个复杂的并且需要前后呼应的过程,这就需要一种方式来自动化阐述这些不同的编译任务如何有机的组合在一起,这就是构建系统(build system)。构建系统有非常多,不过在 Linux 中有一个广泛使用的标准GUN-style build system。编写和适配构建系统是一个非常复杂的任务,但是对于最终用户来说无非就是三步:

  1. configure: 特性于项目的脚本,用来检查目标系统配置和可用功能,以确保可用构建项目
  2. make: 运行Makefile文件,其中会利用 gcc 将源码编译为目标文件,目标文件通过于函数库连接来生成最终的可执行文件
  3. make install: make 后的结果并没有被安装到预定目录,而仍然在当前编译目录下(通常是 build 文件夹内),只有执行make install会根据 Makefile 中关于 install 的项目将编译结果安装到预定目录中

还有一种 cmake 构建系统,他不需要 configure 脚本,而是有 CMakeLists.txt 来作为配置脚本。并且他们大多提供了 make 的兼容层,只需要运行 make 命令即可构建

configure

configure 本质上就是一个脚本,他特定于项目自身。他也提供了一些配置项来定义编译的行为,而且这也是特定于项目的。不过GNU Autotools规定了一些必须支持的选项,其中比较重要的就是 --prefix path 他指定编译好的二进制程序需要被安装到的位置。

程序默认位于/usr/local目录下,其中运行程序放置到/user/local/bin中,依赖库放置到/usr/local/lib,而其他独立于体系结构的文件放置到/usr/local/share中,当然配置也会放置到/etc下。

上面的默认行为通常不会对系统造成什么问题,但是你很难精确的知道那些文件属于哪一个软件,这在需要卸载软件时就造成了很大的困扰,因此更推荐的做法是将他们统一安装到/opt目录下:

Bash
# 这里的软链接是一个非常实用的小技巧
sudo mkdir /opt/node-v8.1.1
sudo ln -sT /opt/node-v8.1.1 /opt/node

./configure --prefix=/opt/node-v8.1.1

make & make install

make 会自动读取Makefile来真正的编译项目:

Bash
make

# 也可以多进程编译
make -j9

编译完成后能够在源码目录中看到编译的结果,对于非 root 权限的用户来说这就可用直接使用了。

但是对于需要全部用户可用时,还需要将他们安装到指定目录(configure --prefix指定):

Bash
sudo make install

测试安装结果:

Bash
sh$ /opt/node/bin/node --version
v8.1.1

通常还需要将/opt/node/bin添加到 PATH 中,或者在/usr/local/bin中创建他的符号连接

这种安装下的卸载就非常简单:

Bash
sudo rm -rf /opt/node-v8.1.1

依赖

依赖分为编译依赖和包依赖。

编译依赖

上面的构建过程中需要用到 make 命令通常并不是内置的需要我们自行安装,还有 make 执行脚本会调用对应的编译器来编译源码,因此对应的编译器也需要安装:

Bash
# debian
sudo  apt install make gcc

# redhat
sudo dnf install make gcc

大多数发行版都会将源码编辑以元包(meta packages)的形式发布,他们集合了用于编译软件的全部典型工具:

Bash
# debian
sudo apt install build-essential

# rethat
sudo dnf groupinstall "Development Tools"

# arch
sudo pacman -S base-devel

包依赖

源码安装最麻烦的地方就是包依赖,通常是一些非内置的函数库。此时就需要读取源码目录中的BUILD.md等文件来查看需要的依赖,首先安装他们。

还有一些就是操作系统存在的函数库无法满足依赖要求。这种情况是最可怕的,通常就是安装低版本或者通过特殊方法来维护多个版本的函数库。

参考