second expansion of the prerequisites (only) for some or all targets. (第一次是在read-in phase時)
格式: .SECONDEXPANSION is defined before the first prerequisite list and escape the variable or function reference for the secondary expansion phase.
例子: automatic variables
main_SRCS := main.c try.c test.c
lib_SRCS := lib.c api.c
.SECONDEXPANSION:
main lib: $$(patsubst %.c,%.o,$$($$@_SRCS))
說明:
initial expansion: the prerequisites of both the ‘main’ and ‘lib’ targets will be $(patsubst %.c,%.o,$($@_SRCS))
secondary expansion: the $@ variable is set to the name of the target and so the expansion for the ‘main’ target will yield $(patsubst %.c,%.o,$(main_SRCS)), or main.o try.o test.o, while the secondary expansion for the ‘lib’ target will yield $(patsubst %.c,%.o,$(lib_SRCS)), or lib.o api.o.
Syntax
$(function_name arguments)
or
${function_name arguments}
function_name跟arguments之間是空格, 多個arguments以逗號隔開
$(subst from,to,text)
$(patsubst pattern,replacement,text)
$(patsubst pattern,replacement,$(var))相當於$(var:pattern=replacement)
$(patsubst %suffix,%replacement,$(var))相當於$(var:suffix=replacement)
$(strip string)
$(findstring find,in)
$(filter pattern...,text)
$(filter-out pattern...,text)
$(sort list)
$(word n,text)
$(wordlist s,e,text)
$(words text)
$(firstword names...)
$(lastword names...)
$(dir names...) – 目錄的部分或 ./
$(notdir names...)
$(suffix names...)
$(basename names...)
$(addsuffix suffix,names...)
$(addprefix prefix,names...)
$(join list1,list2)
$(wildcard pattern)
$(realpath names...)
$(abspath names...)
$(if condition,then-part[,else-part])
$(or condition1[,condition2[,condition3...]])
$(and condition1[,condition2[,condition3...]])
PROGRAMS = server client
server_OBJS = server.o server_priv.o server_access.o
server_LIBS = priv protocol
client_OBJS = client.o client_api.o client_mem.o
client_LIBS = protocol
# Everything after this is generic
.PHONY: all
all: $(PROGRAMS)
define PROGRAM_template
$(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
ALL_OBJS += $$($(1)_OBJS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
$(PROGRAMS):
$(LINK.o) $^ $(LDLIBS) -o $@
clean:
rm -f $(ALL_OBJS) $(PROGRAMS)
告訴你
variable的來源
告訴你
variable的特色
$(shell command)
$(error text...)
$(warning text...)
$(info text...)
在 makefile,變數是用一個名稱代表一個字串。
變數名稱不能包含 ‘:’, ‘#’, ‘=’,最好只使用 letters, numbers, and underscores
case-sensitive, 建議使用 lower case letters for variable names that serve internal purposes in the makefile, and reserving upper case for parameters that control implicit rules or for parameters that the user should override with command options (see Overriding Variables).
Communicating Variables to a Sub-make
– 或
規則中的自動變數
foo.o: new1.c new2.c old1.c new3.c
$@ == foo.o (目標)
$< == new1.c (第一個)
$? == new1.c new2.c new3.c (有更新的)
$^ == new1.c new2.c old1.c new3.c (所有的)
$* == 在 target 中 `%' 所匹配的文字。
remaking特定的target經常有特定的標準方法, 而implicit rules便是那些標準方法. make可以直接用檔名來決定使用哪個implicit rules, 不需要再額外指定. 而且implicit rules可以串連使用. implicit rules有用到一些變數, 改變那些變數就可以改變implicit rules的行為.
例如: 從*.c產生*.o, 就會使用cc $(CFLAGS)
你可以使用pattern rules來定義你自己的implicit rules, 而suffix rules則是另一種方式, 但限制較多.
In general, make searches for an implicit rule for each target, and for each double-colon rule, that has no commands. A file that is mentioned only as a prerequisite is considered a target whose rule specifies nothing, so implicit rule search happens for it.
Built-in (Predefined) Implicit Rules
在沒有Makefile目錄的下`make -p`, 可以看到一段是列出default的implicit rules. 不同的作業系統, 其default implicit rules會有所不同. 另外, 列出的default implicit rules多寡, 跟定義的suffix list有關, 因為大部分predefined implicit rules是用suffix rules定義的
override
取消所有的predefined rules: 使用’-r’或’–no-builtin-rules’ option
pattern rules
suffix rules 依據變數內容決定要不要做
ifneq (,$(findstring t,$(MAKEFLAGS))) # 比用 ifeq 適當
...
else
...
endif