本文是基於網上的一系列文章,加上自己的一些看法,提煉精簡而構成的;
參考文章有如下:
http://www.cnblogs.com/OpenShiFt/p/4313351.html
http://blog.csdn.net/cjsycyl/article/details/47946039
http://blog.csdn.net/wangzhen209/article/details/47153239
還有大神陳浩的文章
http://blog.csdn.net/haoel/article/details/2886
1 一些基本的知識
1.1 常用的交叉編譯工具選項
-ofile :指定輸出的文件爲file,但只能指定一個輸出文件
-c :編譯或彙編源文件,但不做連接,編譯器輸出對應於源文件的目標文件(.o文件)
-I(大寫i)dir :在頭文件的搜索路徑列表中添加dir目錄
-L(大寫l)dir :常接”-L”指定的庫文件搜索路徑
-l(小寫l)libname:指定期望連接的庫的名字,注意!!!文件的順序就是鏈接的順序
例如:
gcc -o hello.o -c hello.c -I/opt/hello/include -L/opt/hello/lib-lworld
-ohello.o :指定輸出文件爲hello.o
-c :編譯或彙編源文件,但不做連接
-I/opt/hello/include:源文件hello.c中用到的頭文件的搜索路徑
-L/opt/hello/lib :源文件hello.c中用到的庫文件的搜索路徑
-lworld :表示在上面的lib的路徑中尋找libworld.so動態庫文件,注意!!!去掉了字符“lib”, 如果編譯選項中加入了“-static”表示尋找libworld.a靜態庫文件;
1.2 Makefile書寫規則
1,命令必須以[Tab鍵]開頭
2,在 include 前面可以有一些空字符,但是絕不能是[Tab]鍵開始
3,定義變量的語句,等號兩端可有空格,最後不要空格(特別是目錄);建議[MYNAME := wzt]
4,如果想要讓上一條命令的結果應用在下一條命令時,這兩條命令寫同一行並用分號分隔
1.3 Makeflie中一些常用字符含義
1,- :命令前面加了一個小減號,標記爲不管命令出不出錯都認爲是成功的
2,@ :用“@”字符在命令行前,這個命令將不被 make 顯示出來
3,$< :自動化變量,表示所有的依賴目標集
4,$@ :自動化變量,表示目標集
5,$$$$ :意爲一個隨機編號
1.4 Make參數
1,-n:只顯示命令,但不執行命令,利於調試Makefile,看看命令執行起來是什麼順序
2,-s:全面禁止命令的顯示
3,-f:運行指定的 Makefile,例如:make -f make.linux
1.5 變量
1.5.1 定義
1,”=”
MyName=$(Name)
Name=wzt
變量是可以使用後面的變量來定義的(遞歸調用容易出問題)
2,”:=”
Name:=wzt
MyName:=$(Name)
前面的變量不能使用後面的變量,只能使用前面已定義好了的變量
推薦使用此種方法
3,”?=”
如果 FOO 沒有被定義過,那麼變量 FOO 的值就是“bar”
如果 FOO 先前被定義過,那麼這條語將什麼也不做
4,”+=”
追加變量值
objects = main.o foo.o bar.o utils.o
objects += another.o
1.5.2 變量高級用法
1,變量值的替換(類似靜態模式)
$(var:a=b)
把變量“var”中所有以“a”字串“結尾”的“a”替換成“b”字串。這裏的“結尾”意思是“空格”或是“結束符”
2,把變量的值再當成變量
x = y
y = z
a := $($(x))
有$(a)=z
1.5.3 VPATH
若未指明此變量,make只會在當前的目錄中去找尋依賴文件和目標文件,一般用來指明源文件的位置(即.c文件),頭文件一般使用編譯選項-Idir指明
1.5.4 vpath
1,vpath <pattern><directories>:
爲符合模式<pattern>的文件指定搜索目錄<directories>
2,vpath <pattern>: 清除符合模式<pattern>的文件的搜索目錄。
3,Vpath: 清除所有已被設置好了的文件搜索目錄。
例如:
vpath %.h ../headers:work
該語句表示,要求make在 ../headers和work兩個目錄下搜索所有以“.h”結尾的文件
1.5.5 系統預定義變量
變量名 |
含 義 |
默 認 值 |
AR |
生成靜態庫庫文件的程序名稱 |
ar |
AS |
彙編編譯器的名稱 |
as |
CC |
C語言編譯器的名稱 |
cc |
CPP |
C語言預編譯器的名稱 |
\$(CC) -E |
CXX |
C++語言編譯器的名稱 |
g++ |
FC |
FORTRAN語言編譯器的名稱 |
f77 |
RM |
刪除文件程序的名稱 |
rm -f |
ARFLAGS |
生成靜態庫庫文件程序的選項 |
無默認值 |
ASFLAGS |
彙編語言編譯器的編譯選項 |
無默認值 |
CFLAGS |
C語言編譯器的編譯選項 |
無默認值 |
CPPFLAGS |
C語言預編譯器的編譯選項 |
無默認值 |
CXXFLAGS |
C++語言編譯器的編譯選項 |
無默認值 |
FFLAGS |
FORTRAN語言編譯器的編譯選項 |
無默認值 |
1.6 靜態模式
靜態模式可以更加容易地定義多目標的規則,可以讓我們的規則變得更加的有彈性和靈活
格式:
<targets ...>: <target-pattern>:<prereq-patterns ...>
<commands>
1,targets定義了一系列的目標文件,可以有通配符。是目標的一個集合(目標集)。
2,target-parrtern是指明瞭targets的模式,也就是的目標集模式(目標模式)。
3,prereq-parrterns是目標的依賴模式(依賴模式),它對target-parrtern形成的模式再進行一次依賴目標的定義。
foo.o bar.o: %.o: %.c
$(CC) -c $< -o $@ $(CFLAGS)
1.7 主Makefile中調用其他文件夾下的子makefile
cd subdir && $(MAKE)
或者
$(MAKE) -C subdir
若要調用子makefile的clean(僞目標),
$(MAKE) clean -C subdir
若要傳遞變量到下級Makefile中
export <variable ...>
export variable := value
其等價於:
variable := value
export variable
1.8 Makefile常用函數
函數調用,很像變量的使用,也是以“$”來標識的,其語法爲:$( )或${ }。
1.8.1 wildcard
原型:$(wildcard PATTERN)
功能:獲取匹配模式的文件名
說明:這個函數的功能是查找當前目錄下所有符合模式 PATTERN 的文件名,其返回值是以空格分割的,當前目錄下的所有符合模式 PATTERN 的文件名列表。
例如:
如下模式返回當前目錄下所有擴展名位 .c 的文件列表。
$(wildcard *.c)
1.8.2 patsubst
原型:$(patsubst pattern, replacement, text)
功能:模式替換函數
說明:函數功能是查找字符串 text 中按照空格分開的單詞,將符合模式 pattern 的字符串替換成 replacement。 Pattern 中的模式可以使用通配符,當 pattern 和 replacement 中都有 % 時,符合條件的字符將被 replacement 中的替換。函數的返回值是替換後的新字符串。
例如:
需要將 C 文件替換爲 .o 的目標文件可以使用如下模式:
$(patsubst%.c, %.o, add.c)
上面的模式將 add.c 字符串作爲輸入,當擴展名爲 .c 時符合模式 %.c ,其中 % 在這裏代表 add,替換爲 add.o,並作爲輸出字符串。
$(patsubst%.c, %.o, $(wildcard *.c))
輸出的字符串將當前擴展名爲 .c 的文件替換成 .o 的文件列表。
1.8.3 foreach
原型:$(foreach VAR, LIST, TEXT)
功能:循環函數
說明: foreach 將 LIST 字符串中一個空格分割的單詞,先傳給臨時變量 VAR ,然後執行 TEXT 表達式,TEXT 表達式處理結束後輸出。其返回值是空格分割表達式 TEXT 的計算結果。
例如:
對於存在 add 和 sub 的兩個目錄,設置 DIRS 爲 "add sub ./" 包含目錄 add、sub 和當前目錄。表達式$(wildcard $(dir)/*.c) ,可以取出目錄 add 和 sub 及當前目錄中的所有擴展名爲 .c 的C語言源文件:
DIRS = subadd ./
FILES =$(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
1.8.4 filter
原型:$(filter PATTERN…,TEXT)
功能:過濾函數
說明:過濾掉字串“TEXT”中所有不符合模式“PATTERN”的單詞,保留所有符合此模式的單詞。可以使用多個模式。模式中一般需要包含模式字符“%”。存在多個模式時,模式表達式之間使用空格分割。一般用來去除一個變量中的某些字符串
返回值:空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。
例如:
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
使用“$(filter %.c%.s,$(sources))”的返回值給 cc 來編譯生成目標“foo”,函數返回
值爲“foo.c bar.c baz.s”
1.8.5 subst
原型:$(subst FROM, TO, TEXT),
功能:替換函數
說明:即將字符串TEXT中的子串FROM變爲TO。