基于源码的软件安装本质就是程序的源代码制作二进制程序的过程,这个过程中就会依赖一些基础软件和函数库来完成程序制作。这些依赖包括但不仅限于:
- gcc或者cc等C语言编译器;
- make、autoconfig等软件;
- 需要内核提供的Library以及相关的include文件;
通常情况下,基于源码的软件安装都会有固定以下的几个步骤,本篇博客将针对每个步骤中涉及到的知识点进行讲解:
- 去XX官网下载软件的Tarball文件;
- 上传到linux服务器,并解压缩;
- 检查软件安装依赖的软件或工具是否已安装;
- 检测操作环境、建立Makefile文件;
- 编译程序;
- 安装程序;
需要注意的是基于源码的安装是顺序执行的,简而言之就是一旦某一步没有执行成功,那么后续步骤是不会执行的。
可以大胆地说,只要吃透了这篇博客,linux操作系统下所有软件的安装都不是问题!
1、去XX官网下载软件的Tarball文件;
首先搞明白一点,基于源码的安装指的是利用厂商发布的Tarball文件来进行软件的安装,如下图所示的nginx和redis为例:
Tarball文件指的是将软件所有的源代码以tar打包,然后再以压缩技术来压缩(最为常见的以gzip来压缩而形成的文件,所以Tarball文件一般的扩展名就是*.tar.gz或者直接简写为*.tgz。近来由于bzip2与xz的压缩率表现较好,所以Tarball渐渐地以这两者来压缩,因此文件的扩展名也会是*.tar.bz2、*.tar.xz之类的;
Tarball文件通常包含以下内容:
- 源代码文件。毫无疑问编译程序用;
- 检测程序文件(可能是configure或config等文件)。这个文件一般有两个作用:检测操作环境是否满足编译安装软件的要求、建立Makefile文件;
- 软件的简易说明(README)或者安装文档(INSTALL);
2、上传到linux服务器,并解压缩;
默认情况下,用户自行安装的软件建议放置到/usr/local里面。而下载的Tarball文件建议放置到/usr/local/src下,在这个目录下进行解压缩;本次以nginx为例,涉及命令如下:
tar -zxvf nginx-1.20.1.tar.gz
在这一步骤中需要注意这两个放置目录;
3、检查软件安装依赖的软件或工具是否已安装;
这一步不是必须的,可根据步骤4中的检测内容进行确认!
4、检测操作环境、建立Makefile文件;
一般在软件开发商提供的Tarball文件中都会有一个检测程序,以nginx的Tarball文件为例,configure就是这个检测程序(二进制程序):
这个检测程序的检测内容大致如下:
- 是否有合适的编译器可以编译本软件的程序代码;比如gcc或cc等C语言编译器。
- 是否已经存在本软件所依赖的函数库或其它软件;比如make和autoconfig等软件。
- 操作系统平台是否适合本软件,包括Linux的内核版本;
- 内核的头文件(header include)是否存在(驱动程序必须要的检测);
不同的软件这个检测程序可能会有不同,但一般都会提供这么一个程序,大家具体问题具体分析即可;
那么我们可以通过执行以下程序进行检测。如果以上内容通过检测,那么会生成Makefile文件,这个文件将被步骤5的make程序用到;
# 执行检测程序,通过检测后创建Makefile
./configure --prefix=/usr/local/nginx
下面先来一个简单Makefile文件了解下,以下Makefile文件中包含两个目标(main和clean)。每个目标的第一行由英文冒号分隔,冒号左边是目标名称,冒号右边是依赖文件(非必要),即具有相关性的目标文件。第二行则为命令行,需要注意的是命令行必须以Tab键作为开头才可以:
main: main.o targetFile.o targetFile2.o targetFile3.o
gcc -o main main.o targetFile.o targetFile2.o targetFile3.o -lm
clean:
rm -f main main.o targetFile.o targetFile2.o targetFile3.o
经上述,可以大致归纳Makefile语法如下:
目标(target):目标文件1 目标文件2 ... 目标文件n
命令1
命令2
...
上述实例Makefile借助变量可以优化成如下所示,这个变量可以是shell的环境变量,可以是Makefile指定的环境变量,也可以是make命令行后面加的变量。稍微有些编程基础的应该对变量很熟悉,本次不做讲解:
LIBS = -lm
OBJS = main.o targetFile.o targetFile2.o targetFile3.o
CFLAGS = -WALL
main: ${OBJS}
gcc -o $@ ${OBJS} ${LIBS}
clean:
rm -f $@ ${OBJS}
另外附上nginx的通过configure程序生成的Makefile文件内容,加深下语法了解;另外以下内容中出现了两行以.PHONY开头的内容,.PHONY 后面跟的目标都被称为伪目标,也就是说我们 make 命令后面跟的参数如果出现在.PHONY 定义的伪目标中,那就直接在Makefile中就执行伪目标的依赖和命令。不管Makefile同级目录下是否有该伪目标同名的文件,即使有也不会产生冲突。另一个就是提高执行makefile时的效率。
default: build
clean:
rm -rf Makefile objs
.PHONY: default clean
build:
$(MAKE) -f objs/Makefile
install:
$(MAKE) -f objs/Makefile install
modules:
$(MAKE) -f objs/Makefile modules
upgrade:
/usr/local/nginx/sbin/nginx -t
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
sleep 1
test -f /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
.PHONY: build install modules upgrade
5、编译程序;
用make这个程序,并使用当前目录下的Makefile作为它的参数配置文件,来进行make(编译或其它)操作;使用命令如下:
make
其实make低层还是利用了gcc进行编译的操作,即源代码->目标文件->执行文件。但它的好处是:
简化编译时所需要执行的命令;
若在编译完成之后,修改了某个源代码文件,那么make只会针对被修改了的文件进行编译,其它的目标文件不会被修改;
可以依照依赖性来更新执行文件
6、安装程序;
通过执行以下命令来完成程序的安装;
make install
其本质就是会执行Makefile文件中的install目标中包含的命令选项,一般为将步骤5中编译完成的内容安装到预定的目录中。预定的目录可以在步骤4时设定,不设定时为默认安装到/usr/local中;