2010年12月29日 星期三

Makefile


Secondary Expansion

  • 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))
  • 說明:
    1. initial expansion: the prerequisites of both the ‘main’ and ‘lib’ targets will be $(patsubst %.c,%.o,$($@_SRCS))
    2. 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.

Functions

Syntax
$(function_name arguments)
or
${function_name arguments}
function_name跟arguments之間是空格, 多個arguments以逗號隔開

text manipulation

  • $(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...)

manipulating file names

  • $(dir names...) – 目錄的部分或 ./
  • $(notdir names...)
  • $(suffix names...)
  • $(basename names...)
  • $(addsuffix suffix,names...)
  • $(addprefix prefix,names...)
  • $(join list1,list2)
  • $(wildcard pattern)
  • $(realpath names...)
  • $(abspath names...)

Conditionals

  • $(if condition,then-part[,else-part])
  • $(or condition1[,condition2[,condition3...]])
  • $(and condition1[,condition2[,condition3...]])

others

  • $(foreach var,list,text)
  • $(call variable,param,param,...)
  • $(value variable)
  • eval
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)
  • $(origin variable)
告訴你variable的來源
  • $(flavor variable)
告訴你variable的特色
  • $(shell command)
  • $(error text...)
  • $(warning text...)
  • $(info text...)

規則 Rules

變數 Variables

在 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
  • – 或
    • = – recursively expanded 的變數 (one of the two flavors)
    • := – simply expanded 的變數 (another one of the two flavors)
    • ?= – 變數未定義才定義
    • += – 添加
  • 規則中的自動變數
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 中 `%' 所匹配的文字。
  • 變數處理 – 較複雜的處理可以 shell 的 awk 程式

隱含規則 Implicit Rules

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

Conditionals

依據變數內容決定要不要做
  • ifeq
  • ifneq
ifneq (,$(findstring t,$(MAKEFLAGS))) # 比用 ifeq 適當
  ...
else
  ...
endif
  • ifdef
  • ifndef

How to use simple speedtest in RaspberryPi CLI

  pi@ChunchaiRPI2:/tmp $  wget -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py --2023-06-26 10:4...