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