天天看點

GNU make函數

自動化編譯腳本工具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
           

繼續閱讀