> 文档中心 > MakeFile的使用

MakeFile的使用


Makefile 其实只是⼀个指示 make 程序(后⾯简称 make 或有时称之为 make 命令)如何为我们⼯作的命令⽂件,我们说 Makefile 其实是说make

软件产品开发在编码阶段最常⻅的⼯作内容⼤致是:

        1.开发人员根据概要设计进行编码。

        2.开发人员编译所设计的源代码以生成可执行文件。

        3.开发人员对软件产品进行测试来验证其功能的正确性。

在上⾯的⼏步中,与 Makefile 关系最⼤的是第⼆步,那 Makefile 的好坏对于项⽬开发有些什么影响呢?设计得好的 Makefile,当我们重新编译时,只需编译那些上次编译成功后修改过的⽂件,也就是说编译的是⼀个 delta,⽽不是整个项⽬。反之,如果⼀个不好的 Makefile 环境,可能对于每⼀次的编译先要clean,然后再重新编译整个项⽬

最为重要的是掌握⼆个概念,⼀个是⽬标(target),另⼀个就是依赖(dependency)。⽬标就是指要⼲什么,或说运⾏ make 后⽣成什么,⽽依赖是告诉 make 如何去做以实现⽬标。在 Makefile 中,⽬标和依赖是通过规则(rule)来表达的。我们最为熟悉的是采⽤make 来进⾏软件产品的代码编译,但它可以被⽤来做很多很多的事情,后⾯我们会给出⼀些不是⽤ make 来进⾏代码编译的例⼦。驾驭 Makefile,最为 重要的是要学会 采⽤⽬标和依赖关系 来思考所需解决的问题。

makefile 三个要素

 简单的命令终端上输出:test可以是目标也可以是依赖,所以all依赖test

(1) 目标    依赖     命令(以tab键空出来),可以make 某个目标(类似于函数的调用)

(2)make 工具会按从左到右的先后顺序先构建规则中所依赖的每一个目标

all: test    @echo "hello all"test:    @echo "hello test"

 (3) 伪对象:  (.PHONY: test)

        以2为例子:如果在同一个文件夹里面如果有和目标同名的文件,如不加伪对象就会报错  ,如下图: 

 加上伪对象之后就会忽略掉当前文件夹上的test文件:

Makefile的工作原理:

makefile的语法

 1.编译简单两个c文件:

//foo.c#include void foo () {printf("This is foo   ()!\n");}//main.cextern void foo();int main (){foo();return 0;}

 all :后边的名字是依赖,也就是下边对应的命令

all: main foogcc -o simple main.o foo.omain: gcc -o main.o -c main.cfoo: gcc -o foo.o -c foo.cclean:rm simple main.o foo.o

 直接执行make,就是执行了以下的命令:就会生成3个文件foo.o  main.o   simple

2.1.变量(语言的变量,都懂)

2.2.自动变量 :以上变量不好的地方就是,如果我们改了文件名字就需要进去改makefile

先介绍语法:

$@  :用于表示一个规则中的目标。当我们的一个规则中有多个目标时,$@所指的是其中任何造成命令被运行的目标

$^  : 表示是规则中的所有先择条件。也就是依赖

$< : 表示的是规则中的第一个先决条件。也就是第一个依赖

 2.3 常用的两个函数 wildcard(通配符)   patsubst(替换)

.PHONY:cleanCC = gccRM = rmEXE = simpleSRCS = $(wildcard *.c)   #匹配所有的c文件名OBJS = $(patsubst %.c,%.o,$(SRCS)) #把所有匹配到的c文件替换成.o文件名$(EXE) : $(OBJS)$(CC) -o $@ $^%.o: %.c$(CC) -o $@ -c $^clean:$(RM) $(EXE) $(OBJS)

 2.3.2 addperfix 函数 :用来给字符串中的每个子串前加上一个前缀,形式是:$(addprefix   prefix,   names)

.PHONY:allwithout_dir = foo.c foo2.c main.owith_dir  := $(addprefix  objs/, $(without_dir))all:    @echo $(with_dir)#这样就可以访问就能拼接到别的文件夹去拿别的文件过来编译了

 2.3.3 filter  从一个字符串中,留下满足的字符串,其形式是: $(filter  pattern..., text)。同伴filter-out把匹配的给去除掉   多个是以空格隔开的

.PHONY:allwithout_dir = $(wildcard *)with_dir  := $(filter  %.c %.s, $(without_dir))all: @echo $(with_dir)