Make

状态:参考

最后更新:

Make command usually write in Makefile.

下文代码块里的配方(recipe)行都必须以 TAB 开头,用空格缩进会报 missing separator

Makefile syntax

Makefile construct by rules.

# rule
<target> : [prerequisites]
	<commands>

target

One or more file name, and the operator(phony target) is okay.

clean: 
	rm *.o

This is a phony target, but when the file clean exist, make clean will not effect.

To avoid this phenomenon, we can declare clean as the phony.

.PHONY: clean
clean: 
	rm *.o temp

targets

[prerequisites]

example:

result: source
	cp source result

command

shell command.

Every line of command execute in different terminal.

But you can solve in three ways.

  1. Use ; as end of a command and write other command in the same line.

  2. Use ; and add \ at the end of the line to continue on the next line.

  3. Add the target .ONESHELL:

other syntax

echoing

Make will print each command, and add @ at the beginning of a recipe line can close the echoing.

@ only works as the first character of the recipe line; in the middle of a line it is passed to the shell.

wildcard *

*: all words ?: one character [...]: any one character in the set

match *

% can match some part of file name

%.o: %.c

variable *

vars = loomt dakta
show-vars:
	@echo $(vars) # makefile变量
	@echo $$HOME # Shell变量
VARIABLE = value # 在执行时扩展,允许递归扩展。
VARIABLE := value # 在定义时扩展。 
VARIABLE ?= value # 只有在该变量为空时才设置值。
VARIABLE += value # 将值追加到变量的尾端。
implicit variables *

implicit variables

$(CC) -o a a.c
automatic variables *

$@: self target $<: first prerequisite $^: all prerequisites

for *
LIST = one two three
for-test:
	for i in $(LIST);\
	  do echo $$i;\
	done
	for i in $$(seq 1 10) ; do \
		echo "iterator $$i"; \
	done
if *

ifeq/else/endif 本身不能用 tab 缩进,但其中的 echo 仍是配方行,要用 tab

if-test:
ifeq (g++,$(CXX))
	echo "cxx eq g++"
else
	echo "cxx neq g++"
endif
function *

Shell

goenv := $(shell  go env)

shell-test:
	echo $(goenv)

Wildcard

path-files := $(wildcard ./*)
wildcard-test:
	echo $(path-files)

Subst

comma:= ,
empty:=
# space变量用两个空变量作为标识符,当中是一个空格
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# bar is now `a,b,c'.
subst-test:
	echo $(bar)

Patsubst

patsubst-test:
	echo $(patsubst dakta%,loomt_%,dakta@example.com)

reference:

https://ruanyifeng.com/blog/2015/02/make.html

https://github.com/seisman/how-to-write-makefile