使用原始码管理软件所需要的基础软件
从原始码的说明我们晓得要制作一个 binary program 需要很多咚咚的呢!这包括底下这些基础的软件:
gcc 或 cc 等 C 语言编译程序 (compiler):
make 及 autoconfig 等软件:
需要 Kernel 提供的 Library 以及相关的 Include 文件:
在 CentOS 当中,如果你已经有网络可以连上 Internet 的话,透过 yum 的软件群组安装功能,你可以这样做:
- 如果是要安装 gcc 等软件开发工具,请使用『 yum groupinstall "Development Tools" 』
- 若待安装的软件需要图形接口支持,一般还需要『 yum groupinstall "X Software Development" 』
- 若安装的软件较旧,可能需要『 yum groupinstall "Legacy Software Development" 』
Tarball 安装的基本步骤
整个安装的基础动作大 多是这样的:
- 取得原始档:将 tarball 文件在 /usr/local/src 目录下解压缩
- 取得步骤流程:进入新建立的目录底下,去查阅 INSTALL 与 README 等相关文件内容 (很重要的步骤!);
- 相依属性软件安装:根据 INSTALL/README 的内容察看并安装好一些相依的软件 (非必要);
- 建立 makefile:以自动侦测程序 (configure 或 config) 侦测作业环境,并建立 Makefile 这个文件;
- 编译:以 make 这个程序并使用该目录下的 Makefile 做为他的参数配置文件,来进行 make (编译或其他) 的动作;
- 安装:以 make 这个程序,并以 Makefile 这个参数配置文件,依据 install 这个目标 (target) 的指定来安 装到正确的路径!
makefile 在制作出来之后,里头会有相当多的目标 (target),最常见的就是 install 与 clean 啰!通常『make clean』代表着将目标文件 (object file) 清除掉,『make』则是将原始码进行编译而已。
tarball 软件之安装的指令下达方式:
- ./configure
这个步骤就是在建立 Makefile 这个文件啰!通常程序开发者会写一支 scripts 来检查你的 Linux 系统、相 关的软件属性等等,这个步骤相当的重要, 因为未来你的安装信息都是这一步骤内完成的!另外,这个步骤的相关信息应该要参考一下该目录下的 README 或 INSTALL 相关的文件!
- make clean
make 会读取 Makefile 中关于 clean 的工作。这个步骤不一定会有,但是希望执行一下,因为他可以去除 目标文件!
- make
make 会依据 Makefile 当中的预设工作进行编译的行为!编译的工作主要是进行 gcc 来将原始码编译成为 可以被执行的 object files ,但是这些 object files 通常还需要一些函式库之类的 link 后,才能产生一个完 整的执行档!使用 make 就是要将原始码编译成为可以被执行的可执行文件,而这个可执行文件会放置在 目前所在的目录之下, 尚未被安装到预定安装的目录中;
- make install
通常这就是最后的安装步骤了,make 会依据 Makefile 这个文件里面关于 install 的项目,将上一个步骤所 编译完成的数据给他安装到预定的目录中,就完成安装啦!
请注意,上面的步骤是一步一步来进行的,而其中只要一个步骤无法成功,那么后续的步骤就完全没 有办法进行的!
一般 Tarball 软件安装的建议事项 (如何移除?升级?)
Linux distribution 释出安装的软件大多是在 /usr 里面的,而 用户自行安装的软件则建议放置在 /usr/local 里面。这是考虑到管理用户所安装软件的便利性。
通常我们会建议大家将自己安装的软件放置在 /usr/local 下,至于原始码 (Tarball)则建议放 置在 /usr/local/src (src 为 source 的缩写)底下啊。
再来,让我们先来看一看 Linux distribution 默认的安装软件的路径会用到哪些?
我们以 apache 这个软件来说明
- /etc/httpd
- /usr/lib
- /usr/bin
- /usr/share/man
我们会发现软件的内容大致上是摆在 etc, lib, bin, man 等目录当中,分别代表『配置文件、函式库、 执行档、联机帮助档』。那么你是以 tarball 来安装时呢?如果是放在预设的 /usr/local 里面, 由于 /usr/local 原本就默认这几个目录了,所以你的数据就会被放在:
- /usr/local/etc
- /usr/local/bin
- /usr/local/lib
- /usr/local/man
但是如果你每个软件都选择在这个默认的路径下安装的话, 那么所有的软件的文件都将放置在这四 个目录当中,因此,如果你都安装在这个目录下的话, 那么未来再想要升级或移除的时候,就会比 较难以追查文件的来源啰! 而如果你在安装的时候选择的是单独的目录,例如我将 apache 安装在 /usr/local/apache 当中,那么你的文件目录就会变成:
- /usr/local/apache/etc
- /usr/local/apache/bin
- /usr/local/apache/lib
- /usr/local/apache/man
呵呵!单一软件的文件都在同一个目录之下,那么要移除该软件就简单的多了! 只要将该目录移除 即可视为该软件已经被移除啰!以上面为例,我想要移除 apache 只要下达『rm -rf /usr/local/apache』 就算移除这个软件啦!
这个方式虽然有利于软件的移除,但不晓得你有没有发现,我们在执行某些指令的时候,与该指令是 否在 PATH 这个环境变量所记录的路径有关,以上面为例,我的 /usr/local/apache/bin 肯定是不在 PATH 里面的,所以执行 apache 的指令就得要利用绝对路径了,否则就得将这个 /usr/local/apache/bin 加入 PATH 里面。另外,那个 /usr/local/apache/man 也需要加入 man page 搜寻 的路径当中啊!
除此之外,Tarball 在升级的时候也是挺困扰的,我们还是以 apache 来说明好了。WWW 服务器为了考虑互动性,所以通常会将 PHP+MySQL+Apache 一起安装起来,果真如此的话,那么每个软件在安装的时候『都有一定的顺序与程序!』 因为他们 三者之间具有相关性,所以安装时必需要三者同时考虑到他们的函式库与相关的编译参数。
假设今天我只要升级 PHP 呢?有的时候因为只有涉及动态函式库的升级,那么我只要升级 PHP 即 可!其他的部分或许影响不大。但是如果今天 PHP 需要重新编译的模块比较多,那么可能会连带的, 连 Apache 这个程序也需要重新编译过才行!tarball 确实有他的优点啦,但是在这方面,确实也有他一定的伤脑筋程度。
由于 Tarball 在升级与安装上面具有这些特色,亦即 Tarball 在反安装上面具有比较高的难度 (如果 你没有好好规划的话~),所以,为了方便 Tarball 的管理,通常鸟哥会这样建议使用者:
- 最好将 tarball 的原始数据解压缩到 /usr/local/src 当中;
- 安装时,最好安装到 /usr/local 这个默认路径下;
- 考虑未来的反安装步骤,最好可以将每个软件单独的安装在 /usr/local 底下;
- 为安装到单独目录的软件之 man page 加入 man path 搜寻:
如果你安装的软件放置到 /usr/local/software/ ,那么 man page 搜寻的设定中,可能就得要在 /etc/man_db.conf 内的 40~50 行左右处,写入如下的一行:
MANPATH_MAP /usr/local/software/bin /usr/local/software/man
一个简单的范例、利用 ntp 来示范
假设我对这个软件的要求是这样的:
- 假设 ntp-4...tar.gz 这个文件放置在 /root 这个目录下;
- 原始码请解开在 /usr/local/src 底下;
- 我要安装到 /usr/local/ntp 这个目录中;
- 解压缩下载的 tarball ,并参阅 README/INSTALL 文件
[root@study ~]# cd /usr/local/src <==切换目录
[root@study src]# tar -zxvf /root/ntp-4.2.8p3.tar.gz <==解压缩到此目录 ntp-4.2.8p3/ <==会建立这个目录喔!
ntp-4.2.8p3/CommitLog
....(底下省略)....
[root@study src]# cd ntp-4.2.8p3
[root@study ntp-4.2.8p3]# vi INSTALL <==记得 README 也要看一下!
# 特别看一下 28 行到 54 行之间的安装简介!可以了解如何安装的流程喔!
- 检查 configure 支持参数,并实际建置 makefile 规则文件
[root@study ntp*]# ./configure --help | more <==查询可用的参数有哪些
--prefix=PREFIX install architecture-independent files in PREFIX
--enable-all-clocks + include all suitable non-PARSE clocks:
--enable-parse-clocks - include all suitable PARSE clocks:
# 上面列出的是比较重要的,或者是你可能需要的参数功能!
[root@study ntp*]# ./configure --prefix=/usr/local/ntp \
> --enable-all-clocks --enable-parse-clocks <==开始建立 makefile
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
....(中间省略)....
checking for gcc... gcc <==也有找到 gcc 编译程序了!
....(中间省略)....
config.status: creating Makefile <==现在知道这个重要性了吧?
config.status: creating config.h
config.status: creating evconfig-private.h
config.status: executing depfiles commands
config.status: executing libtool commands
一般来说 configure 设定参数较重要的就是那个 --prefix=/path 了,--prefix 后面接的路径就是『这个 软件未来要安装到那个目录去?』如果你没有指定 --prefix=/path 这个参数,通常预设参数就是 /usr/local 至于其他的参数意义就得要参考 ./configure --help 了! 这个动作完成之后会产生 makefile 或 Makefile 这个文件。当然啦,这个侦测检查的过程会显示在屏幕上,特别留意关于 gcc 的检查, 还有最重要的是最后需要成功的建立起 Makefile 才行!
- 最后开始编译与安装
[root@study ntp*]# make clean; make
[root@study ntp*]# make check
[root@study ntp*]# make install
# 将数据给他安装在 /usr/local/ntp 底下
利用 patch 更新原始码
所谓的『更新 原始码』常常是只有更改部分文件的小部分内容而已。既然如此的话, 那么我们是否可以就那些被 更动的文件来进行修改就可以咯?也就是说, 旧版本到新版本间没有更动过的文件就不要理他,仅 将有修订过的文件部分来处理即可。
这有什么好处呢?首先,没有更动过的文件的目标文件 (object file) 根本就不需要重新编译,而且有 更动过的文件又可以利用 make 来自动 update(更新),如此一来,我们原先的设定 (makefile 文件里 面的规则) 将不需要重新改写或侦测!可以节省很多宝贵的时间呢 (例如后续章节会提到的核心的编 译!)
从上面的说明当中,我们可以发现,如果可以将旧版的原始码数据改写成新版的版本, 那么就能直 接编译了,而不需要将全部的新版 Tarball 重新下载一次呢!那么如何改写 原始码?
那就是 diff,这个指令可以将『两 个文件之间的差异性列出来』呢!那我们也知道新旧版本的文件之间, 其实只有修改一些程序代码 而已,那么我们可以透过 diff 比对出新旧版本之间的文字差异,然后再以相关的指令来将旧版的文件更新吗? 呵呵!当然可以啦!那就是 patch 这个指令啦!很多的软件开发商在更新了原始码之后, 几乎都会释出所谓的 patch file,也就是直接将原始码 update 而已的一个方式喔!我们底下以一个简单的范例来说明给你了解喔!
这里我们来举个案例解释一下好了。假设我们刚刚计算三角函数的程 序 (main) 历经多次改版, 0.1 版仅会简单的输出, 0.2 版的输出就会含有角度值,因此这两个版 本的内容不相同。如下所示,两个文件的意义为:
- 测试旧版程序的功能
[root@study ~]# tar -zxvf main-0.1.tgz
[root@study ~]# cd main-0.1
[root@study main-0.1]# make clean main
[root@study main-0.1]# ./main
version 0.1
Please input your name: VBird
Please enter the degree angle (ex> 90): 45
Hi, Dear VBird, nice to meet you.
The Sin is: 0.71
The Cos is: 0.71
- 查阅 patch file 内容
[root@study main-0.1]# vim ~/main_0.1_to_0.2.patch
diff -Naur main-0.1/cos_value.c main-0.2/cos_value.c
--- main-0.1/cos_value.c 2015-09-04 14:46:59.200444001 +0800
+++ main-0.2/cos_value.c 2015-09-04 14:47:10.215444000 +0800
@@ -7,5 +7,5 @@
{
float value;
....(底下省略)....
上面表格内有个底线的部分,那代表使用 diff 去比较时,被比较的两个文件所在路径,这个路径非 常的重要喔! 因为 patch 的基本语法如下:
patch -p 数字 < patch_file
特别留意那个『 -p 数字』,那是与 patch_file 里面列出的文件名有关的信息。假如在 patch_file 第一行写的是这样:
*** /home/guest/example/expatch.old
那么当我下达『 patch -p0 < patch_file 』时,则更新的文件是『 /home/guest/example/expatch.old 』, 如果『 patch -p1 < patch_file』,则更新的文件为『home/guest/example/expatch.old』,如果『patch -p4 < patch_file』则更新『expatch.old』,也就是说, -pxx 那个 xx 代表『拿掉几个斜线(/)』的意思!这 样可以理解了吗? 好了,根据刚刚上头的资料,我们可以发现比较的文件是在 main-0.1/xxx 与 main-0.2/xxx ,所以说,如果你是在 main-0.1 底下,并且想要处理更新时,就得要拿掉一个目录 (因 为并没有 main-0.2 的目录存在, 我们是在当前的目录进行更新的!),因此使用的是 -p1 才对喔! 所以:
- 更新原始码,并且重新编译程序!
[root@study main-0.1]# patch -p1 < ../main_0.1_to_0.2.patch
patching file cos_value.c
patching file main.c
patching file Makefile
patching file sin_value.c
# 请注意,鸟哥目前所在目录是在 main-0.1 底下喔!注意与 patch 文件的相对路径!
# 虽然有五个文件,但其实只有四个文件有修改过喔!上面显示有改过的文件!
[root@study main-0.1]# make clean main
[root@study main-0.1]# ./main
version 0.2
Please input your name: VBird
Please enter the degree angle (ex> 90): 45
Hi, Dear VBird, nice to meet you.
The sin(45.000000) is: 0.71
The cos(45.000000) is: 0.71
# 你可以发现,输出的结果中版本变了,输出信息多了括号 () 喔!
[root@study main-0.1]# make install <==将他安装到 /usr/local/bin 给大家用
cp -a main /usr/local/bin
[root@study main-0.1]# main <==直接输入指令可执行!
[root@study main-0.1]# make uninstall <==移除此软件!
rm -f /usr/local/bin/main