Makefile语法

一、Makefile规则格式

Makefile 里面是由一系列的规则组成的,这些规则格式如下:

目标…... : 依赖文件集合……
命令 1
命令 2
……

参考上一节gcc编译器与Makefile入门参考这条规则

  1 main: main.o input.o calcu.o2     gcc -o main main.o input.o calcu.o3 main.o: main.c4     gcc -c main.c5 input.o: input.c6     gcc -c input.c7 calcu.o: calcu.c8     gcc -c calcu.c9     10 clean:11     rm *.o12     rm main

可以看出这条规则的目标是main,依赖文件是main.o input.o calcu.o,如果要更新目标 main,就必须先更新它的所有依赖文件main.o input.o calcu.o,如果依赖文件中的任何一个如calcu.o有更新,那么目标main也必须更新,“更新”就是执行一遍规则中的命令列表。
命令列表中的每条命令必须以 TAB 键开始,不能使用空格!
make 命令会为 Makefile 中的每个以 TAB 开始的命令创建一个 Shell 进程去执行。
上述代码执行步骤如下:更新第一条规则main,发现依赖的三个.o文件还不存在,便去执行后面的三条规则先生成对应的.o文件,再生成main。最后clean没有依赖文件,因此会默认为依赖文件都是最新的,所以其对应的命令不会执行,当我们想要执行 clean 的话可以直接使用命令“make clean”,执行以后就会删除当前目录下所有的.o 文件以及 main,因此 clean 的功能就是完成工程的清理,如图
在这里插入图片描述
总结一下 Make 的执行过程:
1、make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
2、当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
3、当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。

二、Makefile变量

看下面的例子

 main: main.o input.o calcu.ogcc -o main main.o input.o calcu.o

Makefile 加入了变量支持,不像 C 语言中的变量有 int、char等各种类型,Makefile 中的变量都是字符串!类似 C 语言中的宏。使用变量将上面的代码修改

1 #Makefile 变量的使用
2 objects = main.o input.o calcu.o
3 main: $(objects)
4 	gcc -o main $(objects)

Makefile 中变量的引用方法是“$ (变量名)”,比如本例中的“$(objects)”就是使用变量 objects。

三、Makefile模式规则

将下面的工程改为模式规则

1 main: main.o input.o calcu.o
2	 gcc -o main main.o input.o calcu.o
3 main.o: main.c
4	 gcc -c main.c
5 input.o: input.c
6	 gcc -c input.c
7 calcu.o: calcu.c
8	 gcc -c calcu.c
9 
10 clean:
11	 rm *.o
12	 rm main

上述 Makefile 中第 3~8 行是将对应的.c 源文件编译为.o 文件,每一个 C 文件都要写一个对
应的规则,如果工程中 C 文件很多的话显然不能这么做。为此,我们可以使用 Makefile 中的模
式规则,通过模式规则我们就可以使用一条规则来将所有的.c 文件编译为对应的.o 文件。修改如下:

1 objects = main.o input.o calcu.o
2 main: $(objects)
3	 gcc -o main $(objects)
4 
5 %.o : %.c
6	 #命令
7 
8 clean:
9	 rm *.o
10	 rm main

模式规则中,至少在规则的目标定定义中要包涵“%”,否则就是一般规则,目标中的“%”
表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的
文件,类似与通配符,a.%.c 就表示以 a.开头,以.c 结束的所有文件。
当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值。

四、Makefile自动化变量

所谓自动化变量就是这种变量会把模式中所定义的一系列的文件自动的挨个取出,直至所有的符合模式的文件都取完,自动化变量只应该出现在规则的命令中。
用自动化变量显示最终的完整代码如下所示:

1 objects = main.o input.o calcu.o
2 main: $(objects)
3	 gcc -o main $(objects)
4 
5 %.o : %.c
6	 gcc -c $<
7
8 clean:
9	 rm *.o
10	 rm main

$ < :依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么“$<”就是符合模式的一系列的文件集合。

五、Makefile伪目标

Makefile 有一种特殊的目标——伪目标,一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,在执行 make 命令的时候通过指定这个伪目标来执行其所在规则的定义的命令。
使用伪目标主要是为了避免 Makefile 中定义的执行命令的目标和工作目录下的实际文件出现名字冲突,有时候我们需要编写一个规则用来执行一些命令,但是这个规则不是用来创建文件的,比如下面代码用来完成清理工程的功能:

clean:rm *.orm main

上述规则中并没有创建文件 clean 的命令,因此工作目录下永远都不会存在文件 clean,当我们输入“make clean”以后,后面的“rm *.o”和“rm main”总是会执行。可是如果我们在工作目录下创建一个名为“clean”的文件,那就不一样了,当执行“make clean”的时候,规则因为没有依赖文件,所以目标被认为是最新的,因此后面的 rm 命令也就不会执行,我们预先设想的清理工程的功能也就无法完成。为了避免这个问题,我们可以将 clean 声明为伪目标,声明方式如下:

.PHONY : clean

我们使用伪目标来更改上面示例代码,修改完成以后如下:

1 objects = main.o input.o calcu.o
2 main: $(objects)
3	 gcc -o main $(objects)
4 
5 .PHONY : clean
6 
7 %.o : %.c
8	 gcc -c $<
9 
10 clean:
11	 rm *.o
12	 rm main

上述代码第 5 行声明 clean 为伪目标,声明 clean 为伪目标以后不管当前目录下是否存在名为“clean”的文件,输入“make clean”的话规则后面的 rm 命令都会执行。

五、Makefile条件判断

条件关键字有 4 个:ifeq、ifneq、ifdef 和 ifndef
ifeq 用法如下:

ifeq (<参数 1>, <参数 2>)
ifeq ‘<参数 1 >,<参数 2>’
ifeq “<参数 1>,<参数 2>”
ifeq “<参数 1>,<参数 2>’
ifeq ‘<参数 1>,<参数 2>

上述用法中都是用来比较“参数 1”和“参数 2”是否相同,如果相同则为真;ifneq 是用来了比较“参数 1”和“参数 2”是否不相等,如果不相等的话就为真。
ifdef 和 ifndef 的用法如下:

ifdef <变量名>

如果“变量名”的值非空,那么表示表达式为真,否则表达式为假。

六、Makefile函数使用

Makefile 支持函数,类似 C 语言一样,Makefile 中的函数是已经定义好的,我们直接使用,不支持我们自定义函数。函数的用法如下:

$(函数名 参数集合)

或者

${函数名 参数集合}

调用函数和调用普通变量一样,使用符号 $ 来标识。参数集合是函数的多个参数,参数之间以逗号“,”隔开,函数名和参数之间以“空格”分隔开,函数的调用以“$”开头。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/268273.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

19-数据结构-查找-散列查找

目录 一、散列查找结构思路图 二、哈希函数 三、解决冲突 1.开放地址法 1.1.线性探测法&#xff08;线性探测再散列法&#xff09; 1.2.平方探测法&#xff08;二次探测再散列&#xff09; 1.3.再散列法&#xff08;双散列法&#xff09; 2.拉链法 2.1简介 四、散列查…

蓝海彤翔元宇宙技术赋能非遗苏绣文化传播

12月8日&#xff0c;第十五届中国刺绣文化艺术节在苏州高新区正式开幕。本次大会旨在激活非遗传承高质量发展内生动力&#xff0c;以民间工艺发展助力乡村振兴&#xff0c;以传统文化创造性转化、创新性发展引领刺绣工艺文化推陈出新。 在项目启动环节&#xff0c;蓝海彤翔“元…

【hcie-cloud】【8】华为云Stack_LLD设计【部署设计、资源设计、服务设计、学习推荐、缩略语】【下】

设计概览、整体架构设计、网络设计 看下面-这篇文章 【hcie-cloud】【7】华为云Stack_LLD设计【设计概览、整体架构设计、网络设计、部署设计、资源设计、服务设计】【上】 部署设计 云平台整体部署架构 图中在Region下每个灰底都代表一个数据中心&#xff0c;AZ1可以跨数据…

LED 底层原理 和 GPIO引脚、寄存器操作

目录 LED 原理 LED 的驱动方式 普适的 GPIO 引脚操作方法 GPIO 寄存器操作 LED 原理 当我们学习 C 语言的时候&#xff0c;我们会写个 Hello 程序。 那当我们写 ARM 程序&#xff0c;也该有一个简单的程序引领我们入门&#xff0c;这个程序就是点亮 LED。 我们怎样去点亮…

书-选择排序法P156

#include<stdio.h> int main(){int b[5]{8,2,6,3,7};int i , j ,k ;for(i0;i<4;i){for(ji1;j<5;j)if(b[i]<b[j]){kb[i];b[i]b[j];b[j]k;} }for(i0;i<5;i)printf("%d ",b[i]); return 0; }选择排序&#xff1a;就是自己跟下一个比较&#xff0c;然后…

BH1750光照传感器——STM32驱动

———————实验效果——————— &#x1f384;硬件外观 &#x1f384; 接线 &#x1f388; VCC接 3.3V &#x1f388; GND接 GND &#x1f388; SCL接 PB2 &#x1f388; SDA接PB3 &#x1f388; ADDR 悬空不接 &#x1f384; 代码获取 &#x1f388; 查看下方 —…

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址&#xff1a;https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…

SD-WAN架构:优化连接以提升性能

SD-WAN架构主要分为三种类型&#xff0c;分别为本地架构、支持云的架构、支持云的骨干架构。每一种架构都基于它们利用广域网&#xff08;WAN&#xff09;的方式而有其独特的优势。本文将对三种SD-WAN架构进行简要介绍。 SD-WAN本地架构 SD-WAN本地架构是在现场使用SD-WAN盒或…

微信小程序:上传图片到别的域名文件下

效果 wxml <!-- 上传照片 --> <view class"addbtn"><view classpic name"fault_photo" wx:for"{{imgs}}" wx:for-item"item" wx:key"*this"><image classweui-uploader_img src"{{item}}"…

前期只用到审批流程,好用的OA软件有哪几个?

“前期只用到审批流程&#xff0c;需要五六个人层层审批&#xff0c;最好审批流程是免费的&#xff0c;后期会扩展到其它功能&#xff0c;有适合我的软件吗&#xff1f;” 先来总结一下题主的需求&#xff1a; OA系统中审批流程最好是免费的流程需要层层审批后期能够扩展到其…

给孩子选台灯什么标准好?精选高品质的护眼台灯

孩子的身心健康&#xff0c;永远是家长最关心的事情&#xff0c;但是现在的青少年近视率非常高&#xff0c;达到了52.7%&#xff0c;也就是说平均下来&#xff0c;每十个孩子当中就有五个是近视的&#xff01;面对这样的情况&#xff0c;我们又应该如何更好的保护孩子的眼睛呢&…

项目经理该如何正确“救火”

作为一名项目经理&#xff0c;我们经常会面对意想不到的情况。有时候&#xff0c;一些本不应该出现问题的事情却突然出现了困难。比如&#xff0c;有团队成员因为突然感冒无法来上班&#xff0c;导致项目进度受到影响&#xff1b;或是客户在项目设计审批后&#xff0c;又提出了…