7.1 編譯UNIX軟件包
有很多自由軟件或者是商業(yè)軟件包被安裝在我們的系統(tǒng)上,對(duì)于所有的用戶都是可用的。但是每一個(gè)用戶也可以安裝自己想要的軟件,只是對(duì)個(gè)人來說是有用的。
安裝一個(gè)軟件需要如下幾個(gè)步驟:
- 下載源代碼(一般是一個(gè)壓縮文件)
- 解壓縮源代碼
- 編譯源代碼
- 安裝可執(zhí)行文件
- 設(shè)置安裝目錄的環(huán)境變量
以上的步驟中,最難的也許就是編譯階段了
編譯源代碼
所有的高級(jí)語言代碼都必須轉(zhuǎn)換成一個(gè)計(jì)算機(jī)可以理解的形式。比如C語言的源代碼就會(huì)轉(zhuǎn)換成一個(gè)底層的語言,匯編語言。匯編語言代碼階段之后就是字節(jié)碼,這樣的代碼序列計(jì)算機(jī)就可以直接理解了。最后的階段是將程序編譯的代碼和系統(tǒng)的內(nèi)建庫進(jìn)行鏈接,生成可執(zhí)行程序。
所有的這些步驟都是極端復(fù)雜,已經(jīng)超越了一般用戶力所能及的范圍。為了簡(jiǎn)化這些步驟,一些好用的組件和工具有程序員開發(fā)出來供終端用戶使用,以簡(jiǎn)化這些步驟。
make和Makefile
命令make可以讓程序員來管理大型的程序或者程序的組織結(jié)構(gòu)。當(dāng)程序中的一部分被修改,不必編譯項(xiàng)目的所有部分,只要編譯修改過的部分就可以了。
make命令組織變異的方式來自于一個(gè)叫做Makefile的文本文件,這個(gè)Makefile文件盒源代碼是放在一個(gè)目錄下的。包含的信息就是說明如何編譯軟件,例如在優(yōu)化階段,決定是不是在最終程序中包含調(diào)試信息之類的問題。這個(gè)文件也會(huì)包含一些最終的文件安裝到何處的信息等等,還有手冊(cè)頁,數(shù)據(jù)文件,所需要的庫文件和配置文件等等。
一些包需要你手動(dòng)編輯Makefile文件來設(shè)置最終的安裝目錄還有其他的參數(shù)。然而,很多包現(xiàn)在已經(jīng)隨GNU配置組件一起分發(fā)了。
配置
隨著UNIX變種的增加,寫一個(gè)可以運(yùn)行在全部系統(tǒng)版本上的軟件變得很難了。開發(fā)者常常是沒有權(quán)限進(jìn)入每一個(gè)系統(tǒng),系統(tǒng)不同版本的字符集也是各不相同。GNU的配置系統(tǒng)簡(jiǎn)化了程序分發(fā)成源代碼的構(gòu)建構(gòu)成。所有程序的構(gòu)建都是用簡(jiǎn)單標(biāo)準(zhǔn)的兩個(gè)過程。程序的構(gòu)建者不需要安裝特殊的工具來構(gòu)建程序。
configure shell腳本會(huì)嘗試去猜測(cè)不同的系統(tǒng)在編譯的時(shí)候使用的變量的正確之。使用這些值來為每一個(gè)包構(gòu)建一個(gè)Makefile。
編譯一個(gè)包最簡(jiǎn)單的方法就是:
- 切換到包含包源代碼的目錄
- 輸入./configure來對(duì)你的系統(tǒng)和包進(jìn)行配置
- 輸入make來編譯包
- 可選的,輸入make來運(yùn)行包自帶的自我測(cè)試
- 輸入make install來安裝程序文件和數(shù)據(jù)文件,還有文檔手冊(cè)
- 可選的,輸入make clean來刪除所有二進(jìn)制文件和字節(jié)碼文件
configure組件支持非常非常多的額選項(xiàng),可以使用--help來查看需要的選項(xiàng)意思和特使的配置腳本
有一個(gè)選項(xiàng)會(huì)使用比較頻繁,--prefix和--exec-prefix,這兩個(gè)選項(xiàng)用來指定安裝的目錄。
跟在--prefix后面的目錄是安裝一些與機(jī)器無關(guān)的文件,比如文檔,數(shù)據(jù)還有配置文件。
選項(xiàng)--exec-prefix后面的是可執(zhí)行文件的目錄,一般是prefix的目錄的子目錄。
7.2 下載源代碼
猛擊這里下載源代碼
下載之后放到一個(gè)單獨(dú)的目錄中。
7.3 解壓縮源代碼
下載下來的文件名字是以.tar.gz結(jié)尾的。tar命令是將一些文件打包成一個(gè)文件使用的命令。之后
再使用gzip壓縮,生成一個(gè)tar.gz文件。
首先使用gunzip命令解壓縮,創(chuàng)建一個(gè).tar文件
% gunzip units-1.74.tar.gz
之后再解壓縮tar文件
% tar -xvf units-1.74.tar
7.4 配置和創(chuàng)建Makefile
要做的第一件事情就是仔細(xì)的閱讀文本文件README和INSTALL。這兩個(gè)文件包括了編譯和安裝軟件的
重要信息。
包units使用GNU configure系統(tǒng)來編譯源代碼。我們需要指定安裝的目錄,默認(rèn)的目錄就是你具有
權(quán)限的主要目錄??梢宰约簞?chuàng)建一個(gè)目錄來進(jìn)行安裝。
% mkdir ~/units174
之后運(yùn)行configure組件來指定安裝路徑
% ./configure --prefix=$HOME/units174
注意:
變量$HOME是一個(gè)環(huán)境變量的例子,他的值是你的主目錄的路徑
% echo $HOME
就會(huì)返回你的主目錄路徑
如果configure運(yùn)行正確,就會(huì)創(chuàng)建Makefile文件,你可以看看這個(gè)文件,但是不要去修改他的內(nèi)
容。
7.5 構(gòu)建包
現(xiàn)在就可以通過make命令來構(gòu)建包了
% make
一兩分鐘后(根據(jù)計(jì)算機(jī)性能),可執(zhí)行文件就會(huì)被創(chuàng)建。你可以用check來檢查一下
% make check
如果都OK的話,現(xiàn)在就可以安裝包了
% make install
會(huì)安裝在之前創(chuàng)建的 ~/units174 目錄中
7.6 運(yùn)行軟件
| 名字 | 內(nèi)容 |
|---|---|
| bin | 二進(jìn)制文件 |
| info | GNU info格式的文檔 |
| man | 手冊(cè)頁 |
| share | 共享數(shù)據(jù)文件 |
現(xiàn)在你就可以看見軟件安裝好了(如果都OK的話)
切換到安裝目錄,就可以看見下面幾個(gè)目錄
| 名字 | 內(nèi)容 |
|---|---|
| bin | 二進(jìn)制文件 |
| info | GNU info格式的文檔 |
| man | 手冊(cè)頁 |
| share | 共享數(shù)據(jù)文件 |
向運(yùn)行程序,必須是在bin目錄下
% ./units
舉個(gè)例子,將6英尺轉(zhuǎn)換為米
You have: 6 feet
You want: metres
* 1.8288
OK,如果得到的結(jié)果是1.8288,那么恭喜你,沒問題了。
如果想要知道units程序可以轉(zhuǎn)換的所有單位,請(qǐng)查看目錄share中的數(shù)據(jù)文件(很容易理解)。
想要閱讀所有的文檔,可以切換到info目錄,然后輸入
% info --file=units.info
7.7 去除不必要的代碼
在開發(fā)軟件的時(shí)候,在執(zhí)行文件的結(jié)果中包含調(diào)試信息是很有用的。這樣的話,如果問題出現(xiàn)就可以利用調(diào)試器來追蹤定位問題。
雖然這些個(gè)信息對(duì)開發(fā)者很有用,但是隨用戶來說是沒有必要的。我們可以假定軟件包一旦完成,可以獲得下載版本肯定是已經(jīng)測(cè)試和調(diào)試過的。然而,當(dāng)我們編譯上面的軟件時(shí),調(diào)試信息依然編譯進(jìn)了最終的可執(zhí)行程序。既然我們不需要這個(gè)調(diào)試信息,就從最終文件中去除他吧。這樣做的好處之一就是結(jié)果文件的大小會(huì)精簡(jiǎn),運(yùn)行也會(huì)快一些。
我們要做的就是觀察二進(jìn)制文件在之前和之后的大小的對(duì)比,可以使用file命令來看看文件的信息。
% file units
units: ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked (uses shared libs), not stripped
之后使用strip命令來去除所有的調(diào)試信息和行號(hào)信息。
% strip units
ls -l
首先是文件的大小,成為了原來的三分之一,原來二進(jìn)制文件的三分之二都是調(diào)試信息。
之后檢查一下文件信息
% file units
units: ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked (uses shared libs), stripped
有時(shí)候你可以使用命令make來安裝已經(jīng)去除了信息的版本,只要把make install 換成make
install-strip。