Makefile使用詳解

在 Linux(unix )環境下使用GNU 的make工具能夠比較容易的構建一個屬於你自己的工程,整個工程的編譯只需要一個命令就可以完成編譯、連接以至於最後的執行。不過這需要我們投入一些時間去完成一個或者多個稱之爲Makefile 文件的編寫。所要完成的Makefile 文件描述了整個工程的編譯、連接等規則。

makefile 帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make 命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。

默認的情況下,make命令會在當前目錄下按順序找尋文件名爲“GNUmakefile”、“makefile”、“Makefile”的文件,找到 後就解釋並執行該文件,如果找不到就提示錯誤並退出。一般Makeifle文件名我們會用Makefile或makefile,而不會使用 GNUmakefile。接下來我們以之前的靜態庫和動態庫爲例講解makefile的編寫和使用。

Makefile 主要的 5個部分 (顯示規則, 隱晦規則, 變量定義, 文件指示, 註釋)

  1. 變量的定義。在Makefile中我們要定義一系列的變量,變量一般都是字符串,這個有點像C語言中的宏,當Makefile被執行時,其中的變量都會被擴展到相應的引用位置上。
  2. 顯式規則。顯式規則說明了,如何生成一個或多的的目標文件。這是由Makefile的書寫者明顯指出,要生成的文件,文件的依賴文件,生成的命令。 剛纔寫的疑似shell腳本的Makefile全部都是顯示規則。
  3. 隱晦規則。由於我們的make有自動推導的功能,所以隱晦的規則可以讓我們比較粗糙地簡略地書寫Makefile,這是由make所支持的。
  4. 文件指示。其包括了三個部分,一個是在一個Makefile中引用另一個Makefile,就像C語言中的include一樣。
  5. 註釋。Makefile中只有行註釋,和UNIX的Shell腳本一樣,其註釋是用“#”字符,這個就像C/C++中的“//”一樣。如果你要在你的Makefile中使用“#”字符。

Makefile基本格式如下:

#以'#'開頭的行表示註釋
#定義變量VAR爲test,可以使用後面定義的變量
VAR = test
#定義變量VAR爲test,只能使用前面定義好的變量
VAR := test

# target第一條目標爲總的目標,
# depend依賴可以是文件(目錄)或爲其他目標
# 動作可以是Linux命令,動作的那一行必須以TAB鍵開頭
#目標必須得有:依賴和動作有一個即可     
target:	depend1  depend2 depend3 ... 
[TAB]  action1
[TAB]  action2
#每個動作必須以tab開頭
target1:
[TAB] action1 
[TAB] action2

  • target :總目標文件, 可以是 Object File, 也可以是可執行文件;
  • depend:生成 target 所需要的文件或者目標;
  • action:make需要執行的命令 (任意的shell命令), Makefile中的命令必須以 [tab]開頭。

常用命令:
make 找makefile或Makefile文件執行總的目標
make clean 執行makefile文件中的clean目標
make -C directory 進入到directory文件夾中去執行總的目標
make clean -C direcotry 進入到directory文件夾中去執行clean目標
make -f comm_makefile 通過-f選項指定一個makefile文件
make VAR=value 給Makefile傳一個參數VAR,其值爲value

Makefile 隱晦規則

由於僞目標的特性:總是被執行
這裏只列一個和編譯C相關的,
編譯C/C++時,xx.o 的目標會自動推導爲 xx.c/ xx.cpp

# Makefile 中
main : main.o
    gcc -o main main.o

#會自動變爲:
main : main.o
    gcc -o main main.o

#main.o 這個目標是隱含生成的
main.o: main.c   
    gcc -c main.c	

自動變量
在這裏插入圖片描述

直接上代碼比較直觀:

#最後形成的Makefile
INCL=-I${HOME}/incl
BIN=$(HOME)/bin
OBJ1=hellocpp.o
OBJ2=hello.o

#這個隱晦規則其實就是告訴大家,
#後綴爲cpp的文件怎麼編譯成.o 後綴爲c的文件怎麼編譯成.o
.SUFFIXES: .cpp .c
.cpp.o:
	g++ ${INCL} -c $<

.c.o:
	gcc ${INCL} -c $<

all: hellocpp hello

#C++編譯
hellocpp:${OBJ1}
	@echo "============開始編譯============"
	g++ -o $@ $?
	@rm -f ${OBJ1}
	@mv $@ ${BIN}
	@echo "============編譯結束============"
	@echo ""

#C編譯
hello:${OBJ2}
	@echo "============開始編譯============"
	gcc -o $@ $?
	@rm -f ${OBJ2}
	@mv $@ ${BIN}
	@echo "============編譯結束============"
	@echo ""

運行結果如圖:
在這裏插入圖片描述

更爲詳細的makefile使用,可以參考下面鏈接:

makefile經典教程,全部歸納成了一篇博客

經典教程原地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章