自動化編譯腳本工具make,它通過各種規則來控制你的源代碼如何生成目标程式。要使用make編譯一個程式,需要提供一個makefile檔案讓make知道如果構造你的程式,makefile的内容就是一系列的規則,這些規則其實就像一種腳本,它有變量、函數、宏、表達式,分支結構等,而make主要靠檔案依賴性這種方式對源檔案編譯。
比如,首先告訴make我需要目标A,然後make去找對應A的規則,如果A存在(一般是檔案)就傳回,如果不存在就根據A中定義的規則來産生A,A中的規則也可能需要目标B(A依賴B)或多個其它目标,而B也可能也需要目标C等等,這樣就會有一個遞歸調用,make會一直找下去,當然規則也可以是調用一個cl來産生obj或link生成exe。直到所有檔案全部生成最終産生目标A整個過程才完成。
Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files
Make gets its knowledge of how to build your program from a file called the makefile, which lists each of the non-source files and how to compute it from other files. When you write a program, you should write a makefile for it, so that it is possible to use Make to build and install the program.
微軟VC中使用的是nmake,turbo C中也有個make,free pascal也有。很多編譯器都自帶make工具。不同家的make文法也不一樣。
用得最多的估計就是GNU make。它是免費開源産品,我現在用的版本是3.75.
下載下傳位址
以下是GNU make中的一些常用函數。
.SUFFIXES:
.SUFFIXES: .c .o
.PHONY: all
# 先編譯後清除不需要的檔案。
all: ${OUT} clean_temp
# 擷取目前目錄下所有.c檔案。
src := $(wildcard ${CURDIR}*.c)
# 擷取.c檔案對應一個.o檔案名。
obj := $(addsuffix .o, $(basename ${src}))
${OUT}: ${obj}
gecho $<>[email protected]
# 設定指定檔案的編譯規則。
%.o: %.c
$(CC) $< [email protected]
.PHONY: clean_all
# 清除所有生成的檔案。
clean_all: clean_temp clean_out
.PHONY: clean_temp
# 清除除目标檔案之外的生成檔案。
clean_temp:
if exist *.o del *.o
.PHONY: clean_out
# 清除目标檔案。
clean_out:
if exist ${OUT} del ${OUT}
test:
# make 函數測試。
gecho $(wildcard ${CURDIR}*) # 使用通配符列出指定目錄下的檔案或目錄。
gecho $(dir $(wildcard ${CURDIR}*)) # 列出每個檔案路徑的目錄路徑名。
gecho $(notdir $(wildcard ${CURDIR}*)) # 列出每個檔案路徑的全檔案名。
gecho $(realpath $(wildcard ${CURDIR}*)) # 列出每個檔案的真實路徑名。
gecho $(abspath $(wildcard ${CURDIR}*)) # 列出每個檔案的絕對路徑名。
gecho $(suffix $(wildcard ${CURDIR}*)) # 列出每個檔案路徑的檔案擴充名。
gecho $(basename $(wildcard ${CURDIR}*)) # 列出每個檔案路徑的檔案名。
gecho $(addsuffix X2, $(wildcard ${CURDIR}*)) # 給每個檔案路徑追加字尾。
gecho $(addprefix PFX, $(wildcard ${CURDIR}*))# 給每個檔案路徑插入字首。
gecho $(join 1 2 3 4 5, .c .c .c .c .h) # 将兩個清單合并,變成1.c 2.c 3.c 4.c 5.h
gecho $(shell echc) # 執行一個Shell指令并将輸出傳回。
gecho $(foreach d, 1 2 3 4 5 6 7 8 9 10, ${d})# 枚舉一個清單并傳回處理的結果。foreach var,set,expression
gecho $(subst 1, 2, 1 2 3 4 5 6 7 8 9 10) # 傳回文本替換後的結果。subst old, new, string
gecho $(patsubst %x, y, flex xor sex fixed) # 傳回文本替換後的結果。subst pattern,replacement, string
gecho $(src:%.c = %.o) # 傳回文本替換後的結果。var:suffix = replacement
gecho $(strip . start ... c = end of . ) # 移除文本前後的空白字元。
gecho $(findstring end, .end of . ) # 傳回文本中是否包含指定的字元串。沒找到傳回空。
gecho $(filter %d, .end of . ) # 從清單中移除未比對的字元串。
gecho $(filter-out %d, .end of . ) # 從清單中移除比對的字元串。
gecho $(sort 8 2 1 4 3 0 7 14 6 10 32 5) # 按字母排序清單。
gecho $(word 5, 8 2 1 4 3 0 7 14 6 10 32 5) # 傳回清單中指定序号的元素。
gecho $(wordlist 2, 3, X8 X2 X1 X4 X3 X0 X7) # 傳回清單部分的元素。
gecho $(words X8 X2 X1 X4 X3 X0 X7) # 傳回清單的元素數量。
gecho $(firstword X8 X2 X1 X4 X3 X0 X7) # 傳回清單的第一個元素。
gecho $(lastword X8 X2 X1 X4 X3 X0 X7) # 傳回清單的最後一個元素。
# call a complex expression.
# 調用一個表達式
override A = $(info $(origin foo))
override A = $(info $(flavor bar))
# condition directives. 條件指令。
# style 1 for the ifeq statement.
ifndef A
override A = B
gecho ${A}
endif
ifeq (${A}, B)
gecho ifeq (${A}, B) == YES
endif
ifneq (${A}, C)
gecho ifneq (${A}, C) == YES
endif
# style 2 for the ifeq statement.
ifeq '${A}' 'B'
gecho ifeq '${A}' 'B' == YES
endif
ifneq '${A}' 'C'
gecho ifneq '${A}' 'C' == YES
endif
# style 3 for the ifeq statement.
ifeq "${A}" 'B'
gecho ifeq "${A}" 'B' == YES
endif
ifneq "${A}" 'C'
gecho ifneq "${A}" 'C' == YES
endif
# style 4 for the ifeq statement.
ifeq "${A}" "B"
gecho ifeq "${A}" "B" == YES
endif
ifneq "${A}" "C"
gecho ifneq "${A}" "C" == YES
endif