Linux下Makefile的编写与使用详解

目录MakefileMakefile文件命名和规则Makefile的工作原理Makefile变量Makefile函数Makefileclean规则Makefile一个工程文件中的源文件可能有很多,并...

Makefile

一个工程文件中的源文件可能有很多,并且不同的功能、模块等都放在不同的目录中,常规的编译已经不能高效化的处理这样的问题,而Makefile就是为解决这一问题而来。

Makefile一旦写好,只需一个指令,即可完成Makefile文件中所编写的所有指令,从而编译整个工程文件,。

make是一个命令工具,用来解释Makefile中的命令。

Makefile文件命名和规则

采用makefile或Makefile都可。

Makefile中的命令规则如下:

xxx(目标文件):xxx(依赖文件)
()命令(shell命令)
其中,目标文件即最终要生成的文件(伪目标除外),依赖文件即生成目标文件所需的文件,命令即shell命令。

注意,命令前必须有一个tab缩进。

例如:


#Makefile
app: a.c b.c #目标:依赖
	gcc a.c b.c -o app #注意这行最开始的缩进

以上这个后就会将目录下的与编译为目标文件。

Makefile的工作原理

如果:执行命令

如果:向下检查其他规则,是否存在其他规则生成当前规则所需要的依赖,如果有,则执行该规则中的命令。

例如:


#Makefile
app: a.o b.o
	gcc a.o b.o -o app
a.o: a.c
	gcc -c a.c -o a.o
b.o: b.c
	gcc -c b.c -o b.o

在上方这个Makefile中,当执行到app规则时,会发现所需的依赖文件a.o与b.o都不存在于当前目录,所以会向下寻找是否有其他规则生成此文件,当寻找到a.o规则时,发现其是所需的文件,就执行gcc -c a.c -o a.o,b.o同理。


如果依赖文件晚于目标文件修改时间,即依赖文件在上一次生成目标后,则会重新生成目标文件。
如果依赖文件早于目标文件修改时间,即依赖文件在上一次生成目标后,则不会执行相应的命令。
例如,你对一个Makefile使用两次make,第二次会提示。

利用这个特性,在加上我们将依赖与目标分级生成,即上方第二个Makefile,这样当我们仅修改其中的a.c文件,再一次make只会执行a.o规则与app规则,b.o规则因为b.c未修改而不执行,这样可以大大减少资源浪费。

Makefile变量

以上虽然可以减少编译代码的重复量,但是如果一个工程中有1000个.c .h文件,我们编写一个Makefile就会浪费大量时 间。因此,我们要采用一些变量来提高效率。


我们使用 来使用变量。


我们使用 如 来自定义我们所需的变量。
例如上方第一个Makefile就可改写为:


#Makefile
rsc = a.c b.c
app: $(rsc) #目标:依赖
	gcc $(rsc) -o app #注意这行最开始的缩进


有部分变量是的,我们可以直接使用。

为了方便理解接下来的例子,我们简单讲解一下Makefile中的模式匹配。
中,%是 ,匹配一个,而两个%则匹配同一个字符串。
例如上方第二个Makefile可改写为:


#Makefile
rcs = a.o b.o
app: $(rcs)
	$(CC) $(rcs) -o $@
%.o: %.c #上方规则会执行两次此规则
	$(CC) -c $< -o $@

Makefile函数

我们可以看到,上面这个Makefile已经相对简单了,但是,还是没有解决工程中文件很多的情况,rcs的获取还是要我们输入每个需要编译的文件,那么,就要采用函数来替我们去写入这些依赖文件。


这个函数的功能是获取指定目录下指定类型的文件。
其中参数PATTERN是某个目录下某种类型的文件,多个目录多个类型可用空格分隔。
返回值是一个若干个文件的文件列表,文件名用空格隔开。

例如:

$(wildcard ./*.c) 返回当前目录下的所有以c为后缀的文件。


这个函数的功能是查找text中的单词是否符合模式pattern,如果符合,则用replacement替换。
pattern可以包括通配符 % 。如果replacement中也包含 % ,那么replacement中的 % 将和 pattern中的 % 保持一致。
返回值为替换后的字符串。

例如:

$(patsubst %.c, %.o, a.c, b.c) 返回a.o, b.o。

这样,我们上面那个例子就可以改写为:


#Makefile
rcs = $(wildcard ./*.c)
objs = (patsubst %.c, %.o, $(src))
app: $(objs)
	$(CC) $(objs) -o $@
%.o: %.c #上方规则会执行两次此规则
	$(CC) -c $< -o $@

Makefile clean规则

在我们执行完make指令后,会发现当前目录下多出了很多以o为后缀的文件,但是我们仅需要最终的目标文件app,其他的都是多余的,我们该如何处理。clean规则就会帮助我们处理他们。

我们只用将clean规则添加到Makefile的最后,即可在每次编译完成后执行clean规则中的命令。如:


#Makefile
rcs = $(wildcard ./*.c)
objs = (patsubst %.c, %.o, $(src))
app: $(objs)
	$(CC) $(objs) -o $@
%.o: %.c #上方规则会执行两次此规则
	$(CC) -c $< -o $@
clean:
	rm $(objs) -f #rm指令删除 -f迭代删除

但是你会发现当前目录下多出了一个clean目标文件,依旧会采用Makefile的策略,对比修改时间,导致我们时常及时执行了clean,还是无法清除文件,那么,我们就需要接下来这个操作。

我们将clean定义为伪目标,即 .PHONY:clean 那么它就不会生成目标文件,少了对比,那么每次都会执行。

例如:


#Makefile
rcs = $(wildcard ./*.c)
objs = (patsubst %.c, %.o, $(src))
app: $(objs)
	$(CC) $(objs) -o $@
%.o: %.c #上方规则会执行两次此规则
	$(CC) -c $< -o $@
.PHONY: clean #伪目标
clean:
	rm $(objs) -f #rm指令删除 -f迭代删除

到此这篇关于linux下Makefile的编写与使用详解的文章就介绍到这了,更多相关Linux Makefile编写与使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

目录1Apache的作用2Apache的安装3apache的启用4apache的基本信息5apache的访问控制5.1基于客户端ip的访问控制5.2基于用户认证的访问控制6apache...
目录1.在usr目录下创建Hadoop目录,将安装包导入目录中并解压文件2.进入vim/etc/profile文件并编辑配置文件3.使文件生效4.进入Hadoop目录下5.编辑配置文件6.进入sla...
目录1.用户建立脚本2.猜字游戏3.网卡流量监控1.用户建立脚本(1)设计文件判断模块(2)设计用户建立(3)文件内容脚本内容#!/bin/bashUSERADD(){#用户创建函数...
1、查看Linux磁盘情况df-lhlsblk命令用于列出所有可用块设备的信息,并且显示他们之间的依赖关系。新建磁盘分区fdisk/dev/vda更改新分区磁盘类型保存分区操作并重启操作系统格式...
1.查看openjdkrpm-qa|grepjdk2.删除openjdk(rpm-e--nodeps)rpm-e--nodepsjava-1.8.0-openjdk-headles...
1.进入到/etc/init.d目录中:cd/etc/init.d2.创建tomcat服务配置文件:vitomcat3.将以下代码复制到创建的tomcat配置文件中:#idea-...