所谓的
Tarball
文件,就是将软件的所有原始码文件先以tar
打包,然后再以压缩技术来压缩。
Tarball
文件通常是通过tar
和gzip
来打包压缩,所以扩展名会写成*.tar.gz
或*.tgz
。不过,之后由于bzip2
和xz
的压缩率较佳,所以Tarball
渐渐的以bzip
或xz
的压缩技术来取代gzip
,所以档名会变成*.tar.bz2
、*.tar.xz
之类的。Tarball
是一个软件包,加压后,会看到里面通常包含以下文件:
gcc
是Linux上最标准的编译程序。下面是该命令的一些简易用法。
# 仅将原始码编译为目标文件,并不制作连接等功能
[root@instance-d619ad0f ~]# gcc -c hello.c
# 在编译的时候,依据作业环境基于优化执行速度
[root@instance-d619ad0f ~]# gcc -O hello.c -c
# 会自动产生hello.owenjian,并进行优化
# 在进行 binary file 制作时,将连接的函数库与相关路径填入
[root@instance-d619ad0f ~]# gcc sin.c lm -L/lib -I/user/include
# 这个指令较常下达在最终连结成binary file 的时候
# -lm 指的是 libm.so 或 libm.a 这个函数库文件
# -L 后面接的是路径,刚刚上面那个函数库的搜寻目录
# -I 后面接的是原始码内的 include 文件所在目录
# 将编译的结果输出成某个特定的档名
[root@instance-d619ad0f ~]# gcc -o hello hello.c
# -o 后面接的是要输出的 binary file 文件名
# 编译的时候,输出较多的讯息说明
[root@instance-d619ad0f ~]# gcc -o hello hello.c -Wall
# 加入 -Wall 后,程序的编译会变的较为严谨一点,所以警告讯息也会显示出来
当原始码文件非常多时,我们直接用gcc
进行编译连接会非常麻烦,而且如果修改了原始码的某个代码,重新编译也非常麻烦。所以我们可以用make
来进行宏编译,这样可以节省好多成本。以下是一个简单的案例,共有main.c
、haha.c
、sin_value.c
、cos_value.c
四个文件,先直接用gcc
进行编译连接。
# gcc进行编译连接
[root@instance-d619ad0f ~]# gcc -c main.c haha.c sin_value.c cos_value.c
[root@instance-d619ad0f ~]# gcc -o main main.o haha.o sin_value.o cos_value.o -lm
[root@instance-d619ad0f ~]# ./main
Please input your name: xiaobai
Please enter the degree angle (ex> 90): 135
Hi, Dear xiaobai, nice to meet you.
The Sin is: 0.71
The Cos is: -0.71
目前只有4个原始码文件,直接用gcc
编译就感觉比较麻烦了。如果代码有修改,那又要重新编译,重新执行一遍以上的动作;如果原始码文件更多,有几十个或者几百个,那操作起来就更加麻烦了。此时,我们可以使用make
来简化整个过程。
# 编辑 makefile 文件
[root@instance-d619ad0f ~]# vim makefile
main: main.o haha.o sin_value.o cos_value.o
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
# 通过 makefile 进行编译行为
[root@instance-d619ad0f ~]# rm -f main *.o
[root@instance-d619ad0f ~]# make
cc -c -o main.o main.c
cc -c -o haha.o haha.c
cc -c -o sin_value.o sin_value.c
cc -c -o cos_value.o cos_value.c
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
[root@instance-d619ad0f ~]# make
make: `main' is up to date.
通过上面的例子我们可以知道,只要编辑好makefile
文件,我们就可以简单的进行编译连接操作。当然,我们可以写个shell
脚本,把所有的动作都集结在一起,也可以实现类似的效果。如果是shell
脚本,我们需要在脚本里加入编译动作的相关命令;而makefile
更方便,我们只需要写出main
需要的目标文件,make
会主动去判断每个目标文件相关的原始码文件,并直接予以编译,最后再直接进行连接动作。此外,如果修改过某个原始码文件,则make
会主动判断哪个原始码与相关的目标文件有更新过,并只更新该文件。总的来说,make
有以下这些优点:
make
仅会针对被修改了的文件进行编译,其他的object file(目标文件)
不会被改动make
的语法相当多而复杂,基本的Makefile
规则是这样的:
makefile
当中的#
代表注释
需要在命令行的第一个字符:
隔开目标(target): 目标文件1 目标文件2
<tab>gcc -o 欲建立的执行文件 目标文件1 目标文件2
如果我们希望在以上make宏编译基础上,再添加一个操作:清楚所有的目标文件和执行文件,我们可以如下编辑makefile
文件。
[root@instance-d619ad0f ~]# vim makefile
main: main.o haha.o sin_value.o cos_value.o
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
clean:
rm -f main main.o haha.o sin_value.o cos_value.o
[root@instance-d619ad0f ~]# make clean
rm -f main main.o haha.o sin_value.o cos_value.o
[root@instance-d619ad0f ~]# make clean main
rm -f main main.o haha.o sin_value.o cos_value.o
cc -c -o main.o main.c
cc -c -o haha.o haha.c
cc -c -o sin_value.o sin_value.c
cc -c -o cos_value.o cos_value.c
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
如上编辑makefile
文件,则makefile
就有两个操作,分别是main
和clean
。如果我们想要建立main
,则要输入make main
;如果要清除,则要输入make clean
;如果要先清除目标文件在编译,则要输入make clean main
。
此外,我们发现上面的makefile
文件有一部分数据重复编辑,且较长。我们可以通过设置变量来简化makefile
。
[root@instance-d619ad0f ~]# vim makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
main: ${OBJS}
gcc -o main ${OBJS} ${LIBS}
clean:
rm -f ${OBJS}
与bash shell script
相比,makefile
在语法上有以下特点:
=
隔开,同时等号两边可以有空格
=
两边不能有:
${VAR}
或$(VAR)
的形式gcc
在进行编译行为时,会主动读取CFLAGS
这个环境变量,所以我们可以直接在shell定义这个环境变量,也可以在makefile
文件里定义,也可以在指令列中直接使用。
# 以下这个动作在 make 进行编译时,会使用 CFLAGS 的变量内容
[root@instance-d619ad0f ~]# CFLAGS="-Wall" make clean main
# 以上等效于以下操作
[root@instance-d619ad0f ~]# vim makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
CFLAGS = -Wall
main: ${OBJS}
gcc -o main ${OBJS} ${LIBS}
clean:
rm -f ${OBJS}
[root@instance-d619ad0f ~]# make clean main
如果环境变量同名,环境变量的优先级如下:
make 指令列上加上的
> makefile 里指定的
> shell 本身的环境变量
此外,还有一个特殊变量$@
,代表当前的目标(target)。
Tarball
安装软件需要编译制作二进制文件,所以在安装软件之前,我们需要以下基础条件:
gcc
或cc
等编译器make
及autoconfig
等软件Library
以及相关的Include
文件Tarball
安装软件的基本步骤如下:
tarball
文件在/usr/local/src
目录下解压INSTALL
与README
等相关文件内容(很重要)INSTALL
/README
的内容查看并安装好一些关联的软件makefile
:以自动侦测程序(configure或config)侦测作业环境,并建立Makefile
文件make
这个程序并使用该目录下的Makefile
作为他的参数配置文件,来进行make(编译或其他)
操作make
这个程序,并以Makefile
这个参数配置文件,依据install这个目标(target)的指定来安装到正确路径大部分的Tarball
软件一般都是通过以下4个命令来进行软件安装,且必须要按顺序来,其中一个步骤失败,则无法进行后续的步骤。
./configure
→make clean
→make
→make install
./configure
:建立Makefile
文件,创建文件之前会检查系统环境及软件属性等make clean
:执行Makefile
中的clean
操作,Makefile
中不一定有,但执行一下也不会出错,这个步骤可以清理已经存在的目标文件make
:根据Makefile
执行编译,使原始码编译成可被执行的文件object files
,生成的可执行文件会放置在当前所在的目录下make install
:根据Makefile
中的install
操作,将上个步骤中编译好的文件安装到预定目录一般情况下,我们是将自己安装的软件放在/usr/local
下,原始码(Tarball)放在/usr/local/src
下。
下表是一般情况下Linux distribution
默认安装和Tarball
安装时,安装路径的比较(前提是Tarball安装在usr/local
)
Linux distribution | Tarball | |
---|---|---|
配置文件 | /etc | /usr/local/etc |
函数库 | /usr/lib | /usr/local/lib |
执行文件 | /usr/bin | /usr/local/bin |
联机帮助文档 | /usr/share/man | /usr/local/man |
如果打开usr/local
目录,我们会发现系统已经默认就有etc
、lib
、bin
、man
目录了。
我们如果将所有软件都安装在usr/local
下,看上去是结构非常清晰,非常规范,但是这样做,软件都混在一起了,之后想要升级或者删除会比较麻烦。所以我们可以在安装的时候单独创建一个目录,一个软件对应一个目录了。比如我们要装Apache,则我们可以把它装在/usr/local/apache
中,这样文件目录就会变成下面这样:
/usr/local/apache/etc
/usr/local/apache/bin
/usr/lcoal/apache/lib
/usr/local/apache/man
这样我们删除软件的时候,就只需要执行rm -rf /usr/local/apache
这个命令就可以了。当然,实际安装时还得参考安装软件的Makefile
文件中的install
信息。
一个软件对应一个目录,这样虽然利于后期的升级与删除,但系统环境变量PATH
肯定没有包含/usr/local/apache/bin
,所以安装好后如果不把/usr/local/apache/bin
路径添加到PATH
中,我们执行Apache的命令的时候就得使用绝对路径。另外,为了可以通过man
命令查看Apache的相关文档与命令,我们也要将/usr/local/apache/man
加入到MANPATH
环境变量中。
通过以上Apache的案例,我们Tarball
安装软件时,最好能遵循以下建议:
/usr/loca/src
中/usr/lcoal
目录下/usr/local
下的一个单独目录中bin
目录添加到PATH
中,将man
目录添加到MANPATH
中,方便后期的命令使用和文档查看。假设软件安装在/usr/local/software/
,则我们就要在/etc/man_db.conf
(CentOS7)中的加入一行MANPATH_MAP /usr/local/software/bin /usr/local/software/man
(40-50行左右处),这样就可以使用man
来查看相关文档。