在前面的三篇文章徹底掌握Makefile(一)、徹底掌握Makefile(二)和徹底掌握Makeifle(三)當中我們仔細介紹了Makefile各種使用方法,在本篇文章當中主要是對前面三篇關於makefile的文章做一個總結,方便大家快速查閱和檢查。
當我們在命令列當中輸入make
的時候他的執行流程如下:
demo
這個編譯目標,而不是clean
這個目標,因為clean
是第二個編譯目標。編譯目標:依賴檔案
編譯命令
main: demo.o myprint.o
gcc demo.o myprint.o -o out
echo make 解析編譯完成
demo.o: demo.c
gcc -c demo.c -o demo.o
myprint.o: myprint.c
gcc -c myprint.c -o myprint.o
clean:
rm myprint.o demo.o out
cflags=-c
main: demo.o myprint.o
gcc demo.o myprint.o -o out
demo.o: demo.c
gcc $(cflags) demo.c -o demo.o
myprint.o: myprint.c
gcc $(cflags) myprint.c -o myprint.o
clean:
rm myprint.o demo.o out
include submakefile
demo.o: demo.c
gcc $(cflags) demo.c -o demo.o
myprint.o: myprint.c
gcc $(cflags) myprint.c -o myprint.o
clean:
rm myprint.o demo.o out
cflags=-c
main: demo.o myprint.o
gcc demo.o myprint.o -o main
demo.o: demo.c
gcc $(cflags) demo.c -o demo.o
myprint.o: myprint.c
gcc $(cflags) myprint.c -o myprint.o
clean:
rm myprint.o demo.o main
.PHONY: clean # 增加這一行
cflags=-c
main: demo.o myprint.o
gcc demo.o myprint.o -o main
%.o: %.c
gcc $(cflags) $<
clean:
rm myprint.o demo.o main
.PHONY: clean
cflags=-c
VPATH=./files
main: demo.o myprint.o a.o b.o
gcc demo.o myprint.o a.o b.o -o main
demo.o:demo.c
gcc $(cflags) demo.c
myprint.o:myprint.c
gcc $(cflags) myprint.c
a.o: a.c
gcc $(cflags) $<
b.o: b.c
gcc $(cflags) $<
clean:
rm myprint.o demo.o main
.PHONY: clean
有時候在makefile當中我們不想輸出某些命令(如果不進行設定makefile會輸出每一條我們執行過的命令),我們就可以使用@符號進行修飾。
main: demo.c
@echo hello world
主要是用於判斷字元是否相等。
cc=g++
main: demo.c
echo $(cc)
ifeq ($(cc), gcc)
echo $(cc) = 相等的語句執行了
else
echo $(cc) != 不相等的語句執行了
endif
cc=g++
main: demo.c
echo $(cc)
ifneq ($(cc), gcc)
echo $(cc) != gcc
else
echo $(cc) = gcc
endif
判斷變數是否被定義或者為空
foo = 1
main: demo.c
echo demo
ifdef foo
echo define foo
else
echo not define foo
endif
main: demo.c
echo demo
ifdef foo
echo define foo
else
echo not define foo
endif
在makefile當中除了能夠使用條件表示式之外我們還可以使用函數,在makefile當中函數的使用規則如下:
$(<函數名> <函數引數>)
或者
將()替換為{}
函數的呼叫規則如上圖所示,函數引數用.隔開。
$(subst <from>,<to>,<text>)
s = ii am learning makefile
ss = $(subst ii, you, $(s))
main: demo.c
echo demo
echo $(s)
echo $(ss)
$(patsubst <pattern>,<replacement>,<text>)
s = a.c b.c d.c abc.c abo.c
ss = $(patsubst %.c, %.o, $(s))
main: demo.c
echo demo
echo $(s)
echo $(ss)
$(strip <string>)
主要功能去掉字串 string 首尾的空格。
$(findstring <find>,<text>)
這個函數的作用是從字串
$(filter <pattern...>,<text>)
這是一個過濾函數,這個函數執行時,首先會根據空格或者tab鍵或者回車換行符進行分割,然後一一的進行filter函數的操作。然後遍歷每一個被分割出來的字元,如果不滿足pattern的規則的話對應的字元就會被過濾掉。
s = a.c abo.c s.o s.y x.o x.y
ss = $(filter %.c %.o, $(s))
main: demo.c
echo $(ss)
這個函數和filter的用法是一樣的只不過,作用剛好相反,filter是儲存符合條件的字串,filter-out是儲存不符合條件的字串。
s = a.c abo.c s.o s.y x.o x.y
ss = $(filter-out %.c %.o, $(s))
main: demo.c
echo $(ss)
這個函數主要是用於幫助字串排序的,同時還會取出分割之後相同的字串。
s = g a b c d e f a a a a
ss = $(sort $(s))
main: demo.c
echo $(ss)
$(word <n>,<text>)
這個功能很簡單,返回
s = g a b c d e f a a a a
ss = $(word 1, $(s)) # 取出第一個字元
main: demo.c
echo $(ss)
$(wordlist <start>,<end>,<text>)
這個也是從字串當中取出字元,是取出第
s = g a b c d e f a a a a
ss = $(wordlist 1, 5, $(s))
main: demo.c
echo $(ss)
統計單詞的個數。
s = 1 2 3 4 5
ss = $(words $(s))
main: demo.c
echo $(ss)
這個函數主要是用於返回第一個字串的。
s = 1 2 3 4 5
ss = $(firstword $(s))
main: demo.c
echo $(ss)
dir函數主要書獲取檔案路徑當中的目錄部分,而notdir函數主要是獲取檔案路徑當中檔名的部分
file = ./files/a.c
fdir = $(dir $(file))
nfdir = $(notdir $(file))
main: demo.c
echo $(fdir)
echo $(nfdir)
這個函數主要是用於獲取檔案的字尾名。
file = ./files/a.c
fdir = $(dir $(file))
nfdir = $(notdir $(file))
name = $(suffix $(file))
main: demo.c
echo $(fdir)
echo $(nfdir)
echo $(name)
這個函數用於獲取檔案路徑當中除去字尾名的部分。
file = ./files/a.c
base = $(basename $(file))
main: demo.c
echo $(base)
這個函數主要是給檔案加上字尾的。
file = ./files/a.c
base = $(addsuffix .c, $(file))
main: demo.c
echo $(base)
這個函數的主要作用就是在字串的前面加上一串字元。
file = files/a.c
base = $(addprefix ./src/main/, $(file))
main: demo.c
echo $(base)
foreach
函數的主要使用規則為:
$(foreach <var>,<list>,<text>)
我們直接使用一個例子來說明這個情況:
files = a.c b.c c.c d.c
new_files = $(foreach n, $(files), $(n)pp)
main: demo.c
echo $(new_files)
call函數在makefile當中可以用於呼叫我們自定義的一個表示式,他的語法個數如下面所示:
$(call <expression>,<parm1>,<parm2>,...,<parmn>)
$(n)
進行參照。a=a.c
b=b.c
c=$(a)-------$(b)
main: demo.c
echo $(c)
我們在makefile的表示式當中可以使用shell的函數。
比如現在我們有一個檔案叫做test.txt
,檔案的內容如下所示:
a.c b.c c.c d.c
content=$(shell cat test.txt) # 將shell命令的輸出內容賦給content
main: demo.c
echo $(content) # 輸出content
origin這個函數主要是返回變數的定義方式,使用格式如下:
$(origin <variable>) # 其中 variable 是變數名字 這裡不需要使用 $ 符號去參照
在makefile當中我們可以使用error函數讓makefie停止執行。當我們有需求:讓在某種條件下讓makefile停止編譯
data=data
ifeq ($(data), data)
$(error "data == data")
endif
main: main.c
gcc main.c
除此之外還有個warning函數使用方法和error一樣!
在本篇文章當中主要給大家總結了一些常見的makefile的使用方法,方便大家查閱複習!
以上就是本篇文章的所有內容了,我是LeHung,我們下期再見!!!更多精彩內容合集可存取專案:https://github.com/Chang-LeHung/CSCore
關注公眾號:一無是處的研究僧,瞭解更多計算機(Java、Python、計算機系統基礎、演演算法與資料結構)知識。