一、開放源碼的軟體安裝與更新簡介
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:直接編譯生成二進制檔案,隻對單一源代碼檔案有效
·編輯源代碼檔案
1
2
3
4
5
6
<code>[root@xpleaf ~]# vim hello.c </code>
<code>#</code><code>include</code><code><stdio.h></code>
<code>int</code> <code>main(</code><code>void</code><code>)</code>
<code>{</code>
<code> </code><code>printf(</code><code>"hello world\n"</code><code>);</code>
<code>}</code>
--先編譯生成obj檔案,再連結成二進制檔案
·編譯生成obj檔案
<code>[root@xpleaf ~]# gcc -c hello.c</code>
<code>[root@xpleaf ~]# ll hello*</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>64</code> <code>aug </code><code>16</code> <code>03</code><code>:</code><code>57</code> <code>hello.c</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1496</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>21</code> <code>hello.o</code>
·連結obj檔案為二進制檔案
<code>[root@xpleaf ~]# gcc -o hello hello.o ===>指定二進制檔案名為hello</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>6465</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>23</code> <code>hello</code>
·執行二進制檔案
<code>[root@xpleaf ~]# ./hello </code>
<code>hello world</code>
--直接編譯生成二進制執行檔案
·直接編譯生成二進制檔案
<code>[root@xpleaf ~]# gcc hello.c </code>
<code>[root@xpleaf ~]# ll hello.c a.out </code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>6465</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>30</code> <code>a.out ===>預設生成的二進制檔案</code>
·執行生成的二進制檔案
<code>[root@xpleaf ~]# ./a.out </code>
·如果是多個源代碼檔案(多程式),則需要使用第一種方法。
2.主程式、子程式連結:子程式的編譯
·編輯主程式
7
<code>[root@xpleaf ~]# vim thanks.c</code>
<code> </code><code>printf(</code><code>"hello world\n"</code><code>);</code>
<code> </code><code>thanks_2();</code>
·編輯子程式
<code>[root@xpleaf ~]# vim thanks_2.c</code>
<code>void</code> <code>thanks_2(</code><code>void</code><code>)</code>
<code> </code><code>printf(</code><code>"thank you!\n"</code><code>);</code>
<code>[root@xpleaf ~]# gcc -c thanks.c thanks_2.c </code>
<code>[root@xpleaf ~]# ll thanks*</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>74</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>38</code> <code>thanks_2.c</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1504</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>38</code> <code>thanks_2.o</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>90</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>37</code> <code>thanks.c</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1560</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>38</code> <code>thanks.o</code>
·連結obj檔案生成二進制檔案
<code>[root@xpleaf ~]# gcc -o thanks thanks.o thanks_2.o</code>
<code>[root@xpleaf ~]# ll thanks</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>6606</code> <code>aug </code><code>16</code> <code>04</code><code>:</code><code>39</code> <code>thanks</code>
<code>[root@xpleaf ~]# ./thanks </code>
<code>thank you!</code>
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;
--調用外部函數庫的例子
8
9
<code>[root@xpleaf ~]# vim sin.c</code>
<code> </code><code>float value;</code>
<code> </code><code>value = sin ( </code><code>3.14</code> <code>/ </code><code>2</code> <code>);</code>
<code> </code><code>printf(</code><code>"%f\n"</code><code>,value);</code>
<code>[root@xpleaf ~]# gcc -c sin.c </code>
<code>sin.c: in </code><code>function</code> <code>ain</code>
<code> </code><code>sin.c:</code><code>5</code><code>: warning: incompatible implicit declaration of built-</code><code>in</code> <code>function</code> <code>in</code> <code>===>雖然有警告資訊,但是仍然可以通過編譯</code>
<code>[root@xpleaf ~]# ll sin*</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>101</code> <code>aug </code><code>16</code> <code>06</code><code>:</code><code>19</code> <code>sin.c</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1512</code> <code>aug </code><code>16</code> <code>06</code><code>:</code><code>20</code> <code>sin.o</code>
·連結obj檔案與函數庫生成二進制檔案
<code>[root@xpleaf ~]# gcc -o sin sin.o</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>6473</code> <code>aug </code><code>16</code> <code>06</code><code>:</code><code>22</code> <code>sin</code>
<code>[root@xpleaf ~]# ./sin</code>
<code>1.000000</code>
·上面的例子中,并沒有加入任何相關的-lm參數也可以得到最終的結果,這意味着,書中的資訊已有些過時了,等到真正需要深入研究linux c開發時再去探讨吧。
三、用make進行宏編譯
1.對比傳統編譯與make編譯
--多程式的執行個體
<code>main.c 主程式</code>
<code>hello.c 輸出歡迎與提示資訊</code>
<code>square.c 計算使用者輸入的數字的平方</code>
<code>cube.c 計算使用者輸入的數字的立方</code>
·編輯main.c
10
11
<code>[root@xpleaf ~]# vim main.c</code>
<code> </code><code>int</code> <code>num;</code>
<code> </code><code>hello();</code>
<code> </code><code>scanf(</code><code>"%d"</code><code>,&num);</code>
<code> </code><code>square(num);</code>
<code> </code><code>cube(num);</code>
<code> </code><code>return</code> <code>0</code><code>;</code>
·編輯hello.c
<code>[root@xpleaf ~]# vim hello.c</code>
<code>void</code> <code>hello(</code><code>void</code><code>)</code>
<code> </code><code>printf(</code><code>"welcome to my procedure!\n"</code><code>);</code>
<code> </code><code>printf(</code><code>"this procedure will get the number you input.\n"</code><code>);</code>
<code> </code><code>printf(</code><code>"and then output the square and cube of the number.\n"</code><code>);</code>
<code> </code><code>printf(</code><code>"now,please input a number:"</code><code>);</code>
·編輯square.c
<code>[root@xpleaf ~]# vim square.c</code>
<code>void</code> <code>square(</code><code>int</code> <code>n)</code>
<code> </code><code>printf(</code><code>"the square of %d is %d.\n"</code><code>,n,n*n);</code>
·編輯cube.c
<code>[root@xpleaf ~]# vim cube.c</code>
<code>void</code> <code>cube(</code><code>int</code> <code>m)</code>
<code> </code><code>printf(</code><code>"the cube of %d is %d.\n"</code><code>,m,m*m*m);</code>
--使用傳統方法編譯
<code>[root@xpleaf ~]# gcc -c main.c</code>
<code>[root@xpleaf ~]# gcc -c hello.c </code>
<code>[root@xpleaf ~]# gcc -c square.c </code>
<code>[root@xpleaf ~]# gcc -c cube.c</code>
·連結obj檔案生成二進制可執行檔案
<code>[root@xpleaf ~]# gcc -o main main.o hello.o square.o cube.o </code>
<code>[root@xpleaf ~]# ll main</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>7472</code> <code>aug </code><code>16</code> <code>07</code><code>:</code><code>02</code> <code>main</code>
<code>[root@xpleaf ~]# ./main </code>
<code>welcome to my procedure!</code>
<code>this procedure will </code><code>get</code> <code>the number you input.</code>
<code>and then output the square and cube of the number.</code>
<code>now,please input a number:</code><code>3</code>
<code>the square of </code><code>3</code> <code>is</code> <code>9</code><code>.</code>
<code>the cube of </code><code>3</code> <code>is</code> <code>27</code><code>.</code>
--使用make編譯
·編譯makefile檔案,并且告知最終生成的二進制執行檔案為main
<code>[root@xpleaf ~]# vim makefile </code>
<code>main: main.o hello.o square.o cube.o</code>
<code> </code><code>gcc -o main main.o hello.o square.o cube.o ===>這一行開始必須是tab鍵補全</code>
·執行make編譯
<code>[root@xpleaf ~]# make</code>
<code>cc -c -o main.o main.c</code>
<code>cc -c -o hello.o hello.c</code>
<code>cc -c -o square.o square.c</code>
<code>cc -c -o cube.o cube.c</code>
<code>gcc -o main main.o hello.o square.o cube.o</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>7472</code> <code>aug </code><code>16</code> <code>07</code><code>:</code><code>12</code> <code>main</code>
·執行生成的main二進制檔案
<code>[root@xpleaf ~]# ./main</code>
<code>now,please input a number:</code><code>2</code>
<code>the square of </code><code>2</code> <code>is</code> <code>4</code><code>.</code>
<code>the cube of </code><code>2</code> <code>is</code> <code>8</code><code>.</code>
·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編譯時會主動去讀取該環境變量
--基本文法一:單一目标
·如下:
<code>目标(target):目标檔案</code><code>1</code> <code>目标檔案</code><code>2</code>
<code><tab> gcc -o 欲建立的可執行檔案 目标檔案</code><code>1</code> <code>目标檔案</code><code>2</code>
·目标(target)是makefile檔案中的一個标志,代表一種功能,名稱可自定義;
·target需要用“:”與相關檔案分隔;
·目标檔案都是指obj檔案;
--基本文法二:多個目标
·以前面的例子為例添加clean目标以清除檔案
<code> </code><code>gcc -o main main.o hello.o square.o cube.o</code>
<code>clean:</code>
<code> </code><code>rm -f main main.o hello.o square.o cube.o</code>
·執行makefile的clean功能
<code>[root@xpleaf ~]# ll *.o main</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1544</code> <code>aug </code><code>16</code> <code>22</code><code>:</code><code>44</code> <code>cube.o</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1856</code> <code>aug </code><code>16</code> <code>22</code><code>:</code><code>44</code> <code>hello.o</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>7472</code> <code>aug </code><code>16</code> <code>22</code><code>:</code><code>44</code> <code>main</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1720</code> <code>aug </code><code>16</code> <code>22</code><code>:</code><code>44</code> <code>main.o</code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>1536</code> <code>aug </code><code>16</code> <code>22</code><code>:</code><code>44</code> <code>square.o</code>
<code>[root@xpleaf ~]# make clean</code>
<code>rm -f main main.o hello.o square.o cube.o</code>
<code>[root@xpleaf ~]# ll *.o main </code>
<code>ls: cannot access *.o: no such file or directory</code>
<code>ls: cannot access main: no such file or directory</code>
·make可以接兩個目标執行,如make clean main,表示先删除檔案後進行編譯;
--基本文法三:使用變量簡化makefile檔案
·簡化前面的makefile檔案
<code>objs = main.o hello.o square.o cube.o</code>
<code>main: ${objs}</code>
<code> </code><code>gcc -o main ${objs}</code>
<code> </code><code>rm -f main ${objs}</code>
·makefile的基本文法:
a.變量左邊不可以有<tab>
b.習慣上,變量用大寫字母表示
c.以${變量}或$(變量)方式調用變量
d.可以在shell(指令行模式中)中定義cflags這個變量
e.也可以在makefile檔案中定義cflags這個變量
·gcc在編譯時,會主動去讀取cflags這個環境;
·以d來解釋
12
13
14
15
<code>[root@xpleaf ~]# cflags=</code><code>"-wall"</code> <code>make clean main </code>
<code>cc -wall -c -o main.o main.c</code>
<code>main.c: in </code><code>function</code> <code>ain</code>
<code> </code><code>main.c:</code><code>5</code><code>: warning: implicit declaration of </code><code>function</code> <code>ello</code>
<code>main.c:</code><code>7</code><code>: warning: implicit declaration of </code><code>function</code> <code>quare</code>
<code>main.c:</code><code>8</code><code>: warning: implicit declaration of </code><code>function</code> <code>ube</code>
<code>cc -wall -c -o hello.o hello.c</code>
<code>cc -wall -c -o square.o square.c</code>
<code>cc -wall -c -o cube.o cube.c</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>7472</code> <code>aug </code><code>16</code> <code>23</code><code>:</code><code>20</code> <code>main</code>
<code>===>相當于在編譯時使用了-wall參數,輸出警告資訊</code>
·以e來解釋
16
17
18
19
20
21
22
23
24
<code>cflags = -wall</code>
<code>[root@xpleaf ~]# make clean main</code>
<code>-rwxr-xr-x </code><code>1</code> <code>root root </code><code>7472</code> <code>aug </code><code>16</code> <code>23</code><code>:</code><code>24</code> <code>main</code>
<code>===>實作d一樣的功能</code>
·d與e都可以指定cflags環境變量,如果同時指定,有如下規則:
a.make指令行後面加上的環境變量為優先
b.makefile第二優先級
c.shell原本具有的環境變量第三優先級
--基本文法四:特殊變量$@
·特殊變量$@代表目前的目标(target);
·簡化前而的makefile檔案:
<code>[root@xpleaf ~]# vim makefile</code>
<code> </code><code>gcc -o $@ ${objs} ===>$@即代表這裡的目标main</code>
四、tarball的管理與建議
1.使用源碼管理軟體所需的基礎軟體
·根據前面對tarball及編譯過程的了解,所需軟體為:
a.gcc等編譯器
b.make及configure軟體
c.核心(kernel)提供的函數庫(library)及相關的include檔案
·如果沒有這些軟體,可以通過rpm及yum方式安裝。
2.tarball安裝的基本步驟
·基本上,安裝的步驟可參考如下:
步驟
目的
過程
注意
獲得源檔案
将源檔案在/usr/local/src目錄下解壓縮
建議此目錄下
獲得安裝流程
閱讀建立立目錄下的install與readme檔案
依賴軟體安裝
根據b的内容,安裝其它需求的軟體(非必須)
建立makefile
運作自動檢測程式configure或config,建立makefile檔案
注意指定安裝目錄
編譯
根據makefile的内容資訊,執行make指令編譯
安裝
執行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/目錄下
<code>[root@xpleaf ~]# ll ntp-</code><code>4.2</code><code>.4p7.tar.gz </code>
<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>3382146</code> <code>aug </code><code>19</code> <code>2015</code> <code>ntp-</code><code>4.2</code><code>.4p7.tar.gz</code>
<code>[root@xpleaf ~]# cd /usr/local/src/ ===>切換目錄</code>
<code>[root@xpleaf src]# tar -xvf /root/ntp-</code><code>4.2</code><code>.4p7.tar.gz </code>
<code>……</code>
<code>[root@xpleaf src]# ll -ld ntp-</code><code>4.2</code><code>.4p7/</code>
<code>drwxrwsrwx </code><code>24</code> <code>427</code> <code>6011</code> <code>4096</code> <code>aug </code><code>17</code> <code>01</code><code>:</code><code>52</code> <code>ntp-</code><code>4.2</code><code>.4p7/</code>
·2.獲得安裝流程:檢視建立目錄的install或readme檔案
25
26
27
28
29
30
31
<code>[root@xpleaf src]# cd ntp-</code><code>4.2</code><code>.4p7/</code>
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# vim install</code>
<code>the simplest way to compile </code><code>this</code> <code>package</code> <code>is</code><code>:</code>
<code> </code><code>1</code><code>. `cd</code><code>' to the directory containing the package'</code><code>s source code and type</code>
<code> </code><code>`./configure</code><code>' to configure the package for your system. if you'</code><code>re</code>
<code> </code><code>using `csh' on an old version of system v, you might need to type</code>
<code> </code><code>`sh ./configure</code><code>' instead to prevent `csh'</code> <code>from trying to execute</code>
<code> </code><code>`configure' itself.</code>
<code> </code><code>running `configure' takes a </code><code>while</code><code>. while running, it prints some</code>
<code> </code><code>messages telling which features it </code><code>is</code> <code>checking </code><code>for</code><code>.</code>
<code> </code><code>2</code><code>. type `make' to compile the </code><code>package</code><code>.</code>
<code> </code><code>3</code><code>. optionally, type `make check' to run any self-tests that come </code><code>with</code>
<code> </code><code>the </code><code>package</code><code>.</code>
<code> </code><code>4</code><code>. type `make install' to install the programs and any data files and</code>
<code> </code><code>documentation.</code>
<code> </code><code>5</code><code>. you can remove the program binaries and object files from the</code>
<code> </code><code>source code directory by typing `make clean'. to also remove the</code>
<code> </code><code>files that `configure' created (so you can compile the </code><code>package</code> <code>for</code>
<code> </code><code>a different kind of computer), type `make distclean'. there </code><code>is</code>
<code> </code><code>also a `make maintainer-clean' target, but that </code><code>is</code> <code>intended mainly</code>
<code> </code><code>for</code> <code>the </code><code>package</code><code>'s developers. if you </code><code>use</code> <code>it, you may have to </code><code>get</code>
<code> </code><code>all sorts of other programs </code><code>in</code> <code>order to regenerate files that came</code>
<code> </code><code>with</code> <code>the distribution.</code>
·3.檢視configure幫助參數并建立makefile檔案
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# ./configure --help</code>
<code>installation directories:</code>
<code> </code><code>--prefix=prefix install architecture-independent files </code><code>in</code> <code>prefix</code>
<code> </code><code>[/usr/local]</code>
<code> </code><code>--exec-prefix=eprefix install architecture-dependent files </code><code>in</code> <code>eprefix</code>
<code> </code><code>[prefix]</code>
<code>by </code><code>default</code><code>, `make install' will install all the files </code><code>in</code>
<code>`/usr/local/bin</code><code>', `/usr/local/lib'</code> <code>etc. you can specify</code>
<code>an installation prefix other than `/usr/local</code><code>' using `--prefix'</code><code>,</code>
<code>for</code> <code>instance `--prefix=$home'. ===>這段話提示預設目錄就為/usr/locar</code>
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# ./configure --prefix=/usr/local/ntp ===>指定安裝目錄</code>
<code>checking </code><code>for</code> <code>gcc... gcc</code>
<code>config.status: creating makefile</code>
·4.執行make指令編譯
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# make clean ===>make之前先clean</code>
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# make</code>
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# make check ===>執行make的檢查</code>
·5.安裝軟體到指定目錄下
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# make install </code>
<code>[root@xpleaf ntp-</code><code>4.2</code><code>.4p7]# cd /usr/local/ntp/</code>
<code>[root@xpleaf ntp]# ll</code>
<code>total </code><code>12</code>
<code>drwxr-xr-x </code><code>2</code> <code>root root </code><code>4096</code> <code>aug </code><code>17</code> <code>01</code><code>:</code><code>53</code> <code>bin</code>
<code>drwxr-xr-x </code><code>2</code> <code>root root </code><code>4096</code> <code>aug </code><code>17</code> <code>01</code><code>:</code><code>53</code> <code>lib</code>
<code>drwxr-xr-x </code><code>3</code> <code>root root </code><code>4096</code> <code>aug </code><code>17</code> <code>01</code><code>:</code><code>53</code> <code>man</code>
5.利用patch更新源碼
diff:可以比較檔案之間的差異,制作簡單的檔案更新更新檔
patch file:即檔案更新更新檔,使用patch指令可進行源碼更新
·更新tarball安裝的軟體,并非需要下載下傳該軟體完整全新的tarball;
·一些軟體的更新,通常是某部分代碼的更新;
·沒有改變的代碼則不需要進行改動,可以采取“更新源碼”達到要求;
·直接更新部分源碼,再make執行自動update(未改變的内容無需更新),省去makefile的建立,可以節省時間;
·軟體開發商在更新源碼後,會釋出patch file檔案;
--patch更新源碼環境搭建
-修改目标檔案并做測試
·以前面的main.c hello.c square.c cube.c makefile檔案作為舊檔案
·原來檔案的内容分别為:
32
33
34
35
36
37
38
39
40
41
42
43
<code>[root@xpleaf ~]# head main.c hello.c square.c cube.c makefile </code>
<code>==> main.c <==</code>
<code>==> hello.c <==</code>
<code>==> square.c <==</code>
<code>==> cube.c <==</code>
<code>==> makefile <==</code>
<code> </code><code>gcc -o $@ ${objs}</code>
·備份hello.c和makefile
<code>[root@xpleaf ~]# cp hello.c hello.c.backup</code>
<code>[root@xpleaf ~]# cp makefile makefile.backup</code>
·現在隻修改hello.c和makefile的内容分别為:
<code> </code><code>printf(</code><code>"version 2.0\n"</code><code>); ===>新增的内容</code>
<code> </code><code>printf(</code><code>"made by xpleaf.\n"</code><code>);</code>
<code>install: ===>新增install和unstall目标</code>
<code> </code><code>cp -a main /usr/local/bin</code>
<code>unstall:</code>
<code> </code><code>rm -f /usr/local/bin/main</code>
·對新增内容的測試情況
<code>[root@xpleaf ~]# make clean main install</code>
<code>cp -a main /usr/local/bin ===>最終将軟體安裝到/usr/local/bin</code>
<code>[root@xpleaf ~]# main ===>直接在指令行模式下執行</code>
<code>version </code><code>2.0</code>
<code>made by xpleaf.</code>
<code>[root@xpleaf ~]# make unstall ===>解除安裝安裝的軟體</code>
<code>rm -f /usr/local/bin/main</code>
<code>[root@xpleaf ~]# main</code>
<code>-bash: /usr/local/bin/main: no such file or directory</code>
·測試成功,将測試成功檔案放入new檔案夾中,并恢複原來備份檔案
<code>[root@xpleaf ~]# mv hello.c </code><code>new</code><code>/hello_new.c</code>
<code>[root@xpleaf ~]# mv makefile </code><code>new</code><code>/makefile_new</code>
<code>[root@xpleaf ~]# mv hello.c.backup hello.c</code>
<code>[root@xpleaf ~]# mv makefile.backup makefile</code>
-利用diff制作patch file檔案
<code>[root@xpleaf ~]# diff -naur hello.c </code><code>new</code><code>/hello_new.c >> update_patch_file</code>
<code>[root@xpleaf ~]# diff -naur makefile </code><code>new</code><code>/makefile_new >> update_patch_file </code>
<code>[root@xpleaf ~]# cat update_patch_file </code>
<code>--- hello.c </code><code>2015</code><code>-</code><code>08</code><code>-</code><code>17</code> <code>07</code><code>:</code><code>58</code><code>:</code><code>13.289069939</code> <code>+</code><code>0800</code>
<code>+++ </code><code>new</code><code>/hello_new.c </code><code>2015</code><code>-</code><code>08</code><code>-</code><code>17</code> <code>07</code><code>:</code><code>48</code><code>:</code><code>03.818069620</code> <code>+</code><code>0800</code>
<code>@@ -</code><code>1</code><code>,</code><code>6</code> <code>+</code><code>1</code><code>,</code><code>8</code> <code>@@</code>
--利用update_patch_file檔案更新源碼并測試
·更新源碼
<code>[root@xpleaf ~]# patch -p0 < update_patch_file </code>
<code>patching file hello.c</code>
<code>patching file makefile</code>
·對于patch -p0中的0做簡單說明:
前面制作update_patch_file檔案時有:
<code>diff -naur hello.c </code><code>new</code><code>/hello_new.c</code>
a.這裡0即表示要更新的檔案為hello.c
b.如果為/dir1/hello.c,這裡應為1,表示去掉一層目錄結構,更新的檔案為hello.c
c.如果為/dir1/dir2/hello.c,這裡應為2,表示去掉兩層目錄結構,更新的檔案為hello.c
d.以此類推
·執行make編譯并做測試:
<code>cp -a main /usr/local/bin</code>
<code>version </code><code>2.0</code> <code>===>版本已經更新為version </code><code>2.0</code><code>,與前面的測試結果一緻</code>
<code>[root@xpleaf ~]# make unstall</code>
<code>-bash: /usr/local/bin/main: no such file or directory ===>軟體已經被解除安裝</code>
<code>===>達到與測試時同樣的效果</code>
六、函數庫管理
·很多的軟體之間都會使用彼此提供的函數庫來進行特殊功能的運作
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/加載在記憶體中:
<code>[root@xpleaf ~]# vi /etc/ld.so.conf</code>
<code>include</code> <code>ld.so.conf.d/*.conf</code>
<code>/usr/lib/gcc/</code>
<code>[root@xpleaf ~]# ldconfig ===>執行該指令後不會有任何資訊輸出</code>
3.程式的動态函數庫判斷:ldd
ldd:可以判斷程式含有的動态資料庫,-v參數還可以列出其它相關資訊
·判斷/usr/bin/passwd
<code>[root@xpleaf ~]# ldd /usr/bin/passwd </code>
<code> </code><code>linux-vdso.so.</code><code>1</code> <code>=> (</code><code>0x00007fff85046000</code><code>)</code>
<code> </code><code>libuser.so.</code><code>1</code> <code>=> /usr/lib64/libuser.so.</code><code>1</code> <code>(</code><code>0x00007f92b7d7f000</code><code>)</code>
<code> </code><code>libcrypt.so.</code><code>1</code> <code>=> /lib64/libcrypt.so.</code><code>1</code> <code>(</code><code>0x00007f92b7b48000</code><code>)</code>
<code> </code><code>libgobject-</code><code>2.0</code><code>.so.</code><code>0</code> <code>=> /lib64/libgobject-</code><code>2.0</code><code>.so.</code><code>0</code> <code>(</code><code>0x00007f92b78fb000</code><code>)</code>
<code> </code><code>libgmodule-</code><code>2.0</code><code>.so.</code><code>0</code> <code>=> /lib64/libgmodule-</code><code>2.0</code><code>.so.</code><code>0</code> <code>(</code><code>0x00007f92b76f8000</code><code>)</code>
<code> </code><code>libglib-</code><code>2.0</code><code>.so.</code><code>0</code> <code>=> /lib64/libglib-</code><code>2.0</code><code>.so.</code><code>0</code> <code>(</code><code>0x00007f92b73e1000</code><code>)</code>
<code> </code><code>libpopt.so.</code><code>0</code> <code>=> /lib64/libpopt.so.</code><code>0</code> <code>(</code><code>0x00007f92b71d7000</code><code>)</code>
<code> </code><code>libpam_misc.so.</code><code>0</code> <code>=> /lib64/libpam_misc.so.</code><code>0</code> <code>(</code><code>0x00007f92b6fd3000</code><code>)</code>
<code> </code><code>libaudit.so.</code><code>1</code> <code>=> /lib64/libaudit.so.</code><code>1</code> <code>(</code><code>0x00007f92b6db7000</code><code>)</code>
<code> </code><code>libselinux.so.</code><code>1</code> <code>=> /lib64/libselinux.so.</code><code>1</code> <code>(</code><code>0x00007f92b6b97000</code><code>)</code>
<code> </code><code>libc.so.</code><code>6</code> <code>=> /lib64/libc.so.</code><code>6</code> <code>(</code><code>0x00007f92b6803000</code><code>)</code>
<code> </code><code>libpam.so.</code><code>0</code> <code>=> /lib64/libpam.so.</code><code>0</code> <code>(</code><code>0x00007f92b65f5000</code><code>)</code>
<code> </code><code>libfreebl3.so => /lib64/libfreebl3.so (</code><code>0x00007f92b637d000</code><code>)</code>
<code> </code><code>libgthread-</code><code>2.0</code><code>.so.</code><code>0</code> <code>=> /lib64/libgthread-</code><code>2.0</code><code>.so.</code><code>0</code> <code>(</code><code>0x00007f92b6179000</code><code>)</code>
<code> </code><code>libpthread.so.</code><code>0</code> <code>=> /lib64/libpthread.so.</code><code>0</code> <code>(</code><code>0x00007f92b5f5c000</code><code>)</code>
<code> </code><code>librt.so.</code><code>1</code> <code>=> /lib64/librt.so.</code><code>1</code> <code>(</code><code>0x00007f92b5d53000</code><code>)</code>
<code> </code><code>libdl.so.</code><code>2</code> <code>=> /lib64/libdl.so.</code><code>2</code> <code>(</code><code>0x00007f92b5b4f000</code><code>)</code>
<code> </code><code>/lib64/ld-linux-x86-</code><code>64</code><code>.so.</code><code>2</code> <code>(</code><code>0x000000317d400000</code><code>)</code>
·判斷/lib/libc.so.6函數的其他相關函數
<code>[root@xpleaf ~]# ldd -v /lib/libc.so.</code><code>6</code>
<code> </code><code>/lib/ld-linux.so.</code><code>2</code> <code>(</code><code>0x00829000</code><code>)</code>
<code> </code><code>linux-gate.so.</code><code>1</code> <code>=> (</code><code>0x004b1000</code><code>)</code>
<code> </code><code>version information: ===>使用-v參數可以增加其他版本資訊的顯示</code>
<code> </code><code>/lib/libc.so.</code><code>6</code><code>:</code>
<code> </code><code>ld-linux.so.</code><code>2</code> <code>(glibc_private) => /lib/ld-linux.so.</code><code>2</code>
<code> </code><code>ld-linux.so.</code><code>2</code> <code>(glibc_2.</code><code>3</code><code>) => /lib/ld-linux.so.</code><code>2</code>
<code> </code><code>ld-linux.so.</code><code>2</code> <code>(glibc_2.</code><code>1</code><code>) => /lib/ld-linux.so.</code><code>2</code>
六、檢驗軟體正确性
·主要是檢驗檔案的md5或sha1指紋編碼來判斷檔案是否被篡改