2018-04-26 《鸟哥的Linux私房菜 基础学习篇(第四版)》 第21章 软件安装_原始码与Tarball 笔记

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-04-26 《鸟哥的Linux私房菜 基础学习篇(第四版)》 第21章 软件安装_原始码与Tarball 笔记相关的知识,希望对你有一定的参考价值。

一、什么是开放源码、编译程序与可执行文件
在 Linux 系统上面,一个文件能不能被执行看的是有没有可执行权限 (具有 x permission),不过,Linux 系统真正读懂的可执行的文件其实是二进制文件 ( binary program)。例如 /usr/bin/passwd, /bin/touch 这些个文件即为二进制程序代码。
1.1、名词定义:
? 开放源码:就是程序代码,写给人类看的程序语言,但机器并不认识,所以无法执行。如以 *.c 作为扩展名的C语言原始码文件。
? 编译程序:将程序代码转译成为机器看的懂得语言,就类似翻译者的角色。如以 *.o 作为扩展名的目标文件 (Object file)。
? 可执行文件:经过编译程序变成二进制程序后,机器看的懂所以可以执行的文件。此类型文件无后缀,在终端输入“路径/文件名”即为执行。
? 函式库:就类似子程序的角色,可以被呼叫来执行的一段功能函数。
.conf后缀的文件三config的缩写,配置文件的后缀。

二、编译程序的过程:
因为不同版本Linux distribution 核心所使用的系统呼叫可能不相同,而且每个软件所需要的相依的函式库也不相同。软件开发商要针对整个 Unix-Like做开发,而不仅针对 Linux 开发,所以它必须要侦测该操作系统平台有没有提供合适的编译程序。通常软件开发商会写一支文件名为configure(或者是config)的侦测程序,它要侦测的数据一般如下:
    ? 是否有可以编译本软件程序代码的编译程序。
    ? 是否有本软件所需要的函式库,或其他需要的相依软件。
    ? 操作系统平台是否适合本软件,比如Linux 的核心版本是否符合要求。
    ? 核心的表头定义文件 (header include) 是否存在 (驱动程序必须要的侦测)。
侦测符合要求则建立Makefile(or makefile)文件,此makefiel文件内容是原始码如何编译的详细信息。
make 命令进行编译,它将简化编译过程的命令。make执行时,在当前的目录下搜寻 Makefile文件, 依据此Makefile文件判别原始码是否经过变动,若有变动则执行更新文件。
2.1、同一套软件要在不同的平台上面执行时, 必须要重新编译。因为不同的 Linux distribution 的以下信息可能不一样:
1、函式库文件所放置的路径
2、函式库的文件名订定
3、预设安装的编译程序
4、核心的版本


命令:
file 路径/文件名        #查看文件是否为binary:
1、是 binary 而且是可以执行的时候,执行结果会显示执行文件类别 (ELF 64-bit LSBexecutable), 同时说明是否使用动态函式库 (shared libs)。
2、是一般的 script ,执行结果会显示 text executables 之类的字样。


gcc [选项] 目录/文件名    #将源码编译为编译程序。
C语言源码文件中只要加上“include <math.h>”,gcc 命令会主动将函数抓进来给你。
选项:
空    :跳过生成编译文件步骤,将文件在当前目录下直接生成文件名为a.out的可执行文件。若a.out已存在则覆盖掉之前的a.out文件。
-c    :对C 源程序,预处理, 编译, 汇编
-o    :目标文件 (Object file)被传递 给 连接器(linker)
-O    :优化
-Wall    :显示更详细的编译过程信息。显示的警告讯息 (warning) 可以不用理会。
-lm    :加入libm.so函式库。l:加入某个函式库(library)”,lab的简写。m:libm.so函式库的简写,其中lib 与扩展名(.so或.a)省略了。
-L/path :到目录下搜索l参数对应的函式库。,由于 Linux 预设是将函式库放置在 /lib 与 /lib64 当中,所以-L/lib 与 -L/lib64 写与不写没有影响。
I/path :定义C语言源码文件头部中要读取的 include 文件放置的目录
-I/path :在后面接的路径( Path )下,寻找C语言源码文件头部中定义的 include 文件。include 文件默认是放置在 /usr/include 目录下面,除非 include 文件放置到其他路径,否则略过此选项。

实例:
[[email protected] ~]# gcc hello.c            #将hello.cC语言原始码文件编译、生成为默认文件名为a.out的可执行文件。

[[email protected] ~]# gcc -c hello.c                #将hello.cC语言原始码文件编译、生成文件名为hello.o的目标文件
[[email protected] ~]# gcc -o hello hello.o            #将hello.o编译文件编译、生成文件名为hello的可执行文件

[[email protected] ~]# gcc -c thanks.c thanks_2.c        #将thanks.c、thanks_2.cC语言原始码文件编译、生成文件名为thanks.o、thanks_2.o的2个目标文件
[[email protected] ~]# gcc -o thanks thanks.o thanks_2.o    #将thanks.o thanks_2.o目标文件编译、生成文件名为thanks的1个可执行文件

[[email protected] ~]# gcc -O -c thanks.c thanks_2.c
[[email protected] ~]# gcc -Wall -c thanks.c thanks_2.c

[[email protected] ~]# gcc sin.c -lm -L/lib -L/lib64    #要的函式库 libm.so 请到 /lib 或 /lib64 里面搜寻

[[email protected] ~]# gcc sin.c -lm -I/usr/include    #C语言源码文件当中第一行“ #include <stdio.h>”,说的是要将一些定义数据由 stdio.h 这个文件读入,这包括 printf 的相关设定。这个文件是放在 /usr/include/stdio.h,那么万一这个文件并非放置这里时,使用此方式


make命令
实例
# 1. 先编辑 makefile 这个规则文件
[[email protected] ~]# vi makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
CFLAGS = -Wall
main: ${OBJS}
    gcc -o [email protected] ${OBJS} ${LIBS}    <[email protected] 就是 main
clean:
    rm -f main ${OBJS}

# 2. 以目标clean、main测试看看执行 make 的结果
[[email protected] ~]# make clean
[[email protected] ~]# make main
[[email protected] ~]# make clean main
[[email protected] ~]# CFLAGS="-Wall" make clean main    #执行makefile文件内的gcc命令时,会添加上CFLAGS变量的内容作为参数。

makefile文件格式:
    目标(target): 目标文件 1 目标文件 2
    <tab> gcc -o 欲建立的执行文件 目标文件 1 目标文件 2
? 在 makefile 当中的 # 代表批注。
? <tab> 需要在命令行 (例如 gcc 这个编译程序命令) 的第一个字符。
? 目标 (target) 与相依文件(就是目标文件)之间需以“:”隔开。

makefile文件的变量语法与 bash shell script 的语法有点不太相同:
1. 变量与变量内容以“=”隔开,同时两边可以具有空格。
2. 变量左边不可以有 <tab> ,例如上面范例的第一行 LIBS 左边不可以是 <tab>。
3. 变量与变量内容在“=”两边不能具有“:”。
4. 在习惯上,变数最好是以“大写字母”为主。
5. 运用变量时,以 ${变量} 或 $(变量) 使用。
6. 在命令列模式也可以给予变量。
7. 在该 shell 的环境变量是可以被套用的,例如实例中的CFLAGS = -Wall。
8. “[email protected]”代表目前的目标(target)

环境变量取用的优先级别:
1. make 命令列后面加上的环境变量为优先;
2. makefile 里面指定的环境变量第二;
3. shell 原本具有的环境变量第三。

make 命令的好处:
? 简化编译时所需要下达的命令。
? 在编译完成之后某个原始码文件进行再次修改,则 make 仅会针对被修改了的文件进行编译,其他的 object file不会被更动。
? 依照相依性来更新 (update) 执行文件。



三、Tarball 软件
将软件的所有原始码文件先打包,然后再以压缩技术来压缩,就形成了一个Tarball软件包。
? 利用 tar 打包功能与 gzip 压缩功能的tarball 文件的扩展名为 *.tar.gz 或 *.tgz 简写。
? 利用 bzip2 与 xz 压缩的tarball 文件的扩展名为 *.tar.bz2, *.tar.xz 。
? 近来由于 bzip2 与 xz 的压缩率较佳,所以 Tarball渐渐的以 bzip2 及 xz 的压缩技术来取代 gzip。
Tarball软件包里面的文件通常有:
? 源代码文件;
? 侦测程序文件 (可能是 configure 或 config 等文件名);
? 本软件的简易说明与安装说明 (INSTALL 或 README)。

一个Tarball 软件安装流程(gcc方式):
1. 将 Tarball 由厂商的网页下载下来;
2. 将 Tarball 解开,产生很多的原始码文件;
3. 开始以 gcc 进行原始码的编译 (会产生目标文件 object files);
4. 然后以 gcc 进行函式库、主、子程序的链接,以形成主要的 binary file;
5. 将上述的 binary file 以及相关的配置文件安装至自己的主机上面。
第3、4步骤可用make命令简化

Tarball 软件安装的基本步骤(make方式):
1. 取得原始文件:将 tarball 文件在 /usr/local/src 目录下解压缩;
2. 取得步骤流程:进入新建立的目录底下,去查阅 INSTALL 与 README 等相关文件内容 (很重要的步骤! );
3. 相依属性软件安装:根据 INSTALL/README 的内容察看并安装好一些相依的软件 (非必要);
4. 建立 makefile:以自动侦测程序 (configure 或 config) 侦测作业环境,并建立 Makefile 这个文件;
5. 编译:以 make 这个程序并使用该目录下的 Makefile 做为他的参数配置文件,来进行 make (编译或其他)的动作;
6. 安装:以 make 这个程序,并以 Makefile 这个参数配置文件,依据 install 这个目标 (target) 的指定来安装到正确的路径。

tarball 软件安装的命令顺序:
1. ./configure
建立 Makefile 文件。通常程序开发者会写一支 scripts 来检查你的 Linux 系统、相关的软件属性等等,这个步骤相当的重要, 因为未来你的安装信息都是这一步骤内完成的!另外,这个步骤的相关信息应该要参考一下该目录下的 README 或 INSTALL 相关的文件。
2. make clean
make 命令会读取 Makefile 中关于 clean 的工作。这个步骤不一定会有,但是希望执行一下,因为他可以去除目标文件!因为谁也不确定原始码里面到底有没有包含上次编译过的目标文件 (*.o) 存在,所以当然还是清除一下比较妥当的。 至少等一下新编译出来的执行文件我们可以确定是使用自己的机器所编译完成的。
3. make
make 命令会依据 Makefile 当中的预设工作进行编译的行为。编译的工作主要是进行 gcc 来将原始码编译成为可以被执行的 object files ,但是这些 object files 通常还需要一些函式库之类的 link 后,才能产生一个完整的执行档。使用 make 就是要将原始码编译成为可以被执行的可执行文件,而这个可执行文件会放置在目前所在的目录之下, 尚未被安装到预定安装的目录中;
4. make install
通常这是最后的安装步骤,make 会依据 Makefile 这个文件里面关于 install 的项目,将上一个步骤所编译完成的数据给他安装到预定的目录中,就完成安装啦。
上面的步骤是一步一步来进行的,而其中只要一个步骤无法成功,那么后续的步骤就完全没有办法进行的!

Linux distribution 默认安装软件的路径:
? /etc/httpd    配置文件
? /usr/lib        函式库
? /usr/bin        执行文件
? /usr/share/man    联机帮助文件

用户自行安装Tarball软件时的建议:
1. 将 tarball 的原始数据解压缩到 /usr/local/src (src 为 source 的缩写)当中。
2. 安装时,安装到 /usr/local 这个默认路径下。
3. 每个软件都会提供联机帮助的服务(info 与 man 功能),在默认的情况下, man 命令会去搜寻 /usr/local/man 目录下的说明文件, 因此,如果我们将软件安装在 /usr/local底下的话,那么自然安装完成之后, 该软件的说明文件就可以被找到了。但考虑卸载时的容易地追查文件的来源,还是将每个软件单独的安装在 /usr/local/software(对应的软件名)/ 目录下。
4. 为软件的man page 加入 man path 搜索参数。在/etc/man_db.conf 内的 40~50 行左右处,写入:“MANPATH_MAP /usr/local/software/bin /usr/local/software/man”,这样才可以使用 man 来查询该软件的在线文件!
5. 时至今日,真的不太需要有 tarball 的安装了!CentOS/Fedora 有个 RPM 补遗计划(或叫EPEL 计划),相关网址:https://fedoraproject.org/wiki/EPEL。有好心的网友帮我们打包好常用的软件,除了专属软件 (要钱的)软件或者是比较冷门的软件,一般学界会用到的软件都在里头。 ^_^

Tarball 软件升级更新的方法:
? 直接以原始码透过编译来安装与升级。直接以 Tarball 在自己的机器上面进行侦测、编译、安装与设定等动作。这样的动作让使用者在安装过程当中具有很高的弹性, 但是麻烦。
? 直接以编译好的 binary program 来安装与升级。Linux distribution 厂商针对自己的作业平台先进行编译等过程,再将编译好的binary program 释出,使用者的系统环境与该 Linux distribution 的环境相同的话,厂商所释出的binary program 就可以在使用者的机器上面直接安装!省略了侦测与编译等繁杂的过程。

更新原始码。使用diff与patch命令:
[[email protected] 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;
....(底下省略)....
[[email protected] main-0.1]# patch -p1 < ../main_0.1_to_0.2.patch




函式库的相关说明:
Linux 的核心提供很多的核心相关函式库与外部参数, 这些核心功能在设计硬件的驱动程序的时候是相当有用的信息,这些核心相关信息大多放置在/usr/include, /usr/lib, /usr/lib64 里面。



ldd [-vdr] [filename]        #判断某个可执行的 binary 文件含有什么动态函式库
选项与参数:
-v :列出所有内容信息。
-d :重新将资料有遗失的 link 点秀出来。
-r :将 ELF 有关的错误内容秀出来。

























































































































































































以上是关于2018-04-26 《鸟哥的Linux私房菜 基础学习篇(第四版)》 第21章 软件安装_原始码与Tarball 笔记的主要内容,如果未能解决你的问题,请参考以下文章

求鸟哥的linux私房菜全部视频教程 百度网盘资源

求鸟哥的linux私房菜全部视频教程 百度网盘资源

鸟哥的Linux私房菜-----10学习Bash

刘遄:读完《鸟哥的Linux私房菜》的感受。

2018-04-10 《鸟哥的Linux私房菜 基础学习篇(第四版)》 下载方式

鸟哥的Linux私房菜——第八章