Makefile
语法
规则 变量 自动化变量 模式规则 伪目标 条件判断 函数
- 规则
target ... : prerequisites ...
command
...
- 变量
- = 在给变量的赋值的时候,不一定要用已经定义好的值,也可以使用后面定义的值
- := 不会使用后面定义的变量,只能使用前面已经定义好的
- ?= 如果变量前面没有被赋值,那么在此赋值, 如果前面已经赋过值了,那么就使用前面赋的值
- += 已经定义好的变量添加一些字符串
- 自动化变量
- $@ 规则中的目标集合,在模式规则中,如果有多个目标的话, $@表示匹配模式中定义的目标集合
- $% 当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件, 那么其值为空
- $< 依赖文件集合中的第一个文件,如果依赖文件是以模式(即”%”)定义的,那么 “$<“就是符合模式的一系列的文件集合
- $? 所有比目标新的依赖目标集合,以空格分开
- $^ 所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件, $^会去除重复的依赖文件,值保留一份
- $+ 和 $^类似,但是当依赖文件存在重复的话不会去除重复的依赖文件
- $* 目标模式中%及其之前的部分,如果目标是 test/a.test.c,目标模式为 a.%.c,那么$* 就是 test/a.test
- 模式规则 %
- 伪目标
.PHONY
- 条件判断 ifeq, ifneq, ifdef 和 ifndef
libs_for_gcc = -lgnu
normal_libs =
foo: $(objects)
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
- 函数
$(subst <from>,<to>,<text>) =>把字串 <text> 中的 <from> 字符串替换成 <to>
$(patsubst <pattern>,<replacement>,<text>) =>模式字符串替换函数
$(wildcard <pattern...>)
$(strip <string>) =>去掉 <string> 字串中开头和结尾的空字符
$(findstring <find>,<in>) =>在字串 <in> 中查找 <find> 字串
$(filter <pattern...>,<text>) =>过滤函数
$(filter-out <pattern...>,<text>) =>反过滤函数
$(sort <list>) =>给字符串 <list> 中的单词排序(升序)
$(word <n>,<text>) =>取字符串 <text> 中第 <n> 个单词。(从一开始)
$(wordlist <ss>,<e>,<text>) =>取单词串函数
$(words <text>) =>统计 <text> 中字符串中的单词个数
$(firstword <text>) =>取字符串 <text> 中的第一个单词
$(dir <names...>) =>取目录函数
$(notdir <names...>) =>取文件函数
$(suffix <names...>) =>从文件名序列 <names> 中取出各个文件名的后缀
$(basename <names...>) =>从文件名序列 <names> 中取出各个文件名的前缀部分
$(addsuffix <suffix>,<names...>) =>把后缀 <suffix> 加到 <names> 中的每个单词后面
$(addprefix <prefix>,<names...>) =>把前缀 <prefix> 加到 <names> 中的每个单词后面
$(join <list1>,<list2>) =>连接函数
$(foreach <var>,<list>,<text>) =>把参数 <list> 中的单词逐一取出放到参数 <var> 所指定的变量中,然后再执行 <text> 所包含的表达式
$(if <condition>,<then-part>) =>if 函数
$(if <condition>,<then-part>,<else-part>) =>if 函数
$(call <expression>,<parm1>,<parm2>,...,<parmn>) =>创建新的参数化的函数
$(origin <variable>) =>这个变量是哪里来的
contents := $(shell cat foo) =>操作系统 Shell 的命令
$(error <text ...>) =>控制 make 的运行
代码实例
空白模板
C文件编译5个demo
# demo1
hellomake: hellomake.c hellofunc.c hellomake.h
gcc -o hellomake hellomake.c hellofunc.c -I.
# demo2
CC=gcc
CFLAGS=-I.
hellomake: hellomake.o hellofunc.o
$(CC) -o hellomake hellomake.o hellofunc.o
# demo3
CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: hellomake.o hellofunc.o
$(CC) -o hellomake hellomake.o hellofunc.o
# demo4
CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
OBJ = hellomake.o hellofunc.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
# demo5
IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)
ODIR=obj
LDIR =../lib
_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = hellomake.o hellofunc.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(IDIR)/*~
pandoc转html
Makefile to use pandoc to convert all markdown files to html and pdf
# Makefile
#
# Converts Markdown to other formats (HTML, PDF) using Pandoc
# <http://johnmacfarlane.net/pandoc/>
#
# Run "make" (or "make all") to convert to all other formats
#
# Run "make clean" to delete converted files
#
# Adapted from: https://gist.github.com/kristopherjohnson/7466917
# Convert all files in this directory that have a .md suffix
SOURCE_DOCS := $(wildcard *.md)
EXPORTED_DOCS=\
$(SOURCE_DOCS:.md=.html) \
$(SOURCE_DOCS:.md=.pdf) \
RM=/bin/rm
PANDOC=pandoc
PANDOC_OPTIONS=--smart --standalone
PANDOC_HTML_OPTIONS=--to html5
PANDOC_PDF_OPTIONS=
# Pattern-matching Rules
%.html : %.md
$(PANDOC) $(PANDOC_OPTIONS) $(PANDOC_HTML_OPTIONS) -o $@ $<
sed -i 's:\.md:.html:g' $@
%.pdf : %.md
$(PANDOC) $(PANDOC_OPTIONS) $(PANDOC_PDF_OPTIONS) -o $@ $<
# Targets and dependencies
.PHONY: all clean
all : $(EXPORTED_DOCS)
clean:
- $(RM) $(EXPORTED_DOCS)
.PHONY : all
# arg1 dir
define EXPAND_temp
FILES := $(wildcard $(1)*)
DIRS :=
$$(foreach e, $$(FILES), $$(if $$(wildcard $$(e)/*), $$(eval DIRS := $$(DIRS) $$(e))))
FILES := $$(filter-out $$(DIRS),$$(FILES))
ALLFILES := $$(ALLFILES) $$(FILES)
$$(foreach e,$$(DIRS),$$(eval $$(call EXPAND_temp,$$(e)/)))
endef
$(eval $(call EXPAND_temp))
all :
@echo $(ALLFILES)