學習makefile筆記
一個我個人覺得非常實用的例子:
eg:在當前目錄下有a.cpp and b.cpp 現在寫一個makefile,將這些文件編譯出對應的.o文件。
begin:
1
2 src=$(wildcard *.c)
3 dir=$(notdir $(src))
4 obj=$(patsubst %.c,%.o,$(dir) )
5
6 all: $(obj)
7 @echo src:$(src)
8 @echo dir:$(dir)
9 @echo obj:$(obj)
10 @echo "end"
11 $(obj): %.o: %.c
12 gcc -c $(CFLAGS) $< -o $@
13 clean:
14 -@rm -rf *.o
輸出結果爲:
gcc -c char.c -o char.o
gcc -c test_sizeof.c -o test_sizeof.o
gcc -c transfer.c -o transfer.o
src:char.c test_sizeof.c transfer.c
dir:char.c test_sizeof.c transfer.c
obj: char.o test_sizeof.o transfer.o
end
#wildcard把 指定目錄下的所有後綴是c的文件全部展開
a.cpp b.cpp
#notdir把展開的文件去除掉路徑信息
a.cpp b.cpp
#patsubst把$(dir)中的變量符合後綴是.c的全部替換成.o
#CFLAGS: 指定頭文件(.h文件)的路徑,如:CFLAGS=-I/usr/include -I/path/include。同樣地,安裝一個包時會在安裝路徑下建立一個include目錄,當安裝過程中出現問題時,試着把以前安裝的包的include目錄加入到該變量中來。
a.cpp b.cpp
#notdir把展開的文件去除掉路徑信息
a.cpp b.cpp
#patsubst把$(dir)中的變量符合後綴是.c的全部替換成.o
#CFLAGS: 指定頭文件(.h文件)的路徑,如:CFLAGS=-I/usr/include -I/path/include。同樣地,安裝一個包時會在安裝路徑下建立一個include目錄,當安裝過程中出現問題時,試着把以前安裝的包的include目錄加入到該變量中來。
#在每條命令前加上@符號,可以隱藏makefile打印出當前命令本身
#在命令前加上一個“-”號的意思是,忽略該條命令的錯誤,繼續執行。等同於-i i是--ignore-errors的縮寫。
今天學習了makefile中的“命令包”好“目標變量”
命令包:
eg:
1 src=$(wildcard *.c)
2 dir=$(notdir $(src))
3 obj=$(patsubst %.c,%.o,$(dir) )
4
5 define two_line
6 echo "this is two_line:one"
7 echo "this is two_line:two"
8 endef
9
10 all: $(obj)
11 @echo $(src)
12 @echo $(dir)
13 @echo $(obj)
14 @echo "end"
15 @$(two_line)
16
17 $(obj): %.o: %.c
18 gcc -c $(CFLAGS) $< -o $@
19 clean:
20 rm -rf *.o
其中5~8行定義了這個命令包,two_line是這個命令包的名字,在define和endef之間的命令就是這個命令包的內容,在第15行調用了這個命令包。結果和想象的一樣,不用過多解釋。
目標變量:
這個特性很有用,我們設置了一個變量,這個變量只在特定的目標中起作用。
eg:
1 src=$(wildcard *.c)
2 dir=$(notdir $(src))
3 obj=$(patsubst %.c,%.o,$(dir) )
4
5 define two_line
6 echo "this is two_line:one"
7 echo "this is two_line:two"
8 endef
9
10 all: cc = gcc
11
12 all: $(obj)
13 @echo $(src)
14 @echo $(dir)
15 @echo $(obj)
16 @echo "end"
17 @$(two_line)
18
19 $(obj): %.o: %.c
20 $(cc) -c $(CFLAGS) $< -o $@
21 clean:
22 rm -rf *.o
23
24
第十行中,我們在all這個目標中定義 cc=gcc,只在這個目標規則下,$(cc) = gcc