makefile文件的编写规则

makefile:

makefile文件是用来管理项目工程文件的,通过执行make命令,make就会解析并执行makefile文件

makefile命名:makefile或Makefile

makefile的编写

规则:

目标:依赖

(tab)命令

makefile基本规则三要素:

目标:要生成的目标文件

依赖:目标文件由哪些文件生成

命令:通过执行该命令由依赖文件生成目标

第一个版本的makefile文件

main:main.c fun1.c fun2.c sum.c
    gcc -o main main.c fun1.c fun2.c sum.c

makefile工作原理

基本原则:

  • 若想生成目标, 检查规则中的所有的依赖文件是否都存在:

  • 如果有的依赖文件不存在, 则向下搜索规则, 看是否有生成该依赖文件的规则:

如果有规则用来生成该依赖文件, 则执行规则中的命令生成依赖文件;

如果没有规则用来生成该依赖文件, 则报错.

makefile文件的编写规则_第1张图片

若都存在,则比较目标时间和依赖时间,如果依赖时间比目标时间新,则重新生成目标;否则不重新生成。

若不存在,则往下找有没有生成依赖的规则,如果有则生成,如果没有就报错。

makefile文件的编写规则_第2张图片

第二个版本的makefile文件

main:main.o fun1.o fun2.o sum.o
    gcc -o main main.o fun1.o fun2.o sum.o
main.o:main.c
    gcc -o main.o -c main.c -I./
fun1.o:fun1.c
    gcc -o fun1.o -c fun1.c
fun2.o:fun2.c
    gcc -o fun2.o -c fun2.c
sum.o:sum.c
    gcc -o sum.o -c sum.c

makefile中的变量

在makefile中使用变量有点类似于C语言中的宏定义, 使用该变量相当于内容替换, 使用变量可以使makefile易于维护, 修改起来变得简单。

makefile有三种类型的变量:

  • 普通变量

  • 自带变量

  • 自动变量

普通变量

  • 变量定义直接用=

  • 使用变量值用$(变量名)

如:下面是变量的定义和使用

foo = abc //定义变量并赋值
bar = $(foo)//使用变量,$(变量名)

自带变量

CC = gcc #arm-linux-gcc
CPPFLAGS : C预处理的选项 -I
CFLAGS:   C编译器的选项 -Wall -g -c
LDFLAGS :  链接器选项 -L  -l

自动变量

$@:表示规则中的目标

$<:表示规则中的第一个条件

$^:表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复的项则消除重复项

模式规则

至少在规则的目标定义中要包含’%’, ‘%’表示一个或多个, 在依赖条件中同样可以使用’%’, 依赖条件中的’%’的取值取决于其目标:

比如: main.o:main.c fun1.o: fun1.c fun2.o:fun2.c, 说的简单点就是: xxx.o:xxx.c

第三个版本的makefile

target=main
object=main.o fun1.o fun2.o sum.o
CC=gcc
CPPFLAGS=-I./
$(target)=$(object)
    $(CC) -o $@ $^
%.o:%.c
    $(CC) -o $@ -c $< $(CPPFLAGS) 

makefile函数

  1. wildcard – 查找指定目录下的指定类型的文件

src=$(wildcard *.c)  //找到当前目录下所有后缀为.c的文件,赋值给src
  1. patsubst – 匹配替换

obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o

makefile的第四个版本

target = main
src = $(wildcard ./*.c)//找到该目录下所有的.c文件,将其赋值给src
object = $(patsubct %.c,%.o,$(src))//将src中左右的.c文件替换成.o文件赋值给object
CC=gcc
CPPFLAGS = -I./
$(target) = $(object)
    $(CC) -o $@ $^
%.o:%.c
    $(CC) -o $@ -c $< $(CPPFLAGS)

缺点:每次重新编译都需要手工清理中间.o文件和最终目标文件

makefile的清理操作

用途: 清除编译生成的中间.o文件和最终目标文件

make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令, 解决方案:

  • 伪目标声明:

.PHONY:clean

  • 声明目标为伪目标之后,makefile将不会检查该目标是否存在或者该目标是否需要更新

  • clean命令中的特殊符号:

  • “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”

rm -f: 强制执行, 比如若要删除的文件不存在使用-f不会报错

  • “@”不显示命令本身, 只显示结果。如:“@echo clean done”

  • 其它

–make 默认执行第一个出现的目标, 可通过make dest指定要执行的目标

– make -f : -f执行一个makefile文件名称, 使用make执行指定的makefile: make -f mainmak

makefile的第五个版本

src=$(wildcard ./*.c)
object=$(patsubst %.c,%.o,$(src))
target=main
CC=gcc
CPPFLAGS = -I./
$(target):$(object)
    $(CC) -o $@ $^
%.o:%.c
    $(CC) -o $@ -c $< $(CPPFLAGS)
.PHONY:clean
clean:
    -rm -f $(target) $(object)

使用-f可以指定makefile文件,如: make -f mainmak

你可能感兴趣的:(C++,Linux,linux)