Linux Makefile及其规则介绍

Makefile在绝大多数的IDE中都在使用,已经成为一种工程的编译方法。

Makefile:项目的代码管理工具,用于管理工程编译。通过把所有源代码的编译命令写入makefile来达到多文件统一编译。

一、初识Makefile

1、在公司中,架构师负责把各模块集中起来做成makefile提供给公司内部人员使用。

2、Makefile实质:写好的makefile其实就是一个文件,内部写好了各个分模块的编译规则。

3、Makefile文件两种命名规则:全小写(makefile) 或者  首字母大写(Makefile);

4、Makefile写法规则中的三要素:目标、依赖、命令;

//格式:
//目标:依赖条件
//[tab]命令
//举例如下:
app:main.c add.c sub.c mul.c
    gcc main.c add.c sub.c mul.c -o app

5、Make是一个命令工具,它用于解释Makefile中的指令(具体说是规则);在Makefile文件中描述了整个工程的所有文件的编译顺序、编译规则。

注:一般把  .c  和  makefile 放在同一目录下。

6、Makefile优化

上方所写makefile依赖项是 .c  文件,当其中一个 .c 文件发生变化时,其余的 .c 文件也需要跟着它重新编译,显然效率不高,为了提高效率,让单个文件发生变化后,仅编译发生变化的 .c 文件,需要将各个模块分开编译,此时依赖项需要编程 .o 文件

app:main.o add.o sub.o mul.o
    gcc main.o add.o sub.o mul.o -o app
main.o:main.c
    gcc -c main.c
add.o:add.c
    gcc -c add.c
sub.o:sub.c
    gcc -c sub.c
mul.o:mul.c
    gcc -c mul.c

各模块分开编译好处:避免了一个 .c 修改后,所有的 .c 都需要跟着重新编译的缺陷,提高了程序编译的效率。

此时,先执行终极目标app,查找终极目标的依赖项,若某项没有则执行下方的子目标以生成该项依赖,最后集齐所有终极目标的依赖项后,执行终极目标下方的命令已完成最终编译。

二、Makefile工作原理剖析

1、Makefile工作原理叙述:先执行终极目标app,查找终极目标的依赖项,若某项没有则执行下方的子目标以生成该项依赖,最后集齐所有终极目标的依赖项后,执行终极目标下方的命令已完成最终编译。

2、Makefile:目标生成原理

Makefile目标生成规则:首先检查以来的条件是否存在,存在通过命令直接生成对应的目标,若不存在,向下寻找对应的子目标,根据其规则生成依赖条件,最终集齐各依赖项后执行下方命令生成对应的目标。流程详见下图:

3、Makefile:目标更新机制

每次生成目标前,检查目标和依赖项之间是否一致,若依赖项修改了,则重新编译此项目;

三、Makefile变量介绍及使用

Makefile中也支持变量的使用,但弱化了变量的类型,即随定义随时用;同时Makefile也维护了一批内置变量和自动变量(只能在规则中的命令中使用)

Makefile常用的三个自动变量:
1、$< : 代表规则中的第一个依赖
2、$@ : 代表规则中的目标
3、$^ : 代表规则中所有的变量
注:自动变量只能在规则中的命令中使用

Makefile的模式规则:
% : 此处代表所有的项,谁符合条件件是谁的值(类似于shell中的 *)

Makefile中自己维护的变量:
CC=cc (小写cc代表gcc)
注:用户也可以修改内置变量的默认值

Makefile用户自定义变量:
如:obj=main.o add.o sub.o mul.o
注:使用时需要加 $ 表示提取变量内容 如:gcc $(obj) -o app

四、使用Makefile变量再优化上面的Makefile

 obj=main.o add.o sub.o mul.o
 target=app
 $(target):$(obj)
     gcc $(obj) -o $(target)

 %.o:%.c
     gcc -c $< -o $@

五、Makefile常用函数及Makefile继续优化

1、Makefile函数:任意Makefile中的函数均有返回值

2、Makefile常用函数

注:Makefile函数的参数不需要写在括号内,直接在函数名后加空格间隔,紧接着写参数

wildcard函数:显示指定路径下指定文件类型的所有文件
使用:src=$(wildcard ./*.c)
解释:从当前路径下查找所以有以 .c 结尾的文件名作为参数回传给src变量

patsubst函数:模式字符串替换函数
使用:obj=$(patsubst ./%.c,./%.o,$(src))
解释:把src中以 .c 结尾的值变为以 .o 结束

3、Makefile伪目标的声明及定义

伪函数声明语句
.PHONY:clean

定义语句:
clean:
    rm -f $(obj)

注:把clean声明成伪目标的好处:每个Makefile执行后,每个目标都会生成对应的文件,此处clean目标无依赖项,所以不需要做改变项的检查,因此声明成伪目标,每次都执行它

4、Makefile继续优化

target=app

src=$(wildcard ./*.c)
obj=$(patsubst ./%.c, ./%.o, $(src))
CC=gcc

$(target):$(obj)
    $(CC) $(obj) -o $(target)

%.o:%.c
    $(CC) -c $< -o $@

.PHONY:clean  //把clean声明成伪目标
clean:
    rm -f $(obj)  //-f选项:强制执行

此次Makefile的编写加入了Makefile函数的使用,同时加入了新的目标clean,它用于在执行makefile的同时删除生成的用于过渡的 .o 文件;

此时执行makefile时,需要做到:

make && make clean

注:这里显示生成了 clean 目标,因为clean目标没有依赖项,但需求是生成clean目标,所以需要显示指定生成 clean 目标

5、Makefile语句细节优化案列

“-” :在命令前加“-”号,忽略不可执行的命令,不中断Makefile执行

如:简单写一个目标
1、clean:
       mkdir /aaa
       rm -f $(obj)

此时,执行到mkdir命令行会终止后续项的执行,因为普通用户权限不足;这样就会影响Makefile整体的容错能力

2、clean:
       -mkdir /aaa
       rm -f $(obj)
此时,执行到mkdir命令行是不会终止,makefile只是忽略它无权限或不能执行的命令,继续执行后续项

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Star星屹程序设计

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值