从头開始写项目Makefile(三):变量的使用
【版權(quán)聲明:轉(zhuǎn)載請(qǐng)保留出處:blog.csdn.net/gentleliu。
Mail:shallnew?at?163?dot?com】
細(xì)致研究我們的之前Makefile發(fā)現(xiàn)。我們還有改進(jìn)的地方。就是此處:
target_bin : main.o debug.o ipc.o timer.o tools.o >---gcc -o target_bin main.o debug.o ipc.o timer.o tools.o假設(shè)添加一個(gè)源文件xx.c的話。須要在兩處或多處添加xx.o文件。
我們能夠使用變量來解決問題。之前說過。Makefile的變量就像C語(yǔ)言的宏一樣。使用時(shí)在其位置上直接展開。變量在聲明時(shí)賦予初值。在引用變量時(shí)須要給在變量名前加上“$”符號(hào),但最好用小括號(hào)“()”或是大括號(hào)“{}”把變量給包含起來。
默認(rèn)目標(biāo)target_bin也在多處出現(xiàn)了,該文件也能夠使用變量取代。
改動(dòng)我們的Makefile例如以下:
SRC_OBJ = main.o debug.o ipc.o timer.o tools.o SRC_BIN = target_bin $(SRC_BIN) : $(SRC_OBJ) >---gcc -o $(SRC_BIN) $(SRC_OBJ)clean: >---rm $(SRC_OBJ) $(SRC_BIN)這樣每次有新增的文件是僅僅須要在SRC_OBJ變量里面添加一個(gè)文件就可以。
要改動(dòng)終于目標(biāo)的名字是能夠僅僅改動(dòng)變量SRC_BIN。
事實(shí)上在之前還說過特殊變量:
$@。表示規(guī)則中的目標(biāo)。
$<,表示規(guī)則中的第一個(gè)依賴文件。
$?,表示規(guī)則中全部比目標(biāo)新的條件,組成一個(gè)列表,以空格分隔。
$^,表示規(guī)則中的全部條件。組成一個(gè)列表,以空格分隔。
上一節(jié)我們看到make -p有非常多自己定義的變量。比方CC。
當(dāng)中非常多變量我們能夠直接使用或改動(dòng)其變量值或添加值。
我們的Makefile中能夠使用CC(默認(rèn)值為cc)、RM(默認(rèn)值為rm -f)。
?
由此可見我們的Makefile還能夠進(jìn)一步改動(dòng):
?
SRC_OBJ = main.o debug.o ipc.o timer.o tools.o SRC_BIN = target_bin $(SRC_BIN) : $(SRC_OBJ) >---$(CC) -o $@ $^ clean: >---$(RM) $(SRC_OBJ) $(SRC_BIN) 這種Makefile編譯也是可用的。可是這種Makefile還是須要我們手動(dòng)加入文件。還是不夠自己主動(dòng)化,最好增刪文件都要改動(dòng)Makefile。
偉大的人類真是太懶了!。于是乎。他們發(fā)明了一個(gè)函數(shù)wilcard(函數(shù)后面會(huì)講到),它能夠用來獲取指定文件夾下的全部的.c文件列表。這種話我們能夠自己主動(dòng)獲取當(dāng)前文件夾下全部.c源文件。然后通過其它方法再得到.o文件列表,這種話就不須要在每次增刪文件時(shí)去改動(dòng)Makefile了。所謂其它方法這里給出兩種:
1.?????使用patsubst函數(shù)。在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的變量符合后綴是.c的所有替換成.o。
2.?????變量值的替換。
我們能夠替換變量中的共同擁有的部分。其格式是“$(var:a=b)”或“${var:a=b}”,其意思是,把變量“var”中全部以“a”字串“結(jié)尾”的“a”替換成“b”字串。
?
改動(dòng)后的Makefile例如以下:
# SRC_OBJ = $(patsubst %.c, %.o, $(wildcard *.c)) SRC = $(wildcard *.c) SRC_OBJ = $(SRC:.c=.o) SRC_BIN = target_bin$(SRC_BIN) : $(SRC_OBJ) >---$(CC) -o $@ $^clean: >---$(RM) $(SRC_OBJ) $(SRC_BIN) 當(dāng)中# 后面的內(nèi)容為凝視。這樣最終滿足了那些懶人的想法了。
可見在使用變量時(shí),的確能夠是編譯變得更自己主動(dòng)化。
?
事實(shí)上變量的定義有三種運(yùn)算符=、:=、?=、+=。
1.?????=運(yùn)算符能夠讀取到后面定義的變量。比方:
VAR = $(VAR2) VAR2 = hello_makeall: >---@echo =====$(VAR)=====執(zhí)行結(jié)果為:
# =====hello_make===== #可是這樣的定義可能會(huì)導(dǎo)致并非我們意愿的事發(fā)生,并非非常符合C語(yǔ)言的編程習(xí)慣。
2.?????:=運(yùn)算符在遇到變量定義時(shí)馬上展開。
VAR := $(VAR2) VAR2 = hello_makeall: >---@echo =====$(VAR)===== 執(zhí)行結(jié)果為:# ========== #3.??????=運(yùn)算符在復(fù)制之前先做推斷變量是否已經(jīng)存在。比如var1 ?= $(var2)的意思是:假設(shè)var1未定義過。那么?=相當(dāng)于=,假設(shè)var1先前已經(jīng)定義了,則什么也不做。不會(huì)給var又一次賦值。
4.?????+=運(yùn)算符是給變了追加值。假設(shè)變量還未定義過就直接用+=賦值。那么+=相當(dāng)于=
?
怎樣使用這幾個(gè)運(yùn)算符要看實(shí)際情況,有時(shí)一個(gè)大的project可能有很多Makefile組成。變量可能在多個(gè)Makefile中都在使用,這時(shí)可能使用+=比較好。使用:=有時(shí)可能比要好。
有時(shí)在編譯程序時(shí),我們須要編譯器給出警告,或增加調(diào)試信息。或告知編譯器優(yōu)化可運(yùn)行文件。編譯時(shí)C編譯器的選項(xiàng)CFLAGS使用的較多,默認(rèn)沒有提供值。我們能夠給該變量賦值。
有時(shí)我們還須要使用鏈接器選項(xiàng)LFLAGS告訴鏈接器鏈接時(shí)須要的庫(kù)文件。
可能我們還須要給出包括頭文件的路徑,由于頭文件非常可能和源文件不再同一文件夾。
所以,我們今天的Makefile加上部分凝視又更新了:
# A commonMakefile for c programs, version 1.0 # Copyright (C)2014 shallnew \at 163 \dot comCFLAGS += -g -Wall-Werror -O2 CPPFLAGS += -I.-I./inc LDFLAGS +=-lpthread# SRC_OBJ =$(patsubst %.c, %.o, $(wildcard *.c)) SRC_FILES =$(wildcard *.c) SRC_OBJ =$(SRC_FILES:.c=.o) SRC_BIN =target_bin$(SRC_BIN) :$(SRC_OBJ) >---$(CC) -o $@$^ $(LDFLAGS)clean: >---$(RM)$(SRC_OBJ) $(SRC_BIN)編譯:# make cc -g -Wall-Werror -O2 -I. -I./inc -c -o debug.odebug.c cc -g -Wall-Werror -O2 -I. -I./inc -c -o ipc.oipc.c cc -g -Wall-Werror -O2 -I. -I./inc -c -o main.omain.c cc -g -Wall-Werror -O2 -I. -I./inc -c -o timer.otimer.c cc -g -Wall-Werror -O2 -I. -I./inc -c -o tools.otools.c cc -o target_bindebug.o ipc.o main.o timer.o tools.o -lpthread #
可見我們的預(yù)編譯選項(xiàng)。編譯選項(xiàng)都用到了。之前我們說過make的使用隱含規(guī)則自己主動(dòng)推導(dǎo):
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) –c當(dāng)中變量CFLAGS 和 CPPFLAGS均是我們給出的。變量$(TARGET_ARCH)未給,所以在編譯輸出能夠看到-c前面有2個(gè)空,最早未給變量是有四個(gè)空。
眼下給出的Makefile基本上能夠適用于那些源碼所有在同一文件夾下的簡(jiǎn)單項(xiàng)目,而且基本上在增刪文件時(shí)不須要再去手動(dòng)改動(dòng)Makefile代碼。在新的一個(gè)項(xiàng)目?jī)H僅須要把該Makefile復(fù)制到源碼文件夾下。再改動(dòng)一下你須要編譯的可運(yùn)行文件名以及你須要的編譯連接選項(xiàng)就可以。
后面章節(jié)將會(huì)講到怎樣寫多文件夾源碼project下的Makefile。
最后,今天的終于Makefile是這種:
# A commonMakefile for c programs, version 1.0 # Copyright (C)2014 shallnew \at 163 \dot comCFLAGS += -g -Wall-Werror -O2 CPPFLAGS += -I.-I./inc LDFLAGS +=-lpthread# SRC_OBJ =$(patsubst %.c, %.o, $(wildcard *.c)) SRC_FILES =$(wildcard *.c) SRC_OBJ =$(SRC_FILES:.c=.o) SRC_BIN =target_bin$(SRC_BIN) :$(SRC_OBJ) >---$(CC) -o $@$^ $(LDFLAGS)clean: >---$(RM)$(SRC_OBJ) $(SRC_BIN)轉(zhuǎn)載于:https://www.cnblogs.com/jzdwajue/p/6745178.html
總結(jié)
以上是生活随笔為你收集整理的从头開始写项目Makefile(三):变量的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6升小米6——算法解题
- 下一篇: 洛谷——P1002 过河卒||codev