日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux【学习心得】深入剖析软件的源码安装

發(fā)布時(shí)間:2023/12/31 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux【学习心得】深入剖析软件的源码安装 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自:http://www.imooc.com/wenda/detail/242044

? ? 學(xué)習(xí)了一段時(shí)間的Linux,相信大家都會(huì)遇到需要安裝軟件的情況,而新手(比如我)對(duì)于這個(gè)問(wèn)題肯定是特別頭疼。照著網(wǎng)上的步驟裝,可能出現(xiàn)莫名其妙的 錯(cuò)誤,不知道如何是好。更關(guān)鍵的是不知道每一步都是在干嘛,所以即使我們依葫蘆畫瓢地裝了多次某個(gè)軟件,遇到問(wèn)題也沒(méi)有辦法解決。那今天我就來(lái)談?wù)?Linux上源碼安裝軟件的一些東西,我也是新手,勿噴……


????首先我們應(yīng)該知道,計(jì)算機(jī)能夠識(shí)別的只有二進(jìn)制,也就是010101這樣的串,或者說(shuō)是高低電平……

????那么我們平時(shí)敲的代碼,比如說(shuō)C語(yǔ)言打印一個(gè)"Hello world",相信大家都無(wú)比熟悉吧。

#include<stdio.h>int?main(){???printf("Hello?world!");???return?0;}

我 們把上面的文件保存為hello.c。對(duì)于計(jì)算機(jī)來(lái)說(shuō)這只是一個(gè)文本文件,里面存的這些英文字母和符號(hào)它是看不懂的,對(duì)它來(lái)說(shuō)就像天書一樣不知所云。那我 們要讓這段代碼可以執(zhí)行,就必須讓計(jì)算機(jī)能看懂它。比如我們可以把這段代碼用匯編語(yǔ)言寫一遍,雖然更貼近底層,但計(jì)算機(jī)依然看不懂,我們還是得把它寫成機(jī) 器碼才行。

WTF!這我哪兒會(huì)啊!!不用擔(dān)心,我們不會(huì),但是有大牛會(huì),而且他們已經(jīng)做得非常棒了,那就是大名鼎鼎的gcc。

gcc就是我們常說(shuō)的編譯器(事實(shí)上這只是它的一小部分功能),它能把我們?nèi)四芸炊腃語(yǔ)言代碼翻譯成機(jī)器能夠看懂的二進(jìn)制代碼。這樣這段代碼就能在計(jì)算機(jī)上愉快地運(yùn)行了。


那我們現(xiàn)在用gcc來(lái)編譯一下hello.c

gcc?hello.c

執(zhí)行后我們來(lái)看看


可以發(fā)現(xiàn)新生成了一個(gè)可執(zhí)行文件a.out

我們可以運(yùn)行一下它試試

./a.out


可以看到成功地輸出了"Hello world!"也就是說(shuō)gcc把我們的C語(yǔ)言文件成功翻譯成了計(jì)算機(jī)能夠識(shí)別并運(yùn)行的二進(jìn)制文件。


到這里大家可能會(huì)比較疑惑,你講安裝軟件,講編譯C語(yǔ)言代碼干什么。我只想說(shuō),你先別著急,這是為后面理解安裝過(guò)程做鋪墊,是非常重要的,理解軟件安裝的那些步驟在干什么可全看這些了。


上面我們用gcc編譯好了一個(gè)c文件,雖然就是一條指令,但是其實(shí)gcc干了很多事情,我們可以把它分為4步:預(yù)處理、翻譯成匯編語(yǔ)言、匯編、鏈接。我們可以這么來(lái)看看

首先刪除掉剛剛生成的a.out

rm?-rf?a.out

然后我們執(zhí)行下面這條指令

gcc?-E?hello.c?-o?hello.i


誒,我們可以看到,生成了一個(gè)hello.i文件,我們打開(kāi)它看看可以發(fā)現(xiàn),其實(shí)這個(gè)hello.i就是把#include<stdio.h>的stdio.h文件寫了進(jìn)來(lái)。

然后我們?cè)賵?zhí)行

gcc?-S?hello.i?-o?hello.s


那么可以看到我們生成了一個(gè)hello.s文件,打開(kāi)它看看


其實(shí)就是把上一步的hello.i翻譯成了匯編語(yǔ)言

接著我們運(yùn)行

gcc?-c?hello.s?-o?hello.o


生成了一個(gè)hello.o文件,當(dāng)我們想查看這個(gè)文件時(shí)系統(tǒng)會(huì)提示說(shuō)這是個(gè)二進(jìn)制文件。

當(dāng)然這個(gè)文件依然是不能執(zhí)行的,我們可以用file命令看看,它是沒(méi)有excutable屬性的。我們還缺少最后一步

gcc?hello.o?-o?hello.exe


最后就生成了hello.exe這個(gè)可執(zhí)行文件。在這里我還是想說(shuō)一下,linux不是靠后綴來(lái)區(qū)分文件的,后綴只是給人看的。.exe是windows里的可執(zhí)行文件的后綴,但我們不應(yīng)該帶入太多windows里的東西到linux,所以我其實(shí)不推薦給可執(zhí)行文件加.exe后綴

當(dāng)然我這里只是方便大家看,所以執(zhí)行

./hello.exe

就可以打印出"Hello world!"了


到這里大家應(yīng)該也看明白了編譯一個(gè)C語(yǔ)言文件的整個(gè)過(guò)程了,但是細(xì)心的同學(xué)可能就會(huì)有疑問(wèn)了:既然hello.o是個(gè)二進(jìn)制文件我們也看不懂,gcc干嘛生成它,為什么不直接從hello.s生成hello.exe?

這真的是一個(gè)好問(wèn)題,也是后面講Linux下源碼安裝軟件非常核心的地方。那我們就來(lái)講講這個(gè).o是啥東東


其實(shí)在我們實(shí)際的工程項(xiàng)目中,一個(gè)項(xiàng)目是有很多個(gè)c文件的,這些文件會(huì)互相調(diào)用。比如看這個(gè)例子


我要輸出一個(gè)"Hello world!"但是我想把輸出單獨(dú)寫成一個(gè)output.c文件供其它文件調(diào)用。

先看output.c

#include<stdio.h>#include?"haha.h"void?output(){????printf("Hello?world!");}

然后是主程序hello.c

#include<stdio.h>#include?"haha.h"int?main(){???output();???return?0;}

然后是haha.h

void?output();

以上都是C語(yǔ)言需要關(guān)心的地方,大家如果這里看不明白不要緊,關(guān)鍵看我之后的操作


首先我們來(lái)分別編譯兩個(gè).c文件為.o

gcc?-c?hello.c?-o?hello.ogcc?-c?output.c?-o?output.o

完了之后呢,我們進(jìn)行一次鏈接

gcc?hello.o?output.o?-o?final


這樣我們就得到了一個(gè)可執(zhí)行文件final

上面的內(nèi)容大家只需要關(guān)心最后一句,也就是?

gcc hello.o output.o -o final

hello.o和output.o是兩個(gè)獨(dú)立的文件,但是hello會(huì)用到output的功能,所以我們把它鏈接起來(lái),最后生成了一個(gè)可執(zhí)行文件,執(zhí)行就能輸出"Hello world!"啦!。那上面代碼沒(méi)有輸出換行所以看著有點(diǎn)別扭,我用箭頭標(biāo)出來(lái)了。

那這么做有什么好處呢?想象一下,我們?nèi)绻薷哪硞€(gè)文件,其它文件沒(méi)有改變的話,只需要重新編譯那一個(gè)文件,再鏈接即可,而不需要重新編譯所有的文件。不知道大家裝過(guò)mysql沒(méi)有,編譯一次要30分鐘,要是想做個(gè)小小的修改,每次重新編譯那得多么痛苦……


至于怎么鏈接之類的問(wèn)題不在我們的討論范疇,有興趣大家可以上google百度一下。


那 回到的主題,我們要安裝一個(gè)軟件,都會(huì)先去下載一個(gè)"安裝包"。既然是"包"那肯定是有很多源文件的,比如我們的apache,里面有很多c源程序,每個(gè) c程序都實(shí)現(xiàn)了不同的功能。所以我們?nèi)绻惭bapache(即生成一個(gè)可執(zhí)行文件),一定是先各種編譯,最后把各種.o文件鏈接成一個(gè)可執(zhí)行文件。那么 問(wèn)題來(lái)了,幾十上百個(gè).c文件我要自己編譯再鏈接豈不是瘋了?對(duì),確實(shí)會(huì)瘋掉的!你可能都不知道你編譯了哪些沒(méi)有編譯哪些……


所以接下來(lái)就會(huì)介紹大家可能非常熟悉make。這個(gè)玩意兒相信在linux上源碼安裝過(guò)軟件的同學(xué)都知道而且用過(guò)而且?guī)缀趺總€(gè)軟件安裝都會(huì)用到。它到底是用到干什么的呢?其實(shí)啊,它就是來(lái)幫我們解決以上問(wèn)題的,讓我們的編譯鏈接更加方便,讓世界更加美好。


那為了說(shuō)明問(wèn)題,我們?cè)倏匆粋€(gè)例子

我們的代碼可能會(huì)調(diào)用系統(tǒng)的已經(jīng)實(shí)現(xiàn)過(guò)的函數(shù),這時(shí)候編譯會(huì)發(fā)生神馬呢?

sin.c

#include<stdio.h>int?main(){????double?v;????v?=?sin?(3.14?/?6);??//???pi/6????return?0;}

這個(gè)sin我們是沒(méi)有實(shí)現(xiàn)的而是去調(diào)用系統(tǒng)內(nèi)的sin

那 如果我們直接編譯肯定會(huì)報(bào)'未聲明的函數(shù)調(diào)用',這個(gè)大家都知道,所以我們應(yīng)該怎么做呢?既然我們要調(diào)用系統(tǒng)已經(jīng)實(shí)現(xiàn)好的sin,那么我們得知道它在哪 兒?在linux中呢,libm.so里面實(shí)現(xiàn)了sin,所以我們需要在編譯命令中加入這個(gè)路徑,也就是告訴編譯器:“你要是發(fā)現(xiàn)未定義的函數(shù),就去這個(gè) 路徑里找找”。

所以我們來(lái)看看這個(gè)libm.so到底在哪兒

locate?libm.so

然后我們編譯時(shí)加入這個(gè)path

gcc?sin.c?-lm?-L/usr/lib64

-l是說(shuō)要增加library

-m是說(shuō)尋找名字叫做libm.so的東西,lib是大多數(shù)庫(kù)文件的前綴所以我們省掉了。

-L+path就是說(shuō)讓gcc到這個(gè)path下面來(lái)找

這里會(huì)爆出一個(gè)warning,但是沒(méi)關(guān)系,只要不是error就好,可以看到已經(jīng)生成了我們想要的a.out

執(zhí)行它,就得到了我要的滑板鞋,不對(duì),這都是哪跟哪兒啊……就得到了我要的0.5

所以其實(shí)說(shuō)到這里,大家應(yīng)該都知道一個(gè)軟件從源碼到可執(zhí)行文件應(yīng)該怎么安裝了。要是你閑的蛋疼,可以嘗試一下用gcc手動(dòng)安裝mysql,不過(guò)我祝你幸?!?/p>

說(shuō)了這么多其實(shí)我都在為make做鋪墊,可以想象啊,一個(gè)軟件包里的源文件,可能會(huì)調(diào)用各種系統(tǒng)的庫(kù)函數(shù),也會(huì)有相互的依賴關(guān)系,那么我們手動(dòng)編譯起來(lái)就會(huì)特別麻煩。make就是來(lái)簡(jiǎn)化以上操作的。


make具體干了些神馬呢?

首先,make會(huì)在當(dāng)前目錄下尋找一個(gè)叫做Makefile的文件,比如我們有如下的源文件

然后我們新建一個(gè)Makefile,編輯它

注意,命令行(2,3行)必須以tab開(kāi)頭

接下來(lái)執(zhí)行make

可以看到整個(gè)過(guò)程一氣呵成啊。

所以你知道m(xù)ake的方便了吧,一條指令就搞定了所有。

但是又有同學(xué)問(wèn)了,我寫shell腳本不也能做到嗎?確實(shí)能做到,但make還有個(gè)強(qiáng)大的功能——diff,用過(guò)git的同學(xué)都知道,diff用來(lái)判斷修改過(guò)的文件,那么make只會(huì)去重新編譯修改過(guò)的部分,這會(huì)節(jié)約很多時(shí)間。

那 又有好奇的同學(xué)要問(wèn)了,這個(gè)Makefile還不是得寫,我寫一遍Makefile還是得花好長(zhǎng)時(shí)間啊!這個(gè)不用咱們擔(dān)心,這是軟件提供者需要干的。但是 軟件提供者也不會(huì)直接給我們寫Makefile,想一想原因也很簡(jiǎn)答。例如上面的-L/usr/lib64,libm.so在我的電腦里在這個(gè)路徑中,但 是其它的可能不這樣,要是Makefile寫死了不就完蛋了嗎?

所以就有了./configure。這是個(gè)檢測(cè)腳本,用來(lái)檢測(cè)咱們的系統(tǒng)有 沒(méi)有安裝軟件需要的庫(kù)函數(shù)(某個(gè)需要的庫(kù)函數(shù)都會(huì)去默認(rèn)的路徑下找),要是缺少某些庫(kù)函數(shù),那么軟件安裝就不能成功。所以啊,大家可能都能理解 了./configure里有時(shí)候會(huì)加上 --xxx=/usr/local是什么意思了吧(xxx庫(kù)或者依賴包去/usr/local里去找),那么如果./configure提示我們?nèi)鄙倌承?依賴,大家就知道該怎么辦了嗎?當(dāng)然是缺哪個(gè)就locate一下那個(gè)文件的路徑然后在./configure的命令中加上路徑作為參數(shù)咯。那要是 locate沒(méi)有需要的依賴,再自己去網(wǎng)上下載并安裝,這又是一個(gè)相同的過(guò)程(有木有遞歸的感覺(jué))

那么如果./configure成功了, 我們就可以用make來(lái)編譯和鏈接了。有同學(xué)又要問(wèn)了,你說(shuō)了./configure,但是make是需要Makefile的呀!不要急,. /configure這個(gè)檢測(cè)腳本如果檢測(cè)成功了,就會(huì)自動(dòng)生成Makefile,至于怎么生成,生成內(nèi)容是什么,這是軟件開(kāi)發(fā)者的事兒,那你要是有興趣 可以打開(kāi)看看。

所以接下來(lái)我們執(zhí)行make,然后就會(huì)看到一溜的刷屏,這其實(shí)就是make在幫咱們挨個(gè)編譯源文件然后鏈接它們。

make 結(jié)束以后呢我們可以執(zhí)行make install,make install會(huì)在Makefile里找對(duì)應(yīng)的參數(shù),然后把make成功的可執(zhí)行文件放到Makefile指定的路徑。如果我們不make install,那么生成的可執(zhí)行文件就依然還在我們當(dāng)前目錄下。

這便是源碼安裝軟件的整個(gè)過(guò)程了。


所以總結(jié)一下,其實(shí)最重要的一步就是./configure和./configure出錯(cuò)了怎么解決。大家理解了之后可以試著去源碼安裝一下LNMP,幫助加深印象。希望本文對(duì)大家有所幫助,3Q~


轉(zhuǎn)載于:https://blog.51cto.com/8718813/1619042

總結(jié)

以上是生活随笔為你收集整理的Linux【学习心得】深入剖析软件的源码安装的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。