Linux下真正认识的可执行文件是二进制文件(binary program)。shell scripts其实是利用shell(如bash)的功能进行一些判断,最终的执行除了bash提供的功能外,仍然是呼叫一些已经编译好的二进制程序来执行。通过【file】指令可以对档案类型进行观察,如果是binary并且是可执行的时候,会显示类似"ELF 32-bit LSB executable"的字样,同时会说明是否使用动态函数库(shared libs);如果是一般的脚本,会显示"text executable"之类的字样
执行【make】指令时,make会在当前目录下寻找Makefile文件,其中记录了源代码应该如何编译的信息;make可以自动判别原始码是否经过变动而选择是否更新执行档。
通常软件开发商会写一支侦测程序来侦测用户的环境,以及该环境是否具有软件运行所需的其他功能;这支程序运行完成后,就会自动建立Makefile档案。通常侦测程序叫做configure或是config。一般侦测程序会侦测以下内容:
1. 是否有适合的编译程序可以编译本软件的源代码
2. 是否已经存在本软件所需的函数库或其他需要的软件
3. 操作系统是否适合本软件
4. 核心的头文件是否存在
所谓的Tarball档案,其实就是将软件所有的原始码先以tar打包,再进行压缩。软件Tarball的安装流程一般是:
1. 获取Tarball文件并进行解压
2. 将解压得到的源代码用gcc进行编译
3. 用gcc进行函数库、主程序、子程序的链接,得到二进制文件
4. 将二进制文件及相关的配置文件安装到自己的主机上
更新软件的方法有两种:(a) 直接用原始码通过编译进行安装升级;(b) 直接用编译好的二进制程序进行安装升级
gcc:
-O:进行优化
-c:编译源代码,但不链接
-o:后接文件名,表示产生最后的二进制文件名
-Wall:显示warning
-l:调用外部函数库
-L:调用函数库,后接函数库路径
-I:调用头文件,后接头文件路径
通常称"-Wall"和"-O"这些非必要的参数为旗标(FLAGS),因为是C语言,有时也简成为CFALGS
如果一个源代码调用了其他子程序文件,由于原始码档案包含多个文件,所以无法直接进行编译,要先【gcc -c main.c sub.c】生成目标文件,再用【gcc -o result man.o sub.o】进行链接生成最后名为的"result"二进制文件。如果更新了只更新了一个源代码文件(如sub.c),则可以只对它进行编译,再进行链接即可
例:gcc sin.c -lm [-L/lib -L/usr/lib] [-I/usr/include]
其中,"-l"表示加入某个函数库,"m"则表示使用的函数库是"libm.so",其中,"lib"和扩展名".so"(或".a")可以不写。因为Linux预设将函数库放在/lib和/usr/lib/下,所以中括号里的-L内容可以不写;如果要调用放在其他位置的函数库则必须要加"-L/路径"。头文件通常放在/usr/include/下,所以中括号中的-I内容可以省略;如果头文件放在其他位置,则必须要加"-I/路径"
make的优点:
1. 简化编译时下达的指令
2. 如果编译完成后修改了某个源代码档案,make会仅针对被修改的档案进行那个编译,其他档案的object file不会更改
3. 依照相依性来更新执行档
Makefile档案的语法:
(1)基本语法:
目标(target): 目标文件1 目标文件2 ...
<tab>gcc -o 欲建立的执行文件 目标文件1 目标文件2 ...
1. <tab>必须是命令行(如gcc编译指令)的第一个字符
2. 目标(target)与相依档案(就是目标文件)之间需要用冒号(":")隔开
3. 注释用"#"表示
4. 在一个Makefile文件中可以建立多个动作
例:
main: main.o sub1.o sub2.o
<tab>gcc -o main.o sub1.o sub2.o -lm
clean:
<tab>rm -f main main.o sub1.o sub2.o
一次下达指令可以执行一个或多个动作,如make clean main,或make clean
(2)变量:Makefile中可以使用变量,具体语法为:
1. 变量与变量内容用"="隔开,两边可以有空格
2. 变量左边不能有<tab>
3. 变量与变量内容在"="两边不能有":"
4. 一般使用大写字母表示变量
5. 调用变量时使用【${变量名}】或【$(变量名)】的格式
6. 当前shell的环境变量可以直接使用,例如CFLAGS。gcc在编译时会主动读取CFLAGS这个环境变量,所以可以在下达make指令时对其进行定义,也可以在Makefile中对其进行定义,如:CFLAGS="-Wall" make clean main
7. 指令列模式也可以给予变量
8. $@表示目前的目标(target)
例:vim Makefile
LIBS = -lm
OBJS = main.o sub1.o sub2.o
CFLAGS = -Wall
main: ${OBJS}
<tab>gcc -o $@ ${OBJS} ${LIBS}
clean:
<tab>rm -f main ${OBJS}
make各种环境变量的优先级是:
1. make指令列后面的环境变量优先级最高
2. Makefile中设定的环境变量其次
3. shell原有的环境变量优先级最低
Tarball安装的基本步骤
1. 取得Tarball档案并在/usr/local/src下解压
2. 阅读INSTALL与README文件的内容
3. 根据INSTALL/README文件的内容进行相依性软件安装
4. 使用自动侦测程序(configure或config)侦测作业环境并建立Makefile档案
5. 用make进行编译或其他动作
6. 参照Makefile用make进行安装
相关指令:
1. ./configure:建立Makefile档案。通常后接"--help"表示帮助;"--prefix=路径名"表示安装路径,若不加则安装到默认路径/usr/local下
2. make clean:这个指令不一定会有,但最好执行一下,因为可能存在以前编译过的目标文件(*.o)
3. make
4. make install
预设情况下Linux安装的软件大多在/usr下,而用户安装的软件建议放到/usr/local下。在预设的情况下,man会搜寻/usr/local/man中的说明文件,所以如果将软件安装到/usr/local下,则该软件的说明文件会自动被找到。Tarball原始码建议放到/usr/local/src下
安装用户软件时,在/usr/loca/下新建一个目录安装到新建目录中更方便管理,也方便软件的移除,但由于指令与环境变量PATH记录的路径有关,在执行新安装的指令时就不得不使用绝对路径,或者将指令所在的路径加入PATH。另外【/usr/local/新软件名/man】也需要加入man page的搜寻路径中
综上所述,Tarball的安装最好是:
1. 将tarball原始数据解压到/usr/loca/src中
2. 安装到/usr/local这个默认路径下
3. 最好为软件单独建立一个新目录
4. 将新软件的man page加入man path(修改/etc/manpath.config)
利用patch可以对仅对被更新的原始码进行修改,具体用法参考“正规表示法”。注意patch仅更新原始码档案,还要进行编译后才能更新软件
Linux调用的函数库主要有两种:静态(static)函数库和动态(dynamic)函数库
静态函数库:
1. 扩展名为.a
2. 编译行为:函数库在编译时直接整合到执行程序中,所以得到的档案会比较大
3. 编译成功的软件可以独立执行,不再需要外部函数库
4. 因为函数库直接整合到档案中,如果函数库升级,则整个执行档必须要重新编译。也就是说,只要某个函数库升级,所有包含此函数库的程序都需要重新编译
动态函数库:
1. 扩展名为.so
2. 编译行为:函数库没有被整合到程序中,程序中只有指向动态函数库的位置,当执行档要使用函数库时才去读取函数库,所以得到的档案较小
3. 得到的软件因为要调用函数库所以不能独立执行,并且要想成功执行函数库档案必须要存在并且路径也不能变化
4. 函数库升级后不需要进行重新编译(函数库的档名不能发生变化)
大多数的函数库都放在/usr/lib和/lib下;很多函数库其实kernel就已经提供了,它们在/lib/modules下
常用的动态函数库放到cache中可以提高运行速度,步骤为:
1. 在/etc/ld.so.conf中写入要读入cache的函数库所在的目录(只是目录,不是档案,如直接在新的一行添加【/etc/mysql】即可)
2. 使用ldconfig指令读取/etc/ld.so.conf指明的资料
3. 同时也将数据记录一份放在/etc/ld.so.cache档案中
ldconfig [-f 配置文件名] [-C 文件名] [-p]
-f:后接配置文件名,使用这个配置文件作为函数库的取得路径,而不使用/etc/ld.so.conf
-C:后接文件名,使用该文件作为cache的函数库资料,而不使用/etc/ld.so.cache
-p:列出目前所有在cache中的函数库(/etc/ld.so.cache中的资料)
不加任何参数表示读取/etc/ld.so.conf中的资料放入cache
ldd:判断某个binary档案包含了哪些动态函数库,可以用来观察函数库之间的相依性
ldd [-vdr] [file name]
-v:列出所有内容信息
-d:显示资料有遗失的link点
-r:显示ELF有关的错误内容
例:ldd /usr/bin/passwd
可以使用md5sum/sha1sum来校验文件的指纹码
md5sum/sha1sum [-bct] 文件名
md5sum/sha1sum [--status/--warn] --check 文件名
-b:使用binary的读取方式,默认为Windows/DOS型档案的读取方式
-c:检验档案指纹
-t:以文字型方式读取档案指纹
通常直接【md5sum/sha1sum 文件名】得到文件指纹,再与官方提供的文件指纹进行比对即可
可以对系统的重要档案建立指纹,然后用crontab进行检查比对以判断档案是否被篡改