Makefile Cheatsheet
Rule Structure
A rule looks like
1 | targets: prerequisites |
只能一个一个目标地编译(必须串行运行整块指令),优先运行被依赖的文件的编译命令
1 | some_file: other_file |
clean is often used as a target that removes the output of other targets, but it is not a special word in make.
Variables
在makefile自己的定义域中定义变量,使用 $()
或者 ${}
调用变量。在sh中,$(func)
是执行命令的意思,在sh段使用sh域的变量时要用 $${X}
或者 $$X
,在makefile段将变量交给sh,需要使用 export
关键字
1 | files := file1 file2 |
Targets
The all target
Making multiple targets and you want all of them to run? Make an all target. 事实上命令行中执行make只会生成文件中第一个出现的目标
Automatic Variables
1 | hey: one two |
Wildcard
* Wildcard
*
searches your filesystem for matching filenames.
- Danger:
*
may not be directly used in a variable definitions - Danger: When
*
matches no files, it is left as it is (unless run in the wildcard function)
1 | thing_wrong := *.o # Don't do this! '*' will not get expanded |
Fancy Rules
Implicit Rules
- Compiling a C program:
n.o
is made automatically fromn.c
with a command of the form$(CC) -c $(CPPFLAGS) $(CFLAGS)
- Compiling a C++ program:
n.o
is made automatically fromn.cc
orn.cpp
with a command of the form$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
- Linking a single object file:
n
is made automatically fromn.o
by running the command$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
automatically: 只要写出target与prerequisite,不用写编译语句
The important variables used by implicit rules are:
CC
: Program for compiling C programs; default ccCXX
: Program for compiling C++ programs; default g++CFLAGS
: Extra flags to give to the C compilerCXXFLAGS
: Extra flags to give to the C++ compilerCPPFLAGS
: Extra flags to give to the C preprocessorLDFLAGS
: Extra flags to give to compilers when they are supposed to invoke the linker
Static Pattern Rules
1 | objects = foo.o bar.o all.o |
将多个 n.o: n.c
的代码压在一行的语法。
The essence is that the given target
is matched by the target-pattern
(via a % wildcard). Whatever was matched is called the stem. The stem is then substituted into the prereq-pattern
, to generate the target’s prereqs.
Static Pattern Rules and Filter
The filter function can be used in Static pattern rules to match the correct files.
1 | obj_files = foo.result bar.o lose.o |
Pattern Rules
Pattern rules are often used but quite confusing. You can look at them as two ways:
- A way to define your own implicit rules
- A simpler form of static pattern rules
1 | %.o : %.c |
Commands and execution
Command Echoing/Silencing
@
起到silent的效果
1 | all: |
Command Execution
每行命令都在新的命令行中执行;同一行内,可以用分号执行多条命令
Default Shell
默认shell是 /bin/sh
,可以通过 SHELL
来修改
1 | SHELL=/bin/bash |
(unread)Error handling with -k, -i, and -
Add -k when running make to continue running even in the face of errors. Helpful if you want to see all the errors of Make at once.
Add a - before a command to suppress the error
Add -i to make to have this happen for every command.
1 | one: |
Recursive use of make
要递归调用makefile,需要使用 $(MAKE)
,这使得makefile确认新调用的命令也是make,因此会把它的MAKEFLAGS
传过去
1 | cd subdir && $(MAKE) |
Use export for recursive make
Variables Pt.2
Flavors and modification
- recursive (use =) 使用时展开,递归调用,可能导致死循环
- simply expanded (use :=) 定义时直接展开,固定为字符串,不会死循环
- ?= only sets variables if they have not yet been set
- Use += to append, 注意会自动加空格分隔开
An undefined variable is actually an empty string!
Command line arguments and override
可以通过命令行定义变量,makefile可以override它们
You can override variables that come from the command line by using override. Here we ran make with make option_one=hi
and make option_two=hi
1 | # Overrides command line arguments |
You need to export variables to have them run in the shell as well.
one=this will only work locally
export two=we can run subcommands with this
1 | all: |
.EXPORT_ALL_VARIABLES
exports all variables for you. 写在第一行即可
Target-specific variables
在目标 all
的编译命令域内定义makefile的变量
1 | all: one = cool |
Pattern-specific variables
You can assign variables for specific target patterns
1 | %.c: one = cool |
注意要写在一行内
Conditional part of Makefiles
Conditional if/else
注意不需要indent
1 | foo = ok |
MAKEFLAGS is just a list of single characters, one per flag.
Functions
Call functions with $(fn, arguments)
or ${fn, arguments}
.
Text Functions
$(subst from,to,text)
$(subst ee,EE,feet on the street)
$(patsubst pattern,replacement,text)
Finds whitespace-separated words in text that match pattern and replaces them with replacement. Here pattern may contain a ‘%’ which acts as a wildcard, matching any number of any characters within a word. If replacement also contains a ‘%’, the ‘%’ is replaced by the text that matched the ‘%’ in pattern. 仅有第一个%按照这种方式处理$(patsubst pat,rep,$text)
=(text:pat=rep)
$(strip string)
删除开头结尾的空格$(findstring str,in)
$(findstring a,a b c)
->’a’$(findstring a,b c)
->’’$(filter pattern1 pattern2...,text)
pattern之间是或的关系,只要text中的某个word与其中一个匹配即可保留1
2
3sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo$(filter-out pattern1 pattern2...,text)
返回前述函数的补集$(sort text)
将text视为用空格分隔的单词列表,进行排序(word n,text)
n为整型,返回text的第n个单词,从1开始标号$(wordlist s,e,text)
s,e为整型,返回text的第s到第e个单词,从1开始标号
要在函数中使用特殊字符,需要使用变量来指代,如
1 | comma := , |
谨记以上函数,逗号之后不可带空格,否则被视为串的一部分
$(foreach var,list,text)
It converts one list of words (separated by spaces) to another. var is set to each word in list, and text is expanded for each word.
This appends an exclamation after each word:
1 | foo := who are you |
The if function
检查第一个元素是否非空,若非空运行第二个,否则运行第三个
The call function
Make supports creating basic functions. You “define” the function just by creating a variable, but use the parameters $(0)
, $(1)
, etc. You then call the function with the special call function. The syntax is $(call variable,param,param)
. $(0)
is the variable, while $(1)
, $(2)
, etc. are the params.
1 | sweet_new_fn = Variable Name: $(0) First: $(1) Second: $(2) Empty Variable: $(3) |
The shell function
shell - This calls the shell, but it replaces newlines with spaces!
1 | all: |
Other Features
Include Makefiles
The include directive tells make to read one or more other makefiles. It’s a line in the makefile makefile that looks like this:
1 | include filenames... |
The vpath Directive
使用vpath来指明一些前提条件的所在,格式是 vpath <pattern> <directories, space/colon separated>
,<pattern>
可以含有 %
, 可以通过 VPATH
这一变量进行全局修改
.PHONY
.PHONY: clean all
- 意味着
clean
在makefile中不代表文件名 - makefile 与当前路径下的文件
clean
无关
常用方案
1 | SRCS := $(wildcard *.c) |