一、开放源码的软件安装与升级简介
1.开放源码、编译程序与执行文件
开放源码:就是程序代码(写满了程序代码的纯文本文件);
编译程序:将程序代码与函数库做链接,并翻译成机器看得懂的语言;
可执行文件:机器看得懂的二进制执行文件。
图示三者关系:
2.函数库
函数库:类似子程序的角色,可以被调用来执行的一段功能函数。
图示外部动态函数库的调用情况:
·Linux内核提供了相当多的函数库来给硬件开发者利用(系统调用);
·由上面的图示可知识,硬件开发者可通过调用内核函数库来开发出与硬件特性相关的产品;
·软件开发者也可以根据内核函数库来开发出相关的软件。
3.make与configure
make:一个程序,make会在当前的目录下搜索Makefile(or makefile)这个文本文件
Makefile:记录了源码如何编译的详细信息,由configure程序检测环境成功后生成
configure:由软件开发商开发的“一个用来检测用户操作环境是否有软件开发商所需功能”的程序
·使用类似gcc编译程序编译数据量大的源码时(小程序很多),编译命令要写很多;
·make程序可以进行编译过程的命令简化;
·执行make时,先执行configure检测环境,再生成Makefile文件,最后根据Makefile的内容对源码进行编译;
·configure需要检测的数据:
a.是否有适合的编译程序可以编译本软件的程序代码
b.是否已经存在本软件所需要的函数库或其他需要的相关软件
c.操作系统平台是否适合本软件,包括Linux的内核版本
d.内核的头定义文件(header include)是否存在(驱动程序必须要检测的)
图示:make->configure->makefile->编译->生成最终软件
--需要环境检测的原因
·每个Linux distribution使用相同的内核,但内核的版本可能不一样;
·不同版本的内核所使用的系统调用(对应内核函数库)可能不相同;
·不同的Linux distribution的函数库文件路径、函数库的文件名定义或是默认安装的编译程序都不相同;
·每个软件需要的相关函数库并不相同;
·软件开发商并非只针对Linux开发,而是针对UNIX-Like做开发;
·因此为了保证开发的软件能正常的使用,就需要对环境做检测,以得出相关的环境信息,做正确的编译调用。
·因此理论上在Centos编译的软件直接拿到Ubuntu中是无法执行的,需要重新编译。
4.Tarball的软件
纯文件文件:一种文件格式,在网络中传输时,十分浪费带宽,源代码即是这种文件格式
gzip:一种压缩技术,使用该压缩技术压缩后的文件名一般为*.tar.gz
Tarball:通过gzip技术压缩源代码文件后得到的文件,是一个软件包
·源代码文件直接在网络上共享很浪费带宽;
·使用gzip技术打包源代码文件即可以解决这个问题;
·打包后的文件称为Tarball文件,即Tarball是一个软件包;
·解压缩Tarball后,通常可以获得:
a.源代码文件
b.检测程序文件(configure或config等文件名)
c.本软件的简易说明与安装说明(INSTALL或README)
5.安装与升级软件
编译:将源代码文件通过编译程序翻译成机器可识别的二进制可执行文件程序
安装:从源代码编译开始到软件真正可以使用,可以认为是安装;将编译生成的二进制文件组合起来形成功能完整的软件,也可以认为是安装
--软件更新
·更新软件的两大类方法:
a.直接以源码通过编译来安装与升级
b.直接以编译好的二进制程序来安装与升级
·a方法在安装过程中具有很高的可选择性,但相对麻烦;
·b方法,Linux distribution厂商针对自己的Linux平台先进行编译过程,再将编译好的二进制程序释出,这样可以直接在该平台上安装,省去检测与编译的过程,节省了时间;
·b方法即“预先编译好程序的机制”被称为包管理模式;
·包管理模式存在于很多distribution,这些模式有RPM、yum、dpkg与APT等;
--软件安装
·由上面知道,可以有两种方式来提供软件的安装,即编译与包管理模式;
·编译安装的流程为:
a.将Tarball下载下来
b.将Tarball解压缩,生成很多源代码文件
c.开始以gcc等编译器进行源码的编译(会生成目标文件)
d.然后以gcc进行函数库、主程序、子程序的链接,以形成主要的二进制文件
e.将上述的二进制文件以及相关的配置文件安装至自己的主机上面
·c、d步骤已经被make简化。
二、使用C语言进行编译的例子
1.单一程序:打印Hello World
单一程序:只有一个源代码文件,编译生成一个目标文件,再链接成一个可执行二进制文件
多程序(只有一个主程序):多个源代码文件,编译生成多个目标文件,再链接成一个或多个可执行二进制文件
目标文件:object file,即obj文件,由源代码文件编译生成
-c:编译生成obj文件
-o:链接obj文件生成二进制文件
无-c -o:直接编译生成二进制文件,只对单一源代码文件有效
·编辑源代码文件
[root@xpleaf ~]# vim hello.c #includeint main(void) { printf("Hello World\n"); }
--先编译生成obj文件,再链接成二进制文件
·编译生成obj文件
[root@xpleaf ~]# gcc -c hello.c [root@xpleaf ~]# ll hello* -rw-r--r-- 1 root root 64 Aug 16 03:57 hello.c -rw-r--r-- 1 root root 1496 Aug 16 04:21 hello.o
·链接obj文件为二进制文件
[root@xpleaf ~]# gcc -o hello hello.o ===>指定二进制文件名为hello [root@xpleaf ~]# ll hello* -rwxr-xr-x 1 root root 6465 Aug 16 04:23 hello -rw-r--r-- 1 root root 64 Aug 16 03:57 hello.c -rw-r--r-- 1 root root 1496 Aug 16 04:21 hello.o
·执行二进制文件
[root@xpleaf ~]# ./hello Hello World
--直接编译生成二进制执行文件
·直接编译生成二进制文件
[root@xpleaf ~]# gcc hello.c [root@xpleaf ~]# ll hello.c a.out -rwxr-xr-x 1 root root 6465 Aug 16 04:30 a.out ===>默认生成的二进制文件 -rw-r--r-- 1 root root 64 Aug 16 03:57 hello.c
·执行生成的二进制文件
[root@xpleaf ~]# ./a.out Hello World
·如果是多个源代码文件(多程序),则需要使用第一种方法。
2.主程序、子程序链接:子程序的编译
·编辑主程序
[root@xpleaf ~]# vim thanks.c #includeint main(void) { printf("Hello World\n"); thanks_2(); }
·编辑子程序
[root@xpleaf ~]# vim thanks_2.c #includevoid thanks_2(void) { printf("Thank you!\n"); }
·编译生成obj文件
[root@xpleaf ~]# gcc -c thanks.c thanks_2.c [root@xpleaf ~]# ll thanks* -rw-r--r-- 1 root root 74 Aug 16 04:38 thanks_2.c -rw-r--r-- 1 root root 1504 Aug 16 04:38 thanks_2.o -rw-r--r-- 1 root root 90 Aug 16 04:37 thanks.c -rw-r--r-- 1 root root 1560 Aug 16 04:38 thanks.o
·链接obj文件生成二进制文件
[root@xpleaf ~]# gcc -o thanks thanks.o thanks_2.o [root@xpleaf ~]# ll thanks -rwxr-xr-x 1 root root 6606 Aug 16 04:39 thanks
·执行二进制文件
[root@xpleaf ~]# ./thanks Hello World Thank you!
3.调用外部函数库:加入链接的函数库
-l:加入函数库(library),即要在编译时链接函数库
m:libm.so函数库,lib与扩展名(.a或.so)不需要写
-lm:使用libm.so这个函数库来进行链接,sin函数功能即在这个函数库中
-L/lib:使用函数库到/lib目录里去搜索,L为lib的第一个字母
-L/usr/lib:同上
-I/usr/include:使用相关函数库到/usr/include目录里去搜索,比如stdio.h函数库
-O:编译生成obj文件,但是会做一定的优化
-Wall:在编译时显示警告信息
·Linux默认将函数库放在/lib与/usr/lib中,所以没有写-L的参数也是可以的;
·如果需要使用的相关函数库不在默认路径中,则需要使用-L/path;
--调用外部函数库的例子
·编辑源代码文件
[root@xpleaf ~]# vim sin.c #includeint main(void) { float value; value = sin ( 3.14 / 2 ); printf("%f\n",value); }
·编译生成obj文件
[root@xpleaf ~]# gcc -c sin.c sin.c: In function ain sin.c:5: warning: incompatible implicit declaration of built-in function in ===>虽然有警告信息,但是仍然可以通过编译 [root@xpleaf ~]# ll sin* -rw-r--r-- 1 root root 101 Aug 16 06:19 sin.c -rw-r--r-- 1 root root 1512 Aug 16 06:20 sin.o
·链接obj文件与函数库生成二进制文件
[root@xpleaf ~]# gcc -o sin sin.o [root@xpleaf ~]# ll sin* -rwxr-xr-x 1 root root 6473 Aug 16 06:22 sin -rw-r--r-- 1 root root 101 Aug 16 06:19 sin.c -rw-r--r-- 1 root root 1512 Aug 16 06:20 sin.o
·执行生成的二进制文件
[root@xpleaf ~]# ./sin 1.000000
·上面的例子中,并没有加入任何相关的-lm参数也可以得到最终的结果,这意味着,书中的信息已有些过时了,等到真正需要深入研究Linux C开发时再去探讨吧。
三、用make进行宏编译
1.对比传统编译与make编译
--多程序的实例
main.c 主程序 hello.c 输出欢迎与提示信息 square.c 计算用户输入的数字的平方 cube.c 计算用户输入的数字的立方
·编辑main.c
[root@xpleaf ~]# vim main.c #includeint main(void) { int num; hello(); scanf("%d",&num); square(num); cube(num); return 0; }
·编辑hello.c
[root@xpleaf ~]# vim hello.c #includevoid hello(void) { printf("Welcome to my procedure!\n"); printf("This procedure will get the number you input.\n"); printf("And then output the square and cube of the number.\n"); printf("Now,please input a number:"); }
·编辑square.c
[root@xpleaf ~]# vim square.c #includevoid square(int n) { printf("The square of %d is %d.\n",n,n*n); }
·编辑cube.c
[root@xpleaf ~]# vim cube.c #includevoid cube(int m) { printf("The cube of %d is %d.\n",m,m*m*m); }
--使用传统方法编译
·编译生成obj文件
[root@xpleaf ~]# gcc -c main.c [root@xpleaf ~]# gcc -c hello.c [root@xpleaf ~]# gcc -c square.c [root@xpleaf ~]# gcc -c cube.c
·链接obj文件生成二进制可执行文件
[root@xpleaf ~]# gcc -o main main.o hello.o square.o cube.o [root@xpleaf ~]# ll main -rwxr-xr-x 1 root root 7472 Aug 16 07:02 main
·执行生成的二进制文件
[root@xpleaf ~]# ./main Welcome to my procedure! This procedure will get the number you input. And then output the square and cube of the number. Now,please input a number:3 The square of 3 is 9. The cube of 3 is 27.
--使用make编译
·编译makefile文件,并且告知最终生成的二进制执行文件为main
[root@xpleaf ~]# vim makefile main: main.o hello.o square.o cube.o gcc -o main main.o hello.o square.o cube.o ===>这一行开始必须是tab键补全
·执行make编译
[root@xpleaf ~]# make cc -c -o main.o main.c cc -c -o hello.o hello.c cc -c -o square.o square.c cc -c -o cube.o cube.c gcc -o main main.o hello.o square.o cube.o [root@xpleaf ~]# ll main -rwxr-xr-x 1 root root 7472 Aug 16 07:12 main
·执行生成的main二进制文件
[root@xpleaf ~]# ./main Welcome to my procedure! This procedure will get the number you input. And then output the square and cube of the number. Now,please input a number:2 The square of 2 is 4. The cube of 2 is 8.
·make简化了编译时所需执行的命令;
·编译完成好,修改某个源代码文件,则make仅会对变化的源代码文件进行编译,其他目标文件不会改变;
·最后依照相关性来更新文件。
2.makefile的基本语法与变量
单一目标makefile:只有一个功能的makefile文件,通常是gcc编译
多个目标makefile:多个功能的makefile文件
main:习惯作为makefile文件中编译的target名,不唯一
clean:习惯作为makefile文件中删除的target名,不唯一
-O:gcc编译时的非必要参数
-Wall:gcc编译时的非必要参数
FLAGS:标志,非必要的参数即为FLAGS
CFLAGS:语法名词,c语言中的FLAGS,如-O,-Wall,gcc编译时会主动去读取该环境变量
--基本语法一:单一目标
·如下:
目标(target):目标文件1 目标文件2gcc -o 欲新建的可执行文件 目标文件1 目标文件2
·目标(target)是makefile文件中的一个标志,代表一种功能,名称可自定义;
·target需要用“:”与相关文件分隔;
·目标文件都是指obj文件;
--基本语法二:多个目标
·以前面的例子为例添加clean目标以清除文件
[root@xpleaf ~]# vim makefile main: main.o hello.o square.o cube.o gcc -o main main.o hello.o square.o cube.o clean: rm -f main main.o hello.o square.o cube.o
·执行makefile的clean功能
[root@xpleaf ~]# ll *.o main -rw-r--r-- 1 root root 1544 Aug 16 22:44 cube.o -rw-r--r-- 1 root root 1856 Aug 16 22:44 hello.o -rwxr-xr-x 1 root root 7472 Aug 16 22:44 main -rw-r--r-- 1 root root 1720 Aug 16 22:44 main.o -rw-r--r-- 1 root root 1536 Aug 16 22:44 square.o [root@xpleaf ~]# make clean rm -f main main.o hello.o square.o cube.o [root@xpleaf ~]# ll *.o main ls: cannot access *.o: No such file or directory ls: cannot access main: No such file or directory
·make可以接两个目标执行,如make clean main,表示先删除文件后进行编译;
--基本语法三:使用变量简化makefile文件
·简化前面的makefile文件
[root@xpleaf ~]# vim makefile OBJS = main.o hello.o square.o cube.o main: ${OBJS} gcc -o main ${OBJS} clean: rm -f main ${OBJS}
·makefile的基本语法:
a.变量左边不可以有
b.习惯上,变量用大写字母表示
c.以${变量}或$(变量)方式调用变量
d.可以在shell(命令行模式中)中定义CFLAGS这个变量
e.也可以在makefile文件中定义CFLAGS这个变量
·gcc在编译时,会主动去读取CFLAGS这个环境;
·以d来解释
[root@xpleaf ~]# CFLAGS="-Wall" make clean main rm -f main main.o hello.o square.o cube.o cc -Wall -c -o main.o main.c main.c: In function ain main.c:5: warning: implicit declaration of function ello main.c:7: warning: implicit declaration of function quare main.c:8: warning: implicit declaration of function ube cc -Wall -c -o hello.o hello.c cc -Wall -c -o square.o square.c cc -Wall -c -o cube.o cube.c gcc -o main main.o hello.o square.o cube.o [root@xpleaf ~]# ll main -rwxr-xr-x 1 root root 7472 Aug 16 23:20 main ===>相当于在编译时使用了-Wall参数,输出警告信息
·以e来解释
[root@xpleaf ~]# vim makefile OBJS = main.o hello.o square.o cube.o CFLAGS = -Wall main: ${OBJS} gcc -o main ${OBJS} clean: rm -f main ${OBJS} [root@xpleaf ~]# make clean main rm -f main main.o hello.o square.o cube.o cc -Wall -c -o main.o main.c main.c: In function ain main.c:5: warning: implicit declaration of function ello main.c:7: warning: implicit declaration of function quare main.c:8: warning: implicit declaration of function ube cc -Wall -c -o hello.o hello.c cc -Wall -c -o square.o square.c cc -Wall -c -o cube.o cube.c gcc -o main main.o hello.o square.o cube.o [root@xpleaf ~]# ll main -rwxr-xr-x 1 root root 7472 Aug 16 23:24 main ===>实现d一样的功能
·d与e都可以指定CFLAGS环境变量,如果同时指定,有如下规则:
a.make命令行后面加上的环境变量为优先
b.makefile第二优先级
c.shell原本具有的环境变量第三优先级
--基本语法四:特殊变量$@
·特殊变量$@代表目前的目标(target);
·简化前而的makefile文件:
[root@xpleaf ~]# vim makefile OBJS = main.o hello.o square.o cube.o main: ${OBJS} gcc -o $@ ${OBJS} ===>$@即代表这里的目标main clean: rm -f main ${OBJS}
四、Tarball的管理与建议
1.使用源码管理软件所需的基础软件
·根据前面对Tarball及编译过程的理解,所需软件为:
a.gcc等编译器
b.make及configure软件
c.内核(Kernel)提供的函数库(Library)及相关的Include文件
·如果没有这些软件,可以通过RPM及yum方式安装。
2.Tarball安装的基本步骤
·基本上,安装的步骤可参考如下:
步骤 | 目的 | 过程 | 注意 |
1 | 获得源文件 | 将源文件在/usr/local/src目录下解压缩 | 建议此目录下 |
2 | 获得安装流程 | 阅读新建立目录下的INSTALL与README文件 | |
3 | 依赖软件安装 | 根据b的内容,安装其它需求的软件(非必须) | |
4 | 建立makefile | 运行自动检测程序configure或config,建立makefile文件 | 注意指定安装目录 |
5 | 编译 | 根据makefile的内容信息,执行make命令编译 | |
6 | 安装 | 执行make中的install目标,安装软件到d步骤指定的目录中 |
·Tarball软件安装的命令执行方式
a. ./configure,建立makefile文件,但是需要./configure --help查看相关参数
b. make clean,在执行make命令时,建议这样做,排除其它obj文件
c. make,执行make只要将二进制文件编译到当前目录下
d. make install,最后的安装步骤,将编译完成的数据安装到makefile文件指定的目录中去
·除了b步骤,其余不可缺,因为每一步都影响后面的操作。
3.Tarball软件安装的注意事项
lib、bin、man目录:默认安装软件会使用的目录
·考虑到管理用户安装软件的便利性,有如下两种情况:
--Linux distribution软件默认安装情况
·Linux distribution安装的软件多放在/usr;
·以apache软件说明,默认情况下,会用到的目录:
a./etc/httpd apache软件(服务)的相关配置文件放置目录
b./usr/lib apache软件本身所需的特殊函数库(内核本身没有),非必须,因为可能内核本身函数库已满足
c./usr/bin apache软件(服务)所涉及的命令放置目录
d./usr/share/man 在线文档的放置目录
·/usr/lib、/usr/bin放置的不仅仅只有apache软件相关的文件,其它Linux distribution安装的软件的相关文件也放置在该目录;
·可以类比/lib、/bin,只是/lib放置系统开机时需要用到的函数库,/bin放置放置单用户维护模式还能使用的命令;
·单用户维护模式即进入系统维护模式,此模式下只允许单一用户登入;
--用户自行安装软件情况
·用户自行安装软件建议在/usr/local;
·以Tarball安装即源码安装的软件为例,默认情况下,会用到的目录:
a./usr/local/etc
b./usr/local/lib
c./usr/local/bin
d./usr/local/man
·只要是用户源码安装的软件,相关文件都会放到上面的目录中去;
·装好系统时发现这些目录为空,是因为还没有进行过源码安装;
·源码安装默认目录带来的问题:如果安装软件过多,删除或升级的时候,难以追查文件源
·为方便Tarball安装的管理,建议的安装方式:
a.将Tarball的原始数据解压缩到/usr/local/src当中
b.安装时,安装到默认目录/usr/local下
c.还需要安装在/usr/local目录下对应的软件单独目录
d.为安装到单独目录的软件的man page加入man path搜索
·解释c,上面的安装情况变为:
/usr/local/ntp/etc 当然配置文件一般放在/etc或/usr/etc中
/usr/local/ntp/lib
/usr/local/ntp/bin
/usr/local/ntp/man
·解释d,则在/etc/man.conf的40~50行添加内容为:MANPATH /usr/local/ntp/man
4.源码编译方式安装ntp软件
·1.获得源文件:解压缩下载的tarball文件到/usr/local/src/目录下
[root@xpleaf ~]# ll ntp-4.2.4p7.tar.gz -rw-r--r-- 1 root root 3382146 Aug 19 2015 ntp-4.2.4p7.tar.gz [root@xpleaf ~]# cd /usr/local/src/ ===>切换目录 [root@xpleaf src]# tar -xvf /root/ntp-4.2.4p7.tar.gz …… [root@xpleaf src]# ll -ld ntp-4.2.4p7/ drwxrwsrwx 24 427 6011 4096 Aug 17 01:52 ntp-4.2.4p7/
·2.获得安装流程:查看新建目录的INSTALL或README文件
[root@xpleaf src]# cd ntp-4.2.4p7/ [root@xpleaf ntp-4.2.4p7]# vim INSTALL …… The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. ……
·3.查看configure帮助参数并建立makefile文件
[root@xpleaf ntp-4.2.4p7]# ./configure --help …… Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/bin', `/usr/local/lib' etc. You can specify an installation prefix other than `/usr/local' using `--prefix', for instance `--prefix=$HOME'. ===>这段话提示默认目录就为/usr/locar …… [root@xpleaf ntp-4.2.4p7]# ./configure --prefix=/usr/local/ntp ===>指定安装目录 …… checking for gcc... gcc …… config.status: creating Makefile ……
·4.执行make命令编译
[root@xpleaf ntp-4.2.4p7]# make clean ===>make之前先clean …… [root@xpleaf ntp-4.2.4p7]# make …… [root@xpleaf ntp-4.2.4p7]# make check ===>执行make的检查
·5.安装软件到指定目录下
[root@xpleaf ntp-4.2.4p7]# make install …… [root@xpleaf ntp-4.2.4p7]# cd /usr/local/ntp/ [root@xpleaf ntp]# ll total 12 drwxr-xr-x 2 root root 4096 Aug 17 01:53 bin drwxr-xr-x 2 root root 4096 Aug 17 01:53 lib drwxr-xr-x 3 root root 4096 Aug 17 01:53 man
5.利用patch更新源码
diff:可以比较文件之间的差异,制作简单的文件更新补丁
patch file:即文件更新补丁,使用patch命令可进行源码更新
·升级Tarball安装的软件,并非需要下载该软件完整全新的Tarball;
·一些软件的升级,通常是某部分代码的更新;
·没有改变的代码则不需要进行改动,可以采取“更新源码”达到要求;
·直接更新部分源码,再make执行自动update(未改变的内容无需更新),省去makefile的建立,可以节省时间;
·软件开发商在更新源码后,会发布patch file文件;
--patch更新源码环境搭建
-修改目标文件并做测试
·以前面的main.c hello.c square.c cube.c makefile文件作为旧文件
·原来文件的内容分别为:
[root@xpleaf ~]# head main.c hello.c square.c cube.c makefile ==> main.c <== #includeint main(void) { int num; hello(); scanf("%d",&num); square(num); cube(num); return 0; } ==> hello.c <== #include void hello(void) { printf("Welcome to my procedure!\n"); printf("This procedure will get the number you input.\n"); printf("And then output the square and cube of the number.\n"); printf("Now,please input a number:"); } ==> square.c <== #include void square(int n) { printf("The square of %d is %d.\n",n,n*n); } ==> cube.c <== #include void cube(int m) { printf("The cube of %d is %d.\n",m,m*m*m); } ==> makefile <== OBJS = main.o hello.o square.o cube.o main: ${OBJS} gcc -o $@ ${OBJS} clean: rm -f main ${OBJS}
·备份hello.c和makefile
[root@xpleaf ~]# cp hello.c hello.c.backup [root@xpleaf ~]# cp makefile makefile.backup
·现在只修改hello.c和makefile的内容分别为:
[root@xpleaf ~]# vim hello.c #includevoid hello(void) { printf("Version 2.0\n"); ===>新增的内容 printf("Made by xpleaf.\n"); printf("Welcome to my procedure!\n"); printf("This procedure will get the number you input.\n"); printf("And then output the square and cube of the number.\n"); printf("Now,please input a number:"); } [root@xpleaf ~]# vim makefile OBJS = main.o hello.o square.o cube.o main: ${OBJS} gcc -o $@ ${OBJS} clean: rm -f main ${OBJS} install: ===>新增install和unstall目标 cp -a main /usr/local/bin unstall: rm -f /usr/local/bin/main
·对新增内容的测试情况
[root@xpleaf ~]# make clean main install rm -f main main.o hello.o square.o cube.o cc -c -o main.o main.c cc -c -o hello.o hello.c cc -c -o square.o square.c cc -c -o cube.o cube.c gcc -o main main.o hello.o square.o cube.o cp -a main /usr/local/bin ===>最终将软件安装到/usr/local/bin [root@xpleaf ~]# main ===>直接在命令行模式下执行 Version 2.0 Made by xpleaf. Welcome to my procedure! This procedure will get the number you input. And then output the square and cube of the number. Now,please input a number:3 The square of 3 is 9. The cube of 3 is 27. [root@xpleaf ~]# make unstall ===>卸载安装的软件 rm -f /usr/local/bin/main [root@xpleaf ~]# main -bash: /usr/local/bin/main: No such file or directory
·测试成功,将测试成功文件放入new文件夹中,并恢复原来备份文件
[root@xpleaf ~]# mv hello.c new/hello_new.c [root@xpleaf ~]# mv makefile new/makefile_new [root@xpleaf ~]# mv hello.c.backup hello.c [root@xpleaf ~]# mv makefile.backup makefile
-利用diff制作patch file文件
[root@xpleaf ~]# diff -Naur hello.c new/hello_new.c >> update_patch_file [root@xpleaf ~]# diff -Naur makefile new/makefile_new >> update_patch_file [root@xpleaf ~]# cat update_patch_file --- hello.c 2015-08-17 07:58:13.289069939 +0800 +++ new/hello_new.c 2015-08-17 07:48:03.818069620 +0800 @@ -1,6 +1,8 @@ ……
--利用update_patch_file文件更新源码并测试
·更新源码
[root@xpleaf ~]# patch -p0 < update_patch_file patching file hello.c patching file makefile
·对于patch -p0中的0做简单说明:
前面制作update_patch_file文件时有:
diff -Naur hello.c new/hello_new.c
a.这里0即表示要更新的文件为hello.c
b.如果为/dir1/hello.c,这里应为1,表示去掉一层目录结构,更新的文件为hello.c
c.如果为/dir1/dir2/hello.c,这里应为2,表示去掉两层目录结构,更新的文件为hello.c
d.以此类推
·执行make编译并做测试:
[root@xpleaf ~]# make clean main install rm -f main main.o hello.o square.o cube.o cc -c -o main.o main.c cc -c -o hello.o hello.c cc -c -o square.o square.c cc -c -o cube.o cube.c gcc -o main main.o hello.o square.o cube.o cp -a main /usr/local/bin [root@xpleaf ~]# main Version 2.0 ===>版本已经更新为Version 2.0,与前面的测试结果一致 Made by xpleaf. Welcome to my procedure! This procedure will get the number you input. And then output the square and cube of the number. Now,please input a number:3 The square of 3 is 9. The cube of 3 is 27. [root@xpleaf ~]# make unstall rm -f /usr/local/bin/main [root@xpleaf ~]# main -bash: /usr/local/bin/main: No such file or directory ===>软件已经被卸载 ===>达到与测试时同样的效果
六、函数库管理
·很多的软件之间都会使用彼此提供的函数库来进行特殊功能的运行
1.动态与静态函数库
静态函数库 | 动态函数库 | |
扩展名 | .a | .so |
编译行为 |
编译时直接整合到执行程序中,因此利用静态函数库编译的文件会比较大 |
动态函数内容没有整合到执行程序中,程序里只有一个“指向的位置”,在用到函数库时才会去读取函数库,编译的文件相对会比较小 |
独立执行的状态 |
可以独立执行,不需要向外部读取函数库内容 |
不能独立执行,函数库文件要存在且目录不能改变,函数库文件也不能随意移动或删除 |
升级难易程序 |
升级较难,需要将升级后的函数库重新整合到程序中 | 升级容易,只升级函数库即可,不需要对程序重新编译,因为程序与函数库只是一个指向的关系 |
·Linux distribution倾向于使用动态函数;
·函数库多放在/usr/lib、lib目录中;
·内核(Kernel)的函数库放在/lib/modules中,不同版本的内核提供的函数库差异性大。
2.将常用动态数据库加载到内存中去
/etc/ld.so.conf:记录读入高速缓存的动态数据库的配置文件
ldconfig:不加参数可以使/etc/ld.so.conf中的配置生效,-p参数可以列出动态函数库的链接信息
·可以把常用的动态数据库加载到内存中,以加快程序对该数据库的读取速度;
·执行操作的一般流程为:
a.在/etc/ld.so.conf里面写下想要读入高速缓存当中的动态函数库所在的目录
b.执行ldconfig命令,将/etc/ld.so.conf的数据读入缓存中
·演示把/usr/lib/gcc/加载在内存中:
[root@xpleaf ~]# vi /etc/ld.so.conf include ld.so.conf.d/*.conf /usr/lib/gcc/ [root@xpleaf ~]# ldconfig ===>执行该命令后不会有任何信息输出
3.程序的动态函数库判断:ldd
ldd:可以判断程序含有的动态数据库,-v参数还可以列出其它相关信息
·判断/usr/bin/passwd
[root@xpleaf ~]# ldd /usr/bin/passwd linux-vdso.so.1 => (0x00007fff85046000) libuser.so.1 => /usr/lib64/libuser.so.1 (0x00007f92b7d7f000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f92b7b48000) libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f92b78fb000) libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f92b76f8000) libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f92b73e1000) libpopt.so.0 => /lib64/libpopt.so.0 (0x00007f92b71d7000) libpam_misc.so.0 => /lib64/libpam_misc.so.0 (0x00007f92b6fd3000) libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f92b6db7000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f92b6b97000) libc.so.6 => /lib64/libc.so.6 (0x00007f92b6803000) libpam.so.0 => /lib64/libpam.so.0 (0x00007f92b65f5000) libfreebl3.so => /lib64/libfreebl3.so (0x00007f92b637d000) libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f92b6179000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f92b5f5c000) librt.so.1 => /lib64/librt.so.1 (0x00007f92b5d53000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f92b5b4f000) /lib64/ld-linux-x86-64.so.2 (0x000000317d400000)
·判断/lib/libc.so.6函数的其他相关函数
[root@xpleaf ~]# ldd -v /lib/libc.so.6 /lib/ld-linux.so.2 (0x00829000) linux-gate.so.1 => (0x004b1000) Version information: ===>使用-v参数可以增加其他版本信息的显示 /lib/libc.so.6: ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2 ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2 ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
六、检验软件正确性
·主要是检验文件的MD5或SHA1指纹编码来判断文件是否被篡改