1.Makefile基础
Makefile 基本示例(.PHONY
表示clean是伪目标文件,-表示不管是否失败都继续执行,clean不要放开头,不然变成了makefile的默认目标)
main:main.o add.o del.o
cc -o main main.o add.o del.o
main.o:main.c
cc -c main.c
add.o:add.c
cc -c add.c
del.o:del.c
cc -c del.c
.PHONY : clean
clean:
-rm main *.o
使用变量优化一下
OBJ = main.o add.o del.o
main : $(OBJ)
cc -o main $(OBJ)
main.o:main.c main.h command.h
cc -c main.c
add.o:add.c add.h command.h def.h
cc -c add.c
del.o:del.c del.h command.h def.h
cc -c del.c
.PHONY : clean
clean:
rm main $(OBJ)
使用makefile自动推导功能优化下(可以自动找到.o文件的依赖关系,并推导出cc -c xx.c)
OBJ = main.o add.o del.o
main : $(OBJ)
cc -o main $(OBJ)
$(OBJ):command.h
add.o del.o: def.h
.PHONY : clean
clean:
rm main $(OBJ)
2.Makefile综述
2.1文件名一般Makefile或makefile;此时直接运行make就行;若是其他,如Make.Linux,需要运行make -f
Make.Linux
2.2引用其他makefile或变量
include make.a
2.3搜索路径
VPATH =
src:../header (如果当前路径没有,到src和header目录中搜索)
vpath %.h ../header
(可以分类搜索)
vpath %.c foo
vpath % blish
vpath %.h (清除%.h匹配路径)
vpath (清除所有的)
2.4伪目标
伪目标不是文件,不能有重名文件;当然可以使用.PHONY指明伪目标,不管是否有重名文件;
可以放在Makefile第一位;
如:
.PHONY : all
all : target1 target2
target3
伪目标也可以有依赖,如下:(可以按要求清除不同类型文件)
.PHONY: cleanall
cleanobj
cleanall:cleanobj
rm xx
cleanobj:
rm obj
2.5多目标 bigoutput
littleoutput : text.g
generte text.g -$(subst output,,$@) > $@
2.5.1自动化变量
$@ 所有目标集合,依次取出
$< 所有依赖集合
2.5.2Makefile函数
$(subst
output,,$@)
2.6静态模式(更好的处理多目标)
目标集合:目标集模式:目标依赖模式
OBJ=a.o b.o
all:$(OBJ)
$(OBJ):%.o:%.c
cc -c $< -o $@
2.7自动生成依赖性
cc -MM a.c
可以自动找依赖文件,但是不能再跟其他选项
2.8显示,执行,嵌入式执行make
@echo qqq (只会显示命令输出)
cd /home/guo; pwd
(需要在一行,以分号分割)
或者 cd /home/guo && $(MAKE) ($MAKE是makefile自有变量,实际为make)
$(MAKE) -C /home/guo
2.9定义命令包,如下:
define my_order
rm *.o
mv a b
endef
test:
$(my_order)
2.10Makefile中变量值替换
a := a.o b.o c.o
b := $(a:.o=.c)
b变成了a.c b.c c.c
或者
b := $(a:%.o=%.c)
2.11条件判断
ifeq($(CC),gcc)
else
endif
ifeq($(strip $(foo)), ) 如果函数返回值为空
ifneq
ifdef
2.12变量
变量定义:
A =
$(B)a B =
$(A) 可能无限循环
A := $(B)a
B := $(A) 不能使用后面的变量,安全
FOO ?= bar
如果FOO没定义过,其值为bar
nullstring
:=
space :=
$(nullstring) #end of the line 代表定义个空格
2.13变量定义中使用变量
first_second
= Hello
a =
first
b =
second
all =
$($a_$b) all为Hello
2.14Makefile中函数
字符串:
$(subst
from,to, text) 字符串替换,把text中from替换成to
$(patsubt
pattern, replacement, text)
模式字符串替换,text中单词是否匹配pattern,若匹配replacement;
$(strip
text) 去空格函数
$(findstring
find, text) 字符串查找,text中查找find,如果找到返回find,否则空
$(filter
pattern, text) 过滤,text中查找pattern模式的字符串,模式可以多个
cc $(filter %.c %s, $(sources)) -o foo 只编译.c .s文件;
$(filter-out
pattern, text) 反过滤函数
$(word n,
text) 取单词函数,text中取出第n个单词
$(wordlist 2,3 $(text)) 取出第2,3个单词
$(words
$(text))统计单词个数
文件名:
$(dir
src/foo.c hacks) 返回"src/ ./" 取路径名
$(notdir
src/foo.c hacks) 返回"foo.c hacks" 取文件名
$(addprefix
.c, foo bar) 返回"foo.c bar.c" 加后缀函数
foreach函数
names := a b c d
files :=
$(foreach
n,$(name),$(n).o) files为a.o b.o c.o d.c
3.make参数
make -n 仅输出执行过程中的命令序列,但并不执行
make -s 全面禁止命令的显示
make -i 或者 -rm .IGNORE 规则中多有都忽略错误
make -k 某一个规则中忽略错误
make -e 覆盖下一层变量 $(MAKE) -C
tt cd tt
&& $(MAKE)
注:
$@ 所有目标文件
$< 每个被改过的依赖文件
$? 所有被改过的依赖文件
例子:
CC=gcc
INC_DIR=-I/root/guo/tmp/1/inc
LIB_PATH=
LIB_NAME=
LIBS=
EXE_DIR=.
CFLAGS=-c -g $(INC_DIR)
C_SRC=add.c del.c main.c
OBJS=$(C_SRC:.c=.o)
EXES=main
all:$(EXES)
$(EXES):$(OBJS)
$(CC) -o $@ $?
%.o:%.c
$(CC) -c -g $(INC_DIR) $<
#LIB_DIR=.
#LIB_BASEFUNC=$(LIB_DIR)/libbase.a
#all:$(LIB_BASEFUNC)
#$(LIB_BASEFUNC):$(OBJS)
# ar -rv $@ $?
.PHONY:clean
clean:
@echo clean temp files
@-rm *.o main
@echo clean end