Makefile和Make Ruleslinux
多模塊軟件、依賴樹和Makeshell
默認規則函數
Make使用程序對簡單變量的支持學習
內建變量ui
虛目標spa
特殊目標命令行
通常性語法錯誤及其糾正措施調試
命令行的使用和調試code
Makefile中經常使用規則總結server
make經常使用選項
-d 顯示調試信息
-f 指定從哪一個文件中讀取依賴關係信息。默認文件是「Makefile」或「makefile」 ,"-"表示從標準輸入
-h 顯示全部的Makefile的help信息
-n 打印全部Makefile執行命令,但不執行這些命令
-s 運行時不顯示任何信息
註釋
#
鏈接符
\
關聯列表和命令列表中使用shell通配符
?
*
默認模式規則
%.o:%.c:
$(CC) $(CFLAGS) -c $<
%.o:%.s:
$(AS) $(ASFLAGS) -o $@ $<
簡單變量
定義:變量名:=文本
添加:變量名+=文本
變量引用
$(變量名)
${變量名}
$單字符變量
C := gcc $C
CC := gcc OPTIONS := -O3 OBJECTS :=main.o OBJECTS := input.o compute.o SOURCE :=main.c input.c compute.c HEADERS := main.h input.h compute.h power: $(OBJECTS) $(CC) $(OPTIONS) $(OBJECTS) -o power -lm main.o: main.h input.h compute.h #包含隱含規則 input.o: input.h compute.o: compute.h tar: Makefile $(HEADERS) $(SOURCES) #僞目標tar用於打包Makefile和源文件頭文件 tar -cvf power.tar Makefile $(HEADERS) $(SOURCES) clean: rm *.o
內置變量
$@ 當前目標的名稱
$? 比當前目標更加新的已修改的依賴性列表
$< 比當前目標更新的已修改的當前依賴性名稱
$^ 用空格分開的全部依賴性列表
@echo "Build complete" power: $(OBJECTS) $(CC) $(OPTIONS) -O $@ $^ -lm @echo "The executable is in the power file." main.o: main.h input.h compute.h compute.o: compute.h input.o: input.h power.tar: Makefile $(HEADERS) $(SOURCES) tar -cvf $@ $^ .PHONY:clean clean: rm -f *.o power
虛目標
容許強制執行某些在正常規則中不會發生的事件。
好比:能夠經過設置一個虛目標生成多個可執行文件,若不使用虛目標,make就只能創建第一個目標。
.PHONY: rebuild-all rebuild-all:prog1 prog2 prog3 prog1: prog1.o utils.o cc -o prog1 prog1.o utils.o prog2: prog2.o cc -o $@ $^ prog3: prog3.o sort.o utils.o cc -o $@ $^
常見虛目標列表
all 生成工程中全部能夠執行者,一般是Makefile的第一個生成目標
$make all #使目標所有被執行
clean 刪除make all生成的全部文件
install 在系統目錄中安裝工程項目生成的可執行文件和文檔
uninstall 刪除make install 安裝的全部文件
$cat Makefile
INSTALLDIR=/home/embedclub/bin install: client server cp -f $^ $(INSTALLDIR) rm -f *.o $^ cd $(INSTALLDIR); chmod 755 $^ uninstall: cd $(INSTALLDIR); rm client server client: client.o miscc.o rcopyc.o gcc client.o miscc.o rcopyc.o -lnsl -o client \ client.o: client.c netc.h rcopy.h rcopy.h gcc -c client.c
$make install
$make uninstall
通常性語法錯誤
1 缺乏Tab鍵,可以使用cat -t Makefile查看tab鍵位置
2 在鏈接符和換行符之間插入了空格,可以使用cat -e Makefile查看換行符位置
顯示Makefile中不正確的行 grep '\\[]$' Makefile
使用非標準的Makefile名稱文件
$make -f prog1.makefile
從標準輸入讀取
$make -f -
顯示Makefile中所執行命令的順序
$make -n
製做工程文件的Makefile
通常的工程文件proc組成:
src:main.c fun1.c fun2.c
include:fun1.h fun2.h
Makefile
$cat Makefile
VPATH = src:include all:test4 tar .PHONY:all test4:main.o fun1.o fun2.o gcc main.o fun1.o fun2.o -o test4 main.o:main.c gcc -c -linclude -o $@ $^ fun1.o: fun2.o: tar: tar cvf test4.tar src include Makefile .PHONY:clean clean: rm *.o test4
Makefile編寫規則詳解
Make命令與Makefile
Makefile文件內容
顯示規則:說明了如何生成一個或多個目標文件(包括要生成的文件/文件的依賴文件/生成的命令)。
隱式規則
變量定義:通常是字符串,Makefile被執行時,其中變量都會拓展到相應的引用位。
文件指示: 1 在一個Makefile文件中引用另外一個Makefile文件 (相似include)
2 根據某些狀況指定makefile文件中的有效部分 (相似預編譯#if)
3 定義一個多行的命令
註釋: 註釋符#(Makefile文件中須要用到#,可使用\#轉義)
注意:
makefile文件的文件名能夠是其餘名稱,但要使用-f或--file指定
make工做執行步驟
1 讀入全部makefile文件
2 讀入被include包括的其餘makefile文件
3 初始化文件中的變量
4 推導隱式規則,並分析全部規則
5 爲全部目標文件建立依賴關係鏈
6 根據依賴關係,決定哪些目標要從新生成
7 執行生成命令
make參數 例子 做用
-f --file make -f makelinux 指定特定的makefile文件
-I --include-dir 在指定目錄下尋找makefile文件
-n --just-print 只是顯示->命令不執行命令
-s --silent 禁止命令的輸出顯示
makefile關鍵子 例子 做用
include include ../Make.defines 將別的makefile文件包含進來
include foo.make *.mk $(bar)
-include 不理會沒法找到的文件
wildcard objects:= $(wildcard *.o) 讓通配符在變量中展開,即讓objects的值成爲全部.o的文件名的集合
vpath <pattern> <directory> vpath %.h ../headers 爲符合模式<pattern>的文件指定搜素目錄
vpath %.c foo:bar
vpath blish 這兩句一塊兒用的話,表示.c結尾的文件先在foo,而後在bar,最後在blish中尋找
vpath <patterh> 清除符合模式<pattern>的文件的搜索目錄
vpath 清除全部已設置好的文件搜索目錄
定義環境變量 例子 做用
MAKEFILES 把此變量的值(其餘makefile,多個文件用空格分隔)做爲一個相似於include的動做
VPATH VPATH = src:../headers 讓make根據路徑尋找目標依賴文件,多個路徑用:隔開
自動變量
$@ 目標集
$< 全部的依賴目標集
Makefile書寫規則(裏面的命令實際上是shell命令)
通配符(定義一系列比較相似的文件)
* objects=*.o 全部的.o文件的集合
?
[]
~ ~/test 表示宿主主目錄下test文件
文件搜尋
VPATH
vpath 關鍵字
僞目標
.PHONY .PHONY: clean 僞目標能夠直接放在make後面像操做文件同樣操做
make clean
多目標
靜態模式
目標集合 目標集模式 目標集的二次定義
<targets ...>: <target-pattern>: <prereq-pattern>
<commands>
...
makefile文件的函數
filter
自動生成依賴關係
gcc -MM main.c //查找main.c文件包含的頭文件,並生成依賴關係
.d文件的應用
使用命令
顯示命令 @ehco (@避免輸出命令,只輸出命令執行結果)
執行命令
exec:
cd /home/hchen; pwd 第二條命令執行創建在第一條命令結果上
#僞目標一樣能夠存在依賴關係 .PHONY: cleanall cleanobj cleandiff cleanall: cleanobj cleandiff rm program cleanobj: rm *.o cleaniff: rm *.diff
#靜態模式 objects=foo.o bar.o all: $(objects) $(objects): %.o: %.c $(gcc) -c $(CFLAGS) $< -o $@ #展開後等價於 foo.o:foo.c $(gcc) -c $(CFLAGS) foo.c -o foo.o bar.o: bar.c $(gcc) -c $(CFLAGS) bar.c -o bar.o
學習積累
源文件:ChessBoard.h ChessBoard.cpp Player.h Player.cpp main.cpp
依賴關係:
ChessBoard.cpp 包含ChessBoard.h
Player.cpp 包含 Player.h
main.cpp 包含ChessBoard.h 和 Player.h
Makefile:
1 gomoku: ChessBoard.o Player.o main.o 2 g++ -o gomoku ChessBoard.o Player.o main.o 3 #main.o: main.cpp Player.h ChessBoard.h 4 # g++ -c $^ 5 #ChessBoard.o: ChessBoard.cpp ChessBoard.h 6 # g++ -c $^ 7 #Player.o: Player.cpp Player.h 8 # g++ -c $^ 9 10 #經過下面方法編譯器能夠自動推導 11 main.o: Player.h ChessBoard.h 12 ChessBoard.o: ChessBoard.h 13 Player.o: Player.h 14 15 .PHONY: clean allclean 16 clean: 17 rm *.o *.gch 18 allclean: 19 rm *.o *.gch gomoku