Makefile
本篇博客是作者在學習Linux方面知識過程中,對Makefile片面的了解,從而產生了對Makefile有一個全面的認識的想法,在知道《跟我一起寫Makefile》此書后,作者學習閱讀過程中整理出的筆記。
目錄
- Makefile
- makefile介紹:
- 規則:
- 示例:
- 使用變量:
- 自動推導:
- [.o]和[.h]的依賴文件收攏:
- 清空目標文件的規則:
- Makefile文件名:
- 引用其他Makefile
- 環境變量MAKEFILES
- make 的工作方式
makefile介紹:
make 命令執行時,需要一個 Makefile 文件,以告訴 make 命令需要怎么樣的去編譯和
鏈接程序。 規則是:
1)如果這個工程沒有編譯過,那么我們的所有 C 文件都要編譯并被鏈接。
2)某幾個 C 文件被修改,只編譯被修改的 C 文件,并鏈接目標程序。
3)頭文件被改變了,需要編譯引用了這幾個頭文件的 C 文件,并鏈接目標程序。
規則:
target … : prerequisites …
command
解釋:
target 也就是一個目標文件,可以是 Object File,也可以是執行文件。還可以是一個標簽(Label)。
prerequisites 是要生成那個 target 所需要的文件或是目標。
command是make需要執行的命令。
依賴關系:
target 這一個或多個的目標文件依賴于prerequisites 中的文件,其生成規則定義在 command 中。
示例:
edit : main.o command.o \
display.o
cc -o edit main.o command.o \
display.o
main.o : main.c defs.h
cc -c main.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
clean :
rm edit main.o command.o display.o \
反斜杠(\)是換行符的意思,便于 Makefile 的易讀,
目標文件(target)包含:執行文件 edit 和中間目標文件(*.o),
依賴文件(prerequisites)就是冒號后面的那些 .c 文件和 .h 文件
Tab 鍵作為開頭
make 并不管命令是怎么工作的,他只管執行所定義的命令,
Makefile 中只有行注釋,和 UNIX 的 Shell 腳本一樣,其注釋是用“#”字符。
clean 不是一個文件,它只不過是一個動作名字,類似于標簽(lable),
要執行其后的命令,就要在 make 命令后明顯得指出這個lable 的名字
使用變量:
如果 makefile 很復雜,那么我們就有可能會忘掉一個需要加入的地方,而導致編譯失敗。
為了 makefile 的易維護,在 makefile 中我們可以使用變量。makefile 的變量也就是一個字符串,可以理解成 C 語言中的宏。
objects = main.o command.o \
display.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.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
clean :
rm edit $(objects)
聲明一個變量,叫 objects,在 makefile 中以“$(objects)”的方式來使用這個變量,如果有新的 .o 文件加入,我們只需簡單地修改一下 objects 變量就可以了。
自動推導:
我們的 make 會自動識別,并自己推導命令。
只要 make 看到一個[.o]文件,它就會自動的把[.c]文件加在依賴關系中,如果 make找到一個 whatever.o,那么 whatever.c,就會是 whatever.o 的依賴文件。就不用寫cc -c whatever.c。
[.o]和[.h]的依賴文件收攏:
格式:
右邊對應每一個[.h]文件,左邊是需要右邊[.h]文件的對應的[.o]文件
示例:
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
這種風格,讓我們的 makefile 變得很簡單,但文件依賴關系有些凌亂。
一是文件的依賴關系看不清楚,二是如果文件一多,要加入幾個新的.o 文件。
清空目標文件的規則:
每個 Makefile 中都應寫一個清空目標文件(.o 和執行文件)的規則,這不僅便于重
編譯,也利于保持文件的清潔。
一般的風格是:
clean:
rm edit $(objects)
更為穩健的做法是:
.PHONY : clean
clean :
-rm edit $(objects)
.PHONY 意思表示 clean 是一個“偽目標”,。而在 rm 命令前面加了一個小減號的意思是,也許某些文件出現問題,但不管,繼續做后面的事。
clean 的規則不要放在文件的開頭,clean 放在文件的最后。
Makefile文件名:
默認的情況下,make 命令會在當前目錄下按順序找尋文件名為“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解釋這個文件。
在這三個文件名中,最好使用“Makefile”這個文件名,因為,這個文件名第一個字符為大寫,這樣有一種顯目的感覺。最好不要用“GNUmakefile”,這個文件是 GNU 的 make 識別的。
也可以使用別的文件名來書寫Makefile,
要指定特定的 Makefile,你可以使用 make 的“-f”和“–file”參數,
引用其他Makefile
在 Makefile 使用 include 關鍵字可以把別的 Makefile 包含進來,include 的語法是: include
filename 可以是當前操作系統 Shell 的文件模式(可以包含路徑和通配符)
在 include前面可以有一些空字符,但是絕不能是[Tab]鍵開始
include foo.make *.mk $(bar)
等價于:
include foo.make a.mk b.mk c.mk e.mk f.mk
如果文件都沒有指定絕對路徑或是相對路徑的話,make 會在當前目錄下首先尋找,
如果當前目錄下沒有找到,那么,make 還會在下面的幾個目錄下找:
1、如果 make 執行時,有“-I”或“–include-dir”參數,那么 make 就會在這個參數 所指定的目錄下去尋找。
2、目錄/include(一般是:/usr/local/bin 或/usr/include)存在的話,make 也會去找。
環境變量MAKEFILES
如果你的當前環境中定義了環境變量 MAKEFILES,那么,make 會把這個變量中的值做一個類似于 include 的動作。慎用。
make 的工作方式
make工作的執行步驟如下:
1、讀入所有的 Makefile。
2、讀入被 include 的其它 Makefile。
3、初始化文件中的變量。
4、推導隱晦規則,并分析所有規則。
5、為所有的目標文件創建依賴關系鏈。
6、根據依賴關系,決定哪些目標要重新生成。
7、執行生成命令。