什么是开放源码、编译器与可运行档
什么是函式库:
什么是make与configure:
侦测程序会侦测的数据大约有底下这些:
-
是否有适合的编译器可以编译本软件的程序码;
-
是否已经存在本软件所需要的函式库,或其他需要的相依软件;
-
操作系统平台是否适合本软件,包括Linux的核心版本;
-
核心的表头定义档(header include)是否存在(驱动程序必须要的侦测)。
什么是Tarball的软件:
Tarball 是一个软件包,你将他解压缩之后,里面的文件通常就会有:
-
原始程序码文件;
-
侦测程序文件(可能是configure或config等档名);
-
本软件的简易说明与安装说明(INSTALL或README)。
如何安装与升级软件:
-
将Tarball由厂商的网页下载下来;
-
将Tarball解开,产生很多的原始码文件;
-
开始以gcc进行原始码的编译(会产生目标档object files);
-
然后以gcc进行函式库、主、副程序的连结,以形成主要的binary file;
-
将上述的binary file以及相关的配置档安装至自己的主机上面。
单一程序:印出Hello World:
编辑程序码,亦即原始码
开始编译与测试运行
主、副程序连结:副程序的编译:
撰写所需要的主、副程序
进行程序的编译与连结(Link)
呼叫外部函式库:加入连结的函式库
编译时加入额外函式库连结的方式:gccsin.c -lm -L/lib -L/usr/lib;gcc sin.c -lm -I/usr/include
-
-l:是『加入某个函式库(library)』的意思,
-
m :则是libm.so这个函式库,其中,lib与扩展名(.a或.so)不需要写
-lm 表示使用libm.so (或libm.a)这个函式库的意思~至於那个-L后面接的路径呢?这表示:『我要的函式库libm.so 请到/lib或/usr/lib里面搜寻!』
-I/path 后面接的路径(Path )就是配置要去搜寻相关的include文件的目录
gcc 的简易用法(编译、参数与链结):
# 仅将原始码编译成为目标档,并不制作连结等功能: [root@www ~]# gcc -c hello.c # 会自动的产生 hello.o 这个文件,但是并不会产生 binary 运行档。 # 在编译的时候,依据作业环境给予最佳化运行速度 [root@www ~]# gcc -O hello.c -c # 会自动的产生 hello.o 这个文件,并且进行最佳化喔! # 在进行 binary file 制作时,将连结的函式库与相关的路径填入 [root@www ~]# gcc sin.c -lm -L/usr/lib -I/usr/include # 这个命令较常下达在最终连结成 binary file 的时候, # -lm 指的是 libm.so 或 libm.a 这个函式库文件; # -L 后面接的路径是刚刚上面那个函式库的搜寻目录; # -I 后面接的是原始码内的 include 文件之所在目录。 # 将编译的结果输出成某个特定档名 [root@www ~]# gcc -o hello hello.c # -o 后面接的是要输出的 binary file 档名 # 在编译的时候,输出较多的信息说明 [root@www ~]# gcc -o hello hello.c -Wall # 加入 -Wall 之后,程序的编译会变的较为严谨一点, # 所以警告信息也会显示出来! |
[root@www ~]# vi makefile LIBS = -lm OBJS = main.o haha.o sin_value.o cos_value.o main: ${OBJS} gcc -o main ${OBJS} ${LIBS} clean: rm -f main ${OBJS}
变量与变量内容以『=』隔开,同时两边可以具有空格;
-
变量左边不可以有<tab>,例如上面范例的第一行LIBS左边不可以是<tab>;
-
变量与变量内容在『=』两边不能具有『:』;
-
在习惯上,变量最好是以『大写字母』为主;
-
运用变量时,以${变量}或$(变量)使用;
-
在该shell的环境变量是可以被套用的,例如提到的CFLAGS这个变量!
-
在命令列模式也可以给予变量。
[root@www ~]# CFLAGS="-Wall" make clean main
由於gcc在进行编译的行为时,会主动的去读取CFLAGS这个环境变量,所以,你可以直接在shell定义出这个环境变量
[root@www ~]# vi 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 main ${OBJS}
由於gcc在进行编译的行为时,会主动的去读取CFLAGS这个环境变量,所以,你可以直接在shell定义出这个环境变量,也可以在makefile文件里面去定义,更可以在命令列当中给予:
-
make 命令列后面加上的环境变量为优先;
-
makefile 里面指定的环境变量第二;
-
shell 原本具有的环境变量第三。
[root@www ~]# vi makefile LIBS = -lm OBJS = main.o haha.o sin_value.o cos_value.o CFLAGS = -Wall main: ${OBJS} gcc -o $@ ${OBJS} ${LIBS} <==那个 $@ 就是 main ! clean: rm -f main ${OBJS}
$@:代表目前的标的(target)
使用原始码管理软件所需要的基础软件:gcc或cc等C语言编译器(compiler),make及autoconfig等软件,需要Kernel提供的Library以及相关的Include文件
Tarball 安装的基本步骤:
-
取得原始档:将tarball文件在/usr/local/src目录下解压缩;
-
取得步骤流程:进入新创建的目录底下,去查阅INSTALL与README等相关文件内容(很重要的步骤!);
-
相依属性软件安装:根据INSTALL/README的内容察看并安装好一些相依的软件(非必要);
-
创建makefile:以自动侦测程序(configure或config)侦测作业环境,并创建Makefile这个文件;
-
编译:以make这个程序并使用该目录下的Makefile做为他的参数配置档,来进行make (编译或其他)的动作;
-
安装:以make这个程序,并以Makefile这个参数配置档,依据install这个标的(target)的指定来安装到正确的路径!
安装的命令下达方式:
./configure
这个步骤就是在创建Makefile这个文件罗!通常程序开发者会写一支scripts来检查你的Linux系统、相关的软件属性等等,这个步骤相当的重要,因为未来你的安装资讯都是这一步骤内完成的!另外,这个步骤的相关资讯应该要参考一下该目录下的README或INSTALL相关的文件!
-
make clean
make 会读取Makefile中关於clean的工作。这个步骤不一定会有,但是希望运行一下,因为他可以去除目标文件!因为谁也不确定原始码里面到底有没有包含上次编译过的目标文件(*.o)存在,所以当然还是清除一下比较妥当的。至少等一下新编译出来的运行档我们可以确定是使用自己的机器所编译完成的嘛! -
make
make 会依据Makefile当中的默认工作进行编译的行为!编译的工作主要是进行gcc来将原始码编译成为可以被运行的object files,但是这些object files通常还需要一些函式库之类的link后,才能产生一个完整的运行档!使用make就是要将原始码编译成为可以被运行的可运行档,而这个可运行档会放置在目前所在的目录之下,尚未被安装到预定安装的目录中; -
make install
通常这就是最后的安装步骤了,make会依据Makefile这个文件里面关於install的项目,将上一个步骤所编译完成的数据给他安装到预定的目录中,就完成安装啦!
一般Tarball软件安装的建议事项(如何移除?升级?):
-
最好将tarball的原始数据解压缩到/usr/local/src当中;
-
安装时,最好安装到/usr/local这个默认路径下;
-
考虑未来的反安装步骤,最好可以将每个软件单独的安装在/usr/local底下;
-
为安装到单独目录的软件之man page加入man path搜寻:
如果你安装的软件放置到/usr/local/software/,那么man page搜寻的配置中,可能就得要在/etc/man.config内的40~50行左右处,写入如下的一行:MANPATH /usr/local/software/man
利用patch升级原始码
动态与静态函式库
静态函式库的特色:
-
扩展名:(扩展名为.a)
这类的函式库通常扩展名为libxxx.a的类型; -
编译行为:
这类函式库在编译的时候会直接整合到运行程序当中,所以利用静态函式库编译成的文件会比较大一些喔; -
独立运行的状态:
这类函式库最大的优点,就是编译成功的可运行档可以独立运行,而不需要再向外部要求读取函式库的内容(请参照动态函式库的说明)。 -
升级难易度:
虽然运行档可以独立运行,但因为函式库是直接整合到运行档中,因此若函式库升级时,整个运行档必须要重新编译才能将新版的函式库整合到程序当中。也就是说,在升级方面,只要函式库升级了,所有将此函式库纳入的程序都需要重新编译!
动态函式库的特色:
-
扩展名:(扩展名为.so)
这类函式库通常扩展名为libxxx.so的类型; -
编译行为:
动态函式库与静态函式库的编译行为差异挺大的。与静态函式库被整个捉到程序中不同的,动态函式库在编译的时候,在程序里面只有一个『指向(Pointer)』的位置而已。也就是说,动态函式库的内容并没有被整合到运行档当中,而是当运行档要使用到函式库的机制时,程序才会去读取函式库来使用。由於运行档当中仅具有指向动态函式库所在的指标而已,并不包含函式库的内容,所以他的文件会比较小一点。 -
独立运行的状态:
这类型的函式库所编译出来的程序不能被独立运行,因为当我们使用到函式库的机制时,程序才会去读取函式库,所以函式库文件『必须要存在』才行,而且,函式库的『所在目录也不能改变』,因为我们的可运行档里面仅有『指标』亦即当要取用该动态函式库时,程序会主动去某个路径下读取,呵呵!所以动态函式库可不能随意移动或删除,会影响很多相依的程序软件喔! -
升级难易度:
虽然这类型的运行档无法独立运行,然而由於是具有指向的功能,所以,当函式库升级后,运行档根本不需要进行重新编译的行为,因为运行档会直接指向新的函式库文件(前提是函式库新旧版本的档名相同喔!)。
ldconfig 与/etc/ld.so.conf
将库加载到高速缓存
-
首先,我们必须要在/etc/ld.so.conf里面写下『想要读入高速缓存当中的动态函式库所在的目录』,注意喔,是目录而不是文件;
-
接下来则是利用ldconfig这个运行档将/etc/ld.so.conf的数据读入缓存当中;
-
同时也将数据记录一份在/etc/ld.so.cache这个文件当中呐!
程序的动态函式库解析:ldd
判断某个可运行的binary文件含有什么动态函式库
检验软件正确性:md5sum/ sha1sum