Make

Make command usually write in Makefile.

Makefile syntax

Makefile construct by rules.

1
2
3
# rule
<target> : [prerequisites]
  <commands>

target

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

1
2
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.

1
2
3
.PHONY: clean
clean: 
  rm *.o temp

targets

[prerequisites]

example:

1
2
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 \ before other line.

  3. Add the target .ONESHELL:

other syntax

echoing

Make will print each command, and add @ before each line can close the echoing.

Usually, we will add @ before #.

wildcard *

*: all words ?: one word ...: all sub directory

match *

% can match some part of file name

1
%.o: %.c

variable *

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

implicit variables

1
$(CXX) -o a a.c
automatic variables *

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

for *
1
2
3
4
5
6
7
8
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 *

without tab

1
2
3
4
5
6
if-test:
ifeq (g++,$(CXX))
  echo "cxx eq g++"
else
  echo "cxx neq g++"
endif
function *

Shell

1
2
3
4
goenv := $(shell  go env)

shell-test:
  echo $(goenv)

Wildcard

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

Subst

1
2
3
4
5
6
7
8
9
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)

Pastsubst

1
2
pastubst-test:
  echo $(patsubst dakta%,loomt_%,dakta@outlook.com)

reference:

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

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

updatedupdated2024-04-122024-04-12