linux之make

通過Makefile管理。

根據(jù)目標(biāo)和依賴的最后修改時間判斷是否需要更新。

三要素:目標(biāo)、依賴和規(guī)則。

目標(biāo)可以是文件或者偽目標(biāo)。

命令可以與目標(biāo)依賴同一行,中間用;隔開?;蛘擢毩⒁恍?,一條命令占一行,命令以tab開始。

可以使用反斜杠\續(xù)行,但是其后不能有空格。

make有默認規(guī)則,.c文件會默認生成同名的.o文件。所以單獨每個文件只需要將目標(biāo)和除文件本身外的其他依賴寫上即可。

單目標(biāo),多依賴。

命令前加-,表示忽略命令執(zhí)行錯誤。

可以通過-f或者--file=指定make讀取的文件。

使用include包含其他Makefile文件,多個文件使用空格分隔,可以使用通配符。

include前通常會有-,例如-include xxx xxx,這表示忽略包含文件不存在或者無法創(chuàng)建的錯誤提示。

不加-,編譯停止

加-,可以編譯。

$有特殊含義,表示變量或函數(shù)的引用。

order-only依賴使用|指示,|后邊的為此依賴,表示構(gòu)建目標(biāo)存在時,此依賴改變也不會重建目標(biāo)。

庫文件通過lNAME的方式作為依賴。只是指定了庫的名稱,最后對應(yīng)的庫應(yīng)該是libNAME.a或者libNAME.so的文件。

通配符

*、?、[]可以用在目標(biāo)、規(guī)則命令中,其他地方需要wildcard函數(shù)指定。注意在文件名中出現(xiàn)通配符的話需要\轉(zhuǎn)義。

變量中使用wildcard顯示指明通配符,他被展開為已經(jīng)存在的、使用空格分開的、匹配此模式的所有文件的列表。objs=$(wildcard *.o),這樣objs的值是具體的一個一個的xxx.o文件,也就是通配符展開。如果直接objs=*.o那么objs就是*.o這個字符串。

objs:=$(patsubst %.c,%.o,$(wildcard *.c)):獲取所有.c文件,并將后綴改為.o,構(gòu)成.o列表賦值給變量。

$^表示通過目錄搜索得到的依賴文件的完整路徑名列表,即所有的依賴文件。

$@表示規(guī)則的目標(biāo)。

$<第一個依賴文件

$?表示所有依賴文件

變量

多字符變量的引用必須加()。定義變量有兩種方式:直接展開(:=)和遞歸展開(=或define),推薦使用前者。

?=表示條件賦值,如果左值沒有賦值則將右值賦值。

VPATH:指定搜索路徑。路徑之間用冒號隔開。

????????????VPATH=src:../headers

GPATH:與VPATH類似,保證已存在的目標(biāo)在所在目錄重建。

CFLAGS:

.LIBPATTERNS:其值為lib%.so lib%.a,使用lNAME時會將%替換為NAME。

RM:定義為RM=rm -f,可以使用$(RM)來作為clean的命令

MAKELEVEL:make的調(diào)用深度。


關(guān)鍵字

vpath:指定文件的搜索路徑

? ? ? ? ? ? vpath PATTERN DIR? ? 指定

? ? ? ? ? ? vpath PATTERN? ? ? ? ? ? ?清除指定

? ? ? ? ? ? vpath? ? ? ? ? ? ? ? ? ? ? ? ? ? 清除所有

PATTERN需要使用%作為模式匹配,匹配一個或者多個字符。

偽目標(biāo)

.PHONY是一個特殊目標(biāo),其依賴就是偽目標(biāo),

可以使用all作為偽目標(biāo)來構(gòu)建多個程序,這些程序就是all的依賴。

強制目標(biāo),指沒有依賴也沒有命令,且目標(biāo)不存在,主要用在非GNU的make版本中。

特殊目標(biāo)

.PHONY .SUFFIXES .DEFAULT .PRECIOUS .INTERMEDIATE? .SECONDARY? .DELETE_ON_ERROR? .IGNORE? .LOW_RESOLUTION_TIME? .SILENT? .EXPORT_ALL_VARIABLES? .NOTPARALLEL

通過例子講解

#下面三行定義變量ROOT、SRC_DIR、BUILD_DIR并賦值,分別記錄了根目錄、源碼目錄和build中間目錄

ROOT=.

SRC_DIR=$(ROOT)/src

BUILD_DIR = build

#下面兩行CC表示編譯器,CFLAGS表示編譯的參數(shù)

CC = gcc

CFLAGS=-ansi -I$(ROOT)/include -Wall -DLINUX -D_GNU_SOURCE

#下面兩行LIBAPUE表示庫的路徑,LDLIBS表示鏈接的參數(shù)-L表示庫路徑-l表示庫名稱

LIBAPUE=$(ROOT)/lib/libapue.a

LDLIBS=-L$(ROOT)/lib -lapue

#下面兩行C_FILES表示c源文件,wildcard指明后邊的*表示通配符,否則*不起作用。

#OBJ_FILES是c文件對應(yīng)的_c.o文件,冒號前邊表示文件列表,后邊表示匹配規(guī)則。%與*作用類似。

C_FILES = $(wildcard $(SRC_DIR)/*.c)

OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o)

#all后邊表示我們最終想要得到的文件,all是一個偽目標(biāo)。

all: linux-api-demo

#表示目標(biāo)linux-api-demo的依賴和目標(biāo)已經(jīng)產(chǎn)生的方法

linux-api-demo:$(OBJ_FILES) $(LIBAPUE)

gcc -o linux-api-demo $(OBJ_FILES) $(LDLIBS)

表示.c生成.o目標(biāo)的規(guī)則,$<表示依賴,$@表示目標(biāo),$(@D)表示目標(biāo)的路徑,不包括/

$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c

mkdir -p $(@D)

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

#清除規(guī)則,clean偽目標(biāo)

clean:

rm -rf $(BUILD_DIR) linux-api-demo

#make執(zhí)行的時候先通過 all查看其依賴,all的依賴就是我們要得目標(biāo),此處是linux-api-demo,

#要得到linux-api-demo,就要找其生成規(guī)則,找到后發(fā)現(xiàn)他的依賴是.o和.a文件,

#繼續(xù)找.o文件的生成規(guī)則,找到后根據(jù)規(guī)則命令生成對應(yīng)的文件,此處文件的生成是一個一個的,不是批量

#的,可以通過make的輸出看出這一點。

#.o和.a生成后滿足了生成linux-api-demo的條件,編譯產(chǎn)生linux-api-demo后all的依賴也滿足了,

#此時make完成。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容