工程構建 makefile 基礎知識點

2021-10-06 13:03:25 字數 2738 閱讀 8926

#1 make是乙個命令,他會按照自己的規則執行名字為makefile、makefile或者之類的名字,或者通過 make -f 1.txt 這樣來指定執行乙個檔案。

#2 make命令解析檔案的最基本、最重要的途徑就是如下格式:

: [tab]  

對上面這兩行**的解讀:

1 - 想要得到target,材料是prerequisites,工具是commands。

2 - target是必須的,prerequisites和commands至少要有乙個存在。

3 - target可以有多個,像prerequisites一樣,多個目標之間用空格分割。

#3 注意:makefile什麼都不是,我們面向的應該是make這個命令是如何使用的,makefile只是按照make命令要求寫的乙個標準格式檔案。

#4 偽目標(用來指定非編譯動作,因為正常情況下,make動作都會輸出目標檔案,如果我想做某個動作而不是輸出目標檔案,就要指定目標動作為偽目標)

clean:

rm -rf *

make動作是針對makefile(或者-f指定乙個檔案)中的「目標」而言的,如果不指定,那麼就取「第乙個目標」,如果指定,則取指定的目標。

針對上面這種情況,有乙個bug,如果當前目錄中有乙個叫做clean的檔案,那麼make就會以為下面的命令列是用來生成clean檔案的,所以不會再去執行。針對這種情況,

需要把clean明確指定為偽目標:            .phony:clean

clean:

rm -rf *

#5 前置條件(材料)

: [tab]  

只要前置條件列表和之前不一樣了,或者裡面的內容發生更新了,那麼就使用commands重新構建target。

注:如果某個target後面沒有前置條件,那麼每次執行make ,commands都一定會執行。

#6 再說偽目標

有時候也可以這樣用:當commands是空的時候,偽目標類似巨集定義,比如 all:1.c 2.c 3.c ,此時make或者make all,相當於make 1.c ,make 2.c , make 3.c

會依次執行all所指代的前置條件。

注:這也是幾乎所有makefile都在用的一點,需要輸出多個目標的時候,就先定乙個總的來代替多個目標

#7 命令

命令用來表示如何生成target,命令有一行或者多行「shell命令」組成。

預設情況下命令前面要有tab鍵,如果想換成別的,可以設定環境變數.recipeprefix,比如.recipeprefix = >

all:

> echo hello, world

#8 「命令」注意要點

命令可以有多行,但是不同於shell指令碼,這多行是由多個程序一起執行的,所以相互之間沒有關聯。比如:

all:

export a=1

echo $a

針對上面這個檔案,做make或者make all,無法正確獲得a的值。

可以用如下幾種方法來解決:

1 - 命令放在一行,用分號隔開

all:

export a=1;echo $a

2 - 命令放在不同的行,用\連線

all:

export a=1 \

echo $a

3 - 通過偽目標標註

.oneshell:

all:

export a=1

echo $a

#9 語法

#9-1  「回聲」

預設情況下,會向標準輸出列印每一條command。即使是以#開頭,都會列印(但是前置tab不可少,少了就不是command了)。這叫做「回聲」

如果想關閉,只需要在command前面加乙個@就行了。

實際工作過程中,一般會給command的注釋前面加上@

#9-2  「萬用字元」

和bash的萬用字元使用一樣,*,?,[1-2]等

#9-3  「模式匹配」

%.o: %.c代表對當前目錄下所有.c檔案做.o依賴,比如當前目錄下有1.c和2.c,那麼以上的語句等於:

1.o:1.c

2.o:2.c

#9-4  「變數和賦值」

有四種賦值方式:

1 - variable = value    # 在執行時擴充套件,允許遞迴擴充套件

2 - variable := value    # 在定義時擴充套件

3 - variable ?= value    # 只有在該變數為空時才設定值

4 - variable += value    # 將值追加到變數的尾端

#9-5  「內建變數」

提供了一些預設的環境變數,比如$(cc) 指向當前使用的編譯器,$(make) 指向當前使用的make工具。

更多見#9-6  「自動變數」

$@  -  當前commands對應的target

$<  -  第乙個prerequisites

$?  -  較當前target時間點而言,所有更新過的prerequisites(比較有用,可以用來取到所有近期變動過的prerequisites)

$^  -  指代所有的prerequisites

$*  -  所有%匹配的檔名,無字尾(比如前面的 %o:%.c,在這個依賴關係的commands中使用$*,就指代所有的檔名,比如上例中的1 2)

$(@d)和$(@f) - $(@d)指$@的路徑,$(@f)指$@的檔名

$(#10 ----------------------終-----------------------

工程Makefile例項

1級makefil phony clean for subdir in subdirs do cd subdir make clean done 級makefile target lib notdir curdir a objs wildcard o cc flags fpic md 靜態庫合成動態...

Makefile工程編譯

1.寫在前面 本篇文章講的是接前面makefile之編譯多個可執行程式中第二個需求,並延伸到對正規工程的編譯。2.工程 我接觸的工程有2種情況 所有原始檔都放乙個目錄 按模組分放不同的目錄 下面按照這兩種情況講解。3.所有原始檔都放乙個目錄 不建議所有原始檔都放乙個目錄,當工程大時,乙個目錄下會有很...

Makefile工程管理

1 makefile用途 make的工作主要依賴於乙個叫makefile的檔案。makefile檔案描述了整個程式的編譯,鏈結等規則。其中包括 工程中的哪些原始檔需要編譯以及如何編譯,如何最後產生我們想要的可執行檔案。2 makefile中最重要的組成部分是規則 規則 用於說明如何生成目標檔案,規則...