Makefile寫法小結


Makefile的寫法入門心得

 

Makefile的出現使得編譯過程極大地自動化了,省去了很多人工工作,非常方便。這里,小結一下寫Makefile的一點小心得。嗯,對了,差點忘了一件事,同一個Makefile在不同的內核版本和Linux發行版本中不一定能發揮一樣的作用,別人的Makefile可不見得就適用於自己的機器。

我先簡單說一下我自己的機器: Ubuntu12.04-Kernel-3.4.5,內核是根據我自己機器的配置裁剪過的,不過估計這個影響不大,當然,大神們就別批小弟了,咱的水平還不至於寫非常貼近底層的東西。

好了,開始介紹。

下面是一個在網上非常泛濫的模板,雖然泛濫,但就是沒有一個人把這個模版做一個剖析,我這個菜鳥就勉強試一試好了。事前說明:如果在每一段的最前面有空格的,記住那是tab鍵,是Makefile里面專門用於寫命令時固定的格式:

 

#Source file
SRC = ThreadQueue.cpp
#Object file
OBJ = $(SRC:.cpp=.o)
#Output execution file
PROGRAM = ThreadQueue
#Compiler
CC = g++


#Include
INCLUDE = -I/usr/include/ncurses –I/usr/include/
#Linker Parameter
LINKPARAM = -lpthread -lncurses
#Options for development
#CFLAGS = -g

#Options for release
CFLAGS = -o


all: $(PROGRAM)

$(PROGRAM): $(OBJ)

    $(CC) -o $(PROGRAM) $(LINKPARAM) $(OBJ)

.SUFFIXES : .cpp

.cpp.o:

    $(CC) $(INCLUDE) $(CFLAGS) -c $<

clean:
    -rm *.o

下面一行一行的來解析這個makefile。

首先解釋第一行以及好多行都出現的“#”號,注釋,完全是注釋,跟C語言中的//是一樣的,在標准的Linux內核Makefile中有很多內容都是幫你理解的注釋。

第二行是一個變量的定義,變量名為SRC,變量定義為ThreadQueue.cpp,這樣要引用變量時寫作“$(變量名)”即可,就等價為變量的定義內容。

第三行注釋,讀讀就好。

第四行這里又定義了一個變量,請注意,它的定義引用了SRC變量,同時,用到了變量替換,這里

SRC:.cpp=.o的意思是指將SRC下所有以.cpp結尾的文件的.cpp替換為.o,也就定義了要輸出的所有文件。

第五行,注釋的說。

第六行是定義變量,這里順便再一提,這個就是我們在編譯過程中最后要得到的東西,即ThreadQueue.o。

第七行又是注釋的說。

第八行的變量定義是指CC代表的就是gcc編譯器。嗯,據我自己這幾天的經驗,絕大部分Makefile(包括標准的Linux Makefile)都是這么寫的。

第九行(這里是指有內容的第九行,不包括空行)注釋的說。

第十行,又是一個變量定義,這里就得交待一件事情了:在Makefile中變量的定義是很靈活的,基本可以理解為C語言下的宏定義,你定義神馬都可以,你可以用變量來定義一個文件名列表,定義一個可執行文件名,也可以把變量定義成編譯器命令選項。

第十一行,注釋的說。

第十二行,這里也是一個變量的定義,這個變量作為gcc編譯時的編譯器選項使用。

第十三至十五行皆是注釋,不過這三行以及下面的第十六行還是有其他作用的,待到十六行處再講。

第十六行,這里連帶着上面的三行一起講,看英文也應該看出來這里四行的作用了。是這樣的,如果你是想自己要調試用的話,你就保留“options for develop”下面的那一行,把之前的“#”號去掉,而你要是想生成不可調試的發行版,那就選擇讓第十六行生效。這里,為什么會有這樣的區別就涉及到gcc編譯器使用選項的問題了,留做他日再寫。

第十七行,all是一個標簽,你可以理解成一個跳轉符號,如果想讓make程序在編譯時執行某一個特定的指令,就可以把這個指令做成一個標簽,這樣在命令行里輸入“make Name_of_Your_Label”就可以執行某一特定部分的編譯了。

第十八、十九、二十行,來到這里就不得不提一般的Makefile的書寫格式了,這也是為什么我要把三行在一起交待,如下:

目標:依賴

    命令

    ……

必須注意的是,命令前面的不是空格,而是制表符Tab,這是Makefile書寫時必須遵循的規則。那我們看到上面的模板中,我們要生成的是PROGRAM所代表的變量,而所需要的依賴就是OBJ中所有的.o文件,生成時的命令是“$(CC) -o $(PROGRAM) $(LINKPARAM) $(OBJ)”,根據他們各自的變量定義可知,之一段命令可以翻譯為“gcc –o ThreadQueue -lpthread –lncurses ThreadQueue.o”,其中前面帶有-的幾個字母都是gcc編譯時的選項,改天再總結一下gcc編譯器的使用。

第二十一行,這里的“.SUFFIXES”是一個偽目標,它的作用類似於一個標簽,在偽目標之后的所有內容將不會被檢查是否已經執行,而是將它直接執行。

第二十二、二十三行,這里.cpp.o是老式的“后綴規則”,編譯器將會自動將.cpp識別為源文件后綴,而.o識別為輸出文件后綴。,SUFFIXES也是習慣上用來定義后綴規則的偽目標。特別需要注意的是,后綴規則不允許任何依賴文件,但也不能沒有命令。

第二十四、二十五行,這里定義了clean命令的執行規則,以及所要清除的文件的后綴名,如果你還想在clean時清除什么后綴的文件的話,就再寫上”*.post_name”即可,非常方便。

 

小結:Makefile的寫法還是比較復雜的,我這一篇文章只提及了很少的一點,給大家推薦一個人的博客,他曾經寫過《跟我一起學寫Makefile》,希望該大神的博客能對你有所幫助:http://blog.csdn.net/haoel/article/details/2886

 

 

 

By Air_Figher

12.07.21


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM