简介:
自动化编译:只需要一个make命令,整个工程自动编译
提高编译效率:再次编译时,只编译修改的文件(查看时间戳,根据修改文件的时间判断文件是否被修改)
基本语法:
{
目标:依赖
命令
}
{
target... : prerequisites ...
command
}
target 也就是一个目标文件,可以是 Object File ,也可以是执行文件。还可以是一个标签( Label ),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites 就是,要生成那个 target 所需要的文件或是目标。
command 也就是 make 需要执行的命令。(任意的 Shell 命令)
例:
一步编译:.c——>exe
test:add.c sub.c test.cgcc add.c sub.c test.c -o test
两步编译:.c——>.o ——>exe
add.o:add.cgcc -c add.c -o add.o
sub.o:sub.cgcc -c sub.c -o sub.o
test.o:test.cgcc -c test.c -o test.o
test:add.o sub.o test.ogcc add.o sub.o test.c -o test
注意:
1.makefile只识别第一个目标,也就是上图中的add.o
2.因此应修改为下图中的形式,将最终目标作为第一目标
3.会去找当前路径下第一目标的依赖文件,如果依赖文件不存在,就会去找下一个目标,直到第一目标的依赖全部得到
test:add.o sub.o test.ogcc add.o sub.o test.c -o test
add.o:add.cgcc -c add.c -o add.o
sub.o:sub.cgcc -c sub.c -o sub.o
test.o:test.cgcc -c test.c -o test.o
4.make默认执行第一目标,直接执行其他目标格式为"make+目标名"
例:make clean
test:add.o sub.o test.ogcc add.o sub.o test.c -o test
add.o:add.cgcc -c add.c -o add.o
sub.o:sub.cgcc -c sub.c -o sub.o
test.o:test.cgcc -c test.c -o test.o
clean:rm *.o
5.如果当前目录下有最新的clean文件,执行make clean时将会报错,因此修改如下图,通过建立伪目标方式(不是真正想要生成clean文件)
test:add.o sub.o test.ogcc add.o sub.o test.c -o test
add.o:add.cgcc -c add.c -o add.o
sub.o:sub.cgcc -c sub.c -o sub.o
test.o:test.cgcc -c test.c sub.o test.o#伪目标
.PHONY:clean
clean:rm *.o
makefile的变量:
自定义变量:
x = a 变量在声明时需要给予初值(给变量x赋值a)
$(x) 或 ${x} 取值
例:
SRC=add.o sub.o test.otest:add.o sub.o test.ogcc $(SRC) -o test
add.o:add.cgcc -c add.c -o add.o
sub.o:sub.cgcc -c sub.c -o sub.o
test.o:test.cgcc -c test.c sub.o test.o#伪目标
.PHONY:clean
clean:rm *.o
注意:
1.如果你要使用真实的 $ 字符,那么你需要用 $$ 来表示。
2.
SRC=add.o sub.o test.otest:add.o sub.o test.ogcc $(SRC) -o test
变量的赋值:
自动化变量:
此些符号表示变量名,代表了符合的文件(以及输出方式)
隐含变量:
此下变量名是专门为一个功能提供的。
makefile的条件判断:
ifeq:
使用方式:ifeq开头,endif结尾
ifeq($(ARCH),X86)
CC=gccelseCC=arm-none-linux-gcc
endif
含义:如果变量ARCH中的值为X86,执行CC=gcc操作,否则就执行CC=arm-none-linux-gcc操作
ifneq:
使用方式同ifeq,意思相反
ifdef:
使用方式ifdef开头,endif结尾
ifdef ARCH
CC=gccelseCC=arm-none-linux-gcc
endif
含义:如果变量ARCH被定义,执行CC=gcc,否则执行CC=arm-none-linux-gcc
ifndef:
使用方式同ifdef
makefile函数:
基本语法:
$(<function> <arguments>)
或是
${<function> <arguments>}
$(<函数名><参数1,参数2,参数3,.....>)
wildcard函数:
$(wildcard PATTERN)
功能:列出当前目录下所有符合模式“ PATTERN” 格式的文件名。
返回:空格分割的、存在当前目录下的所有符合模“ PATTERN” 的文件名。
说明:“ PATTERN” 使用 shell 可识别的通配符,包括“ ?” (单字
符)、“ *” (多字符)等。
示例: $(wildcard *.c) 返回值为当前目录下所有 .c 源文件列表。
示例:
SRC=$(wildcard *.c)all:echo $(SRC)
输出为当前路径下所有的.c文件
patsubst函数:
$(patsubst <pattern>,<replacement>,<text>)
名称:模式字符串替换函数。
功能:查找 <text> 中的单词(单词以“空格”、“ Tab” 或“回车”“换行”分隔)是否符合模式 <pattern> ,如果匹配的话,则以<replacement> 替换。
这里, <pattern> 可以包括通配符 % ,表示任意长度的字串。
如果 <replacement> 中也包含 % ,那么, <replacement>中的这个 % 将是 <pattern> 中的那个 % 所代表的字串。(可以用 \ 来转义,以 \% 来表示真实含义的 % 字符)
返回:函数返回被替换过后的字符串。
例:
SRC=$(wildcard *.c)
OBJ=$(patsubst %.c,%.o,$(SRC))all:echo $(OBJ)
含义:将路径下所有.c文件赋值到SRC中,再将SRC中的文件与是否符合.c后缀,如果符合,就使用.o后缀替换SRC中的文件,返回值赋值给OBJ
自定义函数:
需要使用系统提供的call函数
例:
含义:定义echo ”*****“的名字为MYFUN,使用call函数调用MYFUN函数
define MYFUNecho "*****"
endefall:$(call MYFUN)
含义:定义MYFUN函数,输出的参数是以call函数的参数
define MYFUNecho "*****"echo $(0) //表示输出第一个参数echo $(1) //表示输出第二个参数echo $(2) //表示输出第三个参数
endefall:$(call MYFUN,10,20) //第一个参数:MYFUN;第二个参数:10;第三个参数:20;
注意:
1.依赖可以是0个也可以是多个,用空格隔开
2.命令前需要使用Tab键空开
3.使用"#"作为注释符
4.在终端make命令后也可以赋值
含义:执行make命令,并且给ARCH变量赋值X86
make ARCH=X86
5.如果函数名称正确,函数名将会变成黄色,函数与参数之间使用空格隔开,参数间使用逗号隔开
6.
相关命令:
echo:
使用方式:echo+数据
功能:将数据输出到终端
@:
在makefile文件的命令前加@,命令的名称将不会显示在终端上(仍会执行)
例:
SRC=add.o sub.o test.otest:add.o sub.o test.ogcc $(SRC) -o test
add.o:add.cgcc -c add.c -o add.oecho $*echo $@@echo $*@echo $@sub.o:sub.cgcc -c sub.c -o sub.o
test.o:test.cgcc -c test.c sub.o test.o#伪目标
.PHONY:clean
clean:rm *.o
输出如下图:
echo add.c
echo add
add.c
add
终端上只会显示自动化变量" * "表示的值,不会显示"echo"命令名称
gcc:
-E:预处理,生成.i文件
-S:编译,生成.s文件
-c:汇编,生成.o文件
-g:生成GDB调试信息
-I(大爱):+文件路径,链接其他路径下文件
-Wall:调试错误