今天我們將深入探討一些更高級(jí)的linux知識(shí),具體來(lái)說(shuō)是關(guān)于linux c程序的構(gòu)建。
在日常的IT生活中,我們經(jīng)常需要在源碼環(huán)境下編譯并安裝軟件。這也是開(kāi)源軟件的一個(gè)顯著特點(diǎn),而Windows中的閉源軟件通常不提供這種源碼編譯安裝的方式。
程序的構(gòu)建過(guò)程通常會(huì)經(jīng)歷以下幾個(gè)階段:
配置
配置階段的目的是檢查當(dāng)前環(huán)境是否滿(mǎn)足安裝該軟件的依賴(lài)關(guān)系。這可以被視為開(kāi)源軟件的一個(gè)缺點(diǎn),因?yàn)殚_(kāi)源軟件的開(kāi)發(fā)者通常使用其他開(kāi)源庫(kù)或工具來(lái)構(gòu)建自己的程序。當(dāng)我們想要運(yùn)行他們的軟件時(shí),就需要檢查我們的系統(tǒng)中是否已經(jīng)安裝了這些庫(kù)或工具。
此外,配置階段還包括設(shè)置一些安裝必需的信息,如安裝路徑、需要安裝的組件等。配置完成后,會(huì)生成一個(gè)Makefile文件,供下一步的make命令使用。
開(kāi)源軟件的開(kāi)發(fā)者通常會(huì)提供一個(gè)configure文件,這個(gè)文件是通過(guò)autotool等工具生成的。關(guān)于configure文件的生成涉及到其他工具的使用和C/c++的知識(shí),這里就不深入介紹了。
我們可以通過(guò)以下命令查看configure文件的可用選項(xiàng):
./configure --help
或者我們可以配置程序的安裝路徑:
./configure --prefix=/usr/local/my
通常,我建議直接使用開(kāi)發(fā)者默認(rèn)的配置:
./configure
這樣,程序會(huì)自動(dòng)檢測(cè)我們的系統(tǒng)環(huán)境,并列出我們?nèi)鄙俚奈募?/p>
我們以一個(gè)名為Shadow的軟件為例進(jìn)行演示。
從開(kāi)發(fā)者的網(wǎng)站下載并解壓這個(gè)軟件后,進(jìn)入目錄,你會(huì)發(fā)現(xiàn)里面的結(jié)構(gòu)大致如下。
按照上述步驟執(zhí)行 ./configure 看看:
之后你會(huì)看到,configure文件開(kāi)始檢測(cè)系統(tǒng)環(huán)境是否滿(mǎn)足安裝需求。
通常,開(kāi)發(fā)者會(huì)在其gitHub頁(yè)面上列出需要安裝的依賴(lài)包,我們可以根據(jù)我們的系統(tǒng)版本來(lái)查找這些依賴(lài)。
例如,這里我們可以在github上找到開(kāi)發(fā)者提供的以下內(nèi)容:
由于我們的系統(tǒng)是Fedora & RHEL類(lèi)的,所以我們可以點(diǎn)擊這里查看需要安裝的依賴(lài):
安裝完依賴(lài)后,再次執(zhí)行 ./configure 就不會(huì)出現(xiàn)錯(cuò)誤了:
(我悄悄換了一臺(tái)已經(jīng)安裝好依賴(lài)的機(jī)器~)
接下來(lái),我們可以進(jìn)行下一步,編譯。
編譯
顧名思義,編譯就是將源文件進(jìn)行編譯鏈接生成可執(zhí)行程序。
在執(zhí)行完上述配置步驟后,目錄中會(huì)出現(xiàn)一個(gè)Makefile文件。
你可能會(huì)說(shuō),我們之前已經(jīng)看到了Makefile文件了。好的,我們來(lái)對(duì)比一下執(zhí)行configure前后的區(qū)別。
以下是未執(zhí)行configure之前的,確實(shí)有Makefile.am和Makefile.in兩個(gè)文件,但它們并不是Makefile。
如果使用過(guò)automake的同學(xué)就會(huì)清楚這兩個(gè)文件的作用(不過(guò)這種同學(xué)可能不會(huì)來(lái)看這種文章哈哈哈):
然后是執(zhí)行完 ./configure 之后的:
已經(jīng)多出了幾個(gè)文件,最重要的是有了Makefile這個(gè)文件。
我們這里不討論Makefile是如何編寫(xiě)的,這個(gè)比較復(fù)雜,一般需要寫(xiě)c語(yǔ)言超過(guò)一年以上的同學(xué)才能完全理解,而且對(duì)于用戶(hù)來(lái)說(shuō),沒(méi)必要知道程序的編譯過(guò)程。
需要注意的是,Linux中的make命令會(huì)自動(dòng)在當(dāng)前目錄下查找名為Makefile或makefile的文件來(lái)加載。
對(duì)于依賴(lài)較少且代碼結(jié)構(gòu)簡(jiǎn)單的代碼,可以手動(dòng)編寫(xiě)Makefile,這樣可以省去第一步的配置工作。
但是對(duì)于依賴(lài)較多且代碼結(jié)構(gòu)復(fù)雜的項(xiàng)目,最好還是使用程序自動(dòng)生成的Makefile。
這里簡(jiǎn)單介紹一下在Linux下編譯文件。
假設(shè)我們有一個(gè)名為linux-test.c的C文件,如何編譯它?
可以使用gcc命令:
gcc linux-test.c -o lt
這里的linux-test.c是我們編寫(xiě)的代碼,-o之后接的是我們希望編譯后程序的名字,這里是lt。
如果你編寫(xiě)的是C++代碼,要使用g++命令。
好了,我們繼續(xù)編譯。一個(gè)文件我們可以用gcc,但是一堆文件的編譯,我們就需要用到make了。
現(xiàn)在我們有了Makefile文件,我們就可以執(zhí)行make了:
這樣,程序就會(huì)自動(dòng)鏈接和編譯文件了。
最后等待一會(huì)兒,編譯完成。
安裝
在Linux中,安裝就簡(jiǎn)單多了。如果你完成了上述幾個(gè)步驟,只需將生成的可執(zhí)行程序復(fù)制到你想要的地方即可。
但是我們有一個(gè)簡(jiǎn)單的命令:
make install
其實(shí)install是Makefile中的一個(gè)規(guī)則,我們可以打開(kāi)Makefile來(lái)查看或編輯,但這是不建議的。
之后,程序就會(huì)自動(dòng)復(fù)制到代碼編寫(xiě)者指定的地方了。
這樣,我們的程序就安裝完成了。