如何在Linux中進行C語言多文件編譯

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

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

target ... : prerequisites ... command ... ...
形如這樣的就是一個Makefile,其中 target 也就是一個目標文件,可以是 Object File,也可以是執(zhí)行文件。還可以是一個標簽( Label)。prerequisites 就是,要生成那個 target 所需要的文件或是目標。command 也就是 make 需要執(zhí)行的命令。(任意的 Shell 命令)
這 是 一 個 文 件 的 依 賴 關 系 , 也 就 是 說 , target 這 一 個 或 多 個 的 目 標 文 件 依 賴 于prerequisites 中 的 文 件 , 其 生 成 規(guī) 則 定 義 在 command 中 。 說 白 一 點 就 是 說 ,prerequisites 中如果有一個以上的文件比 target 文件要新的話, command 所定義的命令就會被執(zhí)行。這就是 Makefile 的規(guī)則。
好了,我說完了,Makefile的核心內(nèi)容就是這樣了,

Image.png

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

make 會在當前目錄下找名字叫“ Makefile”或“ makefile”的文件
如果找到,它會找文件中的第一個目標文件( target),在上面的例子中,他會找到“ film”這個文件,并把這個文件作為最終的目標文件。
如果 film 文件不存在,或是 film 所依賴的后面的文件的文件修改時間要比film這個文件新,那么,他就會執(zhí)行后面所定義的命令來生成 film這個文件。

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

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]文件的字符串被重復了兩次,如果我們的工程需要加入一個新的[.o]文
件,那么我們需要在兩個地方加,但如果 makefile 變得復雜,那么我們就有可能會忘掉一個需要加入的地方,而導致編譯失敗所以,為了 makefile 的易維護,在 makefile 中我們可以使用變量。 makefile 的變量也就是一個字符串,理解成 C語言中的宏可能會更好。比如,我們聲明一個變量,叫 objects, OBJECTS, objs, OBJS, obj, 或是 OBJ,反
正不管什么啦,只要能夠表示 obj 文件就行了。我們在 makefile 一開始就這樣定義:

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

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

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ī)則
它的語法就是下面這個樣子

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

targets 是文件名,以空格分開,可以使用通配符。一般來說,我們的目標基本上是一個文件,但也有可能是多個文件。command 是命令行,如果其不與“ target:prerequisites”在一行,那么,必須以[Tab鍵]開頭,如果和 prerequisites 在一行,那么可以用分號做為分隔。(見上)prerequisites 也就是目標所依賴的文件(或依賴目標)。如果其中的某個文件要比目標文件要新,那么,目標就被認為是“過時的”,被認為是需要重生成的。這個在前面已經(jīng)講過了。如果命令太長,你可以使用反斜框(‘ \’)作為換行符。 make 對一行上有多少個字符沒有限制。規(guī)則告訴 make 兩件事,文件的依賴關系和如何成成目標文件。
一般來說, make 會以 UNIX 的標準 Shell,也就是/bin/sh 來執(zhí)行命令。
好了,簡單的Makefile的就到這,看過這個之后大家就學會在linux下進行件簡單的工程的編譯,如果想要對于Makefile進行系統(tǒng)的學習可以去參考一下相關的書籍.

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容