工程中編寫自己的Makefile---1 一些基本概念

本文是基於網上的一系列文章,加上自己的一些看法,提煉精簡而構成的;

參考文章有如下:

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

1vpath <pattern><directories>

爲符合模式<pattern>的文件指定搜索目錄<directories>

2vpath <pattern>   清除符合模式<pattern>的文件的搜索目錄。

3Vpath                  清除所有已被設置好了的文件搜索目錄。

例如:

vpath  %.h  ../headers:work

該語句表示,要求make ../headerswork兩個目錄下搜索所有以“.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>

1targets定義了一系列的目標文件,可以有通配符。是目標的一個集合(目標集)

2target-parrtern是指明瞭targets的模式,也就是的目標集模式(目標模式)

3prereq-parrterns是目標的依賴模式(依賴模式),它對target-parrtern形成的模式再進行一次依賴目標的定義。

foo.o bar.o: %.o: %.c

$(CC) -c $< -o $@ $(CFLAGS)

1.7             主Makefile中調用其他文件夾下的子makefile

cd subdir && $(MAKE)

         或者

$(MAKE) -C subdir

若要調用子makefileclean(僞目標)

$(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。


發佈了51 篇原創文章 · 獲贊 106 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章