如何在Linux中進(jìn)行C語(yǔ)言多文件編譯

今天寫C語(yǔ)言的時(shí)候,我突然遇到需要做一個(gè)項(xiàng)目.以前沒有接觸過(guò),通過(guò)簡(jiǎn)單的了解,Windows下可以通過(guò)IDE來(lái)進(jìn)行共同編譯 vs就是很好的選擇.
而我們今天討論的重點(diǎn)是如何在Linux中進(jìn)行多文件編譯,一般簡(jiǎn)單的項(xiàng)目會(huì)有三個(gè)文件 (xxx.c ,xxx.c,xxx.h)其中一個(gè)執(zhí)行程序主要功能,一個(gè)描述抽象數(shù)據(jù)類型的函數(shù),一個(gè)進(jìn)行函數(shù)原型的聲明,在Linux下,大家都是手動(dòng)達(dá)人,我們?cè)诰幾g的時(shí)候是需要把怎么編譯都寫出來(lái),比如編譯順序,那個(gè)文件和那個(gè)文件進(jìn)行鏈接,那些文件在什么情況下需要重新編譯等等,或者一些更加復(fù)雜的操作,用來(lái)寫這些具體操作的文件就是這個(gè)項(xiàng)目的makefile.
而且,我們?cè)趯懞昧艘粋€(gè)makefile之后就可以自動(dòng)編譯了,只需用一個(gè)make命令就行.而且更加建議先學(xué)了makefile之后用IDE,因?yàn)閷W(xué)習(xí)了mmakefile之后你就對(duì)其中怎樣把編程語(yǔ)言變成可執(zhí)行程序有了更加深刻的理解,基礎(chǔ)更加扎實(shí).好了,接下來(lái)我們就來(lái)一起看看怎么寫Makefile,
我是以c語(yǔ)言作為源碼,編譯器是Ubuntu 下默認(rèn)的gcc.

首先我們來(lái)聊聊有關(guān)程序的編譯和鏈接 無(wú)論是 C场刑、 C++伊履、還是 pas巴刻,首先要把源文件編譯成中間代碼文件,在 Windows 下也就是 .obj 文件,UNIX 下是 .o 文件,即 Object File,這個(gè)動(dòng)作叫做編譯( compile)世吨。然后再把大量的 Object File合成執(zhí)行文件,這個(gè)動(dòng)作叫做鏈接( link),windows下大部分的IDE都將這兩個(gè)動(dòng)作結(jié)合成一個(gè)并且集合到一個(gè)快捷鍵上,這樣對(duì)初學(xué)者友好但是對(duì)于深刻理解缺有點(diǎn)缺陷呻征。
Makefile就是一個(gè)怎樣編譯多文件的腳本,我們寫好之后在終端下輸入make 這個(gè)命令就可以開始編譯了.

target ... : prerequisites ... command ... ...
形如這樣的就是一個(gè)Makefile,其中 target 也就是一個(gè)目標(biāo)文件耘婚,可以是 Object File,也可以是執(zhí)行文件陆赋。還可以是一個(gè)標(biāo)簽( Label)沐祷。prerequisites 就是,要生成那個(gè) target 所需要的文件或是目標(biāo)攒岛。command 也就是 make 需要執(zhí)行的命令赖临。(任意的 Shell 命令)
這 是 一 個(gè) 文 件 的 依 賴 關(guān) 系 , 也 就 是 說(shuō) 灾锯, target 這 一 個(gè) 或 多 個(gè) 的 目 標(biāo) 文 件 依 賴 于prerequisites 中 的 文 件 兢榨, 其 生 成 規(guī) 則 定 義 在 command 中 。 說(shuō) 白 一 點(diǎn) 就 是 說(shuō) ,prerequisites 中如果有一個(gè)以上的文件比 target 文件要新的話吵聪, command 所定義的命令就會(huì)被執(zhí)行凌那。這就是 Makefile 的規(guī)則。
好了,我說(shuō)完了,Makefile的核心內(nèi)容就是這樣了,

Image.png

這就是一個(gè)實(shí)例,其中film 就是編譯之后要生成的文件,它依賴的就是后面的film4.c ,list.c和list.h這三個(gè)文件.
make 的具體工作方式是這樣,當(dāng)你在默認(rèn)界面或者是終端中輸入了make命令之后,

make 會(huì)在當(dāng)前目錄下找名字叫“ Makefile”或“ makefile”的文件
如果找到吟逝,它會(huì)找文件中的第一個(gè)目標(biāo)文件( target)帽蝶,在上面的例子中,他會(huì)找到“ film”這個(gè)文件块攒,并把這個(gè)文件作為最終的目標(biāo)文件励稳。
如果 film 文件不存在,或是 film 所依賴的后面的文件的文件修改時(shí)間要比f(wàn)ilm這個(gè)文件新囱井,那么驹尼,他就會(huì)執(zhí)行后面所定義的命令來(lái)生成 film這個(gè)文件。

好了,這樣就通過(guò)編譯器生成了film 這個(gè)文件.
Makefile中還可以使用變量,讓我們看這樣一個(gè)例子,

edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o

我們可以看到[.o]文件的字符串被重復(fù)了兩次琅绅,如果我們的工程需要加入一個(gè)新的[.o]文
件扶欣,那么我們需要在兩個(gè)地方加,但如果 makefile 變得復(fù)雜鹅巍,那么我們就有可能會(huì)忘掉一個(gè)需要加入的地方千扶,而導(dǎo)致編譯失敗所以,為了 makefile 的易維護(hù)骆捧,在 makefile 中我們可以使用變量澎羞。 makefile 的變量也就是一個(gè)字符串,理解成 C語(yǔ)言中的宏可能會(huì)更好敛苇。比如妆绞,我們聲明一個(gè)變量,叫 objects, OBJECTS, objs, OBJS, obj, 或是 OBJ枫攀,反
正不管什么啦括饶,只要能夠表示 obj 文件就行了。我們?cè)?makefile 一開始就這樣定義:

objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o

于是来涨,我們就可以很方便地在我們的 makefile 中以“ $(objects)”的方式來(lái)使用這個(gè)變
量了图焰,于是我們的改良版 makefile 就變成下面這個(gè)樣子:

objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects)

如果有新的.o文件加入,我們只用在開始的變量聲明中修改就可以了.
最后我告訴大家一下Makefile的書寫規(guī)則
它的語(yǔ)法就是下面這個(gè)樣子

targets : prerequisites command ...
或是這樣:
targets : prerequisites ; command command ...

targets 是文件名,以空格分開蹦掐,可以使用通配符技羔。一般來(lái)說(shuō),我們的目標(biāo)基本上是一個(gè)文件卧抗,但也有可能是多個(gè)文件藤滥。command 是命令行,如果其不與“ target:prerequisites”在一行社裆,那么拙绊,必須以[Tab鍵]開頭,如果和 prerequisites 在一行,那么可以用分號(hào)做為分隔标沪。(見上)prerequisites 也就是目標(biāo)所依賴的文件(或依賴目標(biāo))张漂。如果其中的某個(gè)文件要比目標(biāo)文件要新,那么谨娜,目標(biāo)就被認(rèn)為是“過(guò)時(shí)的”航攒,被認(rèn)為是需要重生成的。這個(gè)在前面已經(jīng)講過(guò)了趴梢。如果命令太長(zhǎng)漠畜,你可以使用反斜框(‘ \’)作為換行符。 make 對(duì)一行上有多少個(gè)字符沒有限制坞靶。規(guī)則告訴 make 兩件事憔狞,文件的依賴關(guān)系和如何成成目標(biāo)文件。
一般來(lái)說(shuō)彰阴, make 會(huì)以 UNIX 的標(biāo)準(zhǔn) Shell瘾敢,也就是/bin/sh 來(lái)執(zhí)行命令。
好了,簡(jiǎn)單的Makefile的就到這,看過(guò)這個(gè)之后大家就學(xué)會(huì)在linux下進(jìn)行件簡(jiǎn)單的工程的編譯,如果想要對(duì)于Makefile進(jìn)行系統(tǒng)的學(xué)習(xí)可以去參考一下相關(guān)的書籍.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尿这,一起剝皮案震驚了整個(gè)濱河市簇抵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌射众,老刑警劉巖碟摆,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異叨橱,居然都是意外死亡典蜕,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門罗洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)愉舔,“玉大人,你說(shuō)我怎么就攤上這事伙菜⌒停” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵仇让,是天一觀的道長(zhǎng)典奉。 經(jīng)常有香客問(wèn)我,道長(zhǎng)丧叽,這世上最難降的妖魔是什么卫玖? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮踊淳,結(jié)果婚禮上假瞬,老公的妹妹穿的比我還像新娘陕靠。我一直安慰自己,他們只是感情好脱茉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布剪芥。 她就那樣靜靜地躺著,像睡著了一般琴许。 火紅的嫁衣襯著肌膚如雪税肪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天榜田,我揣著相機(jī)與錄音益兄,去河邊找鬼。 笑死箭券,一個(gè)胖子當(dāng)著我的面吹牛净捅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辩块,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼蛔六,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了废亭?” 一聲冷哼從身側(cè)響起国章,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滔以,沒想到半個(gè)月后捉腥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氓拼,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡你画,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了桃漾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坏匪。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖撬统,靈堂內(nèi)的尸體忽然破棺而出适滓,到底是詐尸還是另有隱情,我是刑警寧澤恋追,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布凭迹,位于F島的核電站,受9級(jí)特大地震影響苦囱,放射性物質(zhì)發(fā)生泄漏嗅绸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一撕彤、第九天 我趴在偏房一處隱蔽的房頂上張望鱼鸠。 院中可真熱鬧,春花似錦、人聲如沸蚀狰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)麻蹋。三九已至跛溉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扮授,已是汗流浹背倒谷。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糙箍,地道東北人渤愁。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像深夯,于是被迫代替她去往敵國(guó)和親抖格。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容