makefile

本文详细介绍了Makefile的基础知识,包括它的作用、基本规则、书写规则和注释。通过实例展示了如何编写和改进Makefile,利用默认规则和自定义规则实现自动化编译。此外,还提到了Makefile中的函数使用,如字符串替换和模式替换,以及伪目标的概念,帮助提升编译效率。
摘要由CSDN通过智能技术生成

Makefile基础

什么是makefile?

makefile关系到了整个工程的编译规则。一个工程中的源文件可以有很多,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令make脚本工具

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率

make是一个命令工具–附带在编译器–GNU GCC

GNU make,是一个解释makefile脚本文件中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

总的来说,makefile目前是帮我们完成工程管理中编译管理的重要工具。特别是大型工程。

当然makefile还可以用来做其他功能的管理工具–拓展

makefile的make基本规则

make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。

make基本规则:

  • 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。

  • 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。

对比文件修改时间

  • 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接

​ 目标程序。

makefile基本书写规则

  • makefile文件一般默认命名为makefile/Makefile(约定俗成)

make -f 自命名的make脚本文件(一般不用)

例如:

my(脚本件名)

make -f my       (命令)
  • 书写规则
目标...:依赖...
[Tab]生成目标的规则
...

目标:可以是一个.o目标文件,可以是最终的可执行文件,也可以是一个标签
依赖:生成目标所需要的文件
规则:定义如何使用依赖文件生成目标文件。一般使用shell命令--gcc,前面必须是Tab缩进

实例:

在这里插入图片描述

结果

在这里插入图片描述

当重复使用make时会显示目标已是最新

在这里插入图片描述

以上例子中

第一执行make:

Main:Call.o Deal_File.o Get_txt.o Pitch_on.o rand_num.o Write_file.o
  gcc Call.o Deal_File.o Get_txt.o Pitch_on.o rand_num.o Write_file.o -o Main

最终目标是Main,而Main的目标文件不存在;需要根据后面的依赖文件和规则生成Main;但是Call.o等这些依赖文件也不存在;那么make会去往下找生成Call.o和Deal_File.o等文件的生成规则。 先找到Call.o,Call.o生成依赖Call.c(.h文件可以不用写在这里,写了也没事),刚好Call.c文件存在,那么就会根据下面的规则编译生成Call.o;然后继续往下找剩余欠缺的目标文件,同上理生成Deal_File.o等文件。这样这些Main目标的依赖文件都有了,最后使用第一条规则生成Main可执行程序。

第二次及后续执行make:查看第一个目标,对比所有目标文件和依赖文件,如果有任何一

个依赖文件的修改时间比目标文件的修改时间新,则执行其对应规则。过程如上,最终完成

更新后最终目标文件的生成。make的这一规则减少了对已编译未更新文件的时间花费,提

高了编译链接速度。

makefile注释

#号注释

需要在行首加注释,放在其他末尾容易造成阅读以及make脚本命令识别歧义。

在这里插入图片描述

makefile编写改进

改进1(默认变量):

  • $^ 代表所有依赖 ​
  • $< 代表第一个依赖
  • $@ 代表目标文件

自定义makefile变量的规则:

  • 变量名 = 变量的内容

makefile变量的实质:

本质上只是将若干字符文本内容取个别名,你在书写makefile时,可以使用变量,但是在实际的make执行过程中,类似宏替换,所有变量替换为原来内容

变量的引用:$(变量名)

注意:在makefile变量 ,目标,依赖不能直接使用通配符,只有在规则命令中才能直接使用;但可以通过其它方法让通配符可以用在变量中。

在这里插入图片描述

自定义变量中的赋值问题:

  • = 直接赋值(展开赋值)

  • := 不展开赋值(不支持变量的嵌套 和你+=位置有关 不能将最终的变量引用过来)

  • += 追加赋值

不展开赋值:(其中的print标签用法和前面的生成规则一样,只是没有依赖)

在这里插入图片描述

在这里插入图片描述

展开赋值:

在这里插入图片描述

改进2(默认推导)

  • make 如果存在多目标,默认只执行第一目标

  • 如果需生成指定目标: make target

  • 如果依赖未生成,则先生成依赖,再生成目标

  • 如果目标文件为标准的*.o类型,则make将进行自动推导,通过同名的*.c生成*.o

  • 当默认的编译推导规则不满足需求,则可以自定义编译规则

#自定义编译规则:所有的C文件生成对应的.o,通过自定义规则进行编译
%.o:%.c 
    gcc -c $^ -o $@ 
  
    
project:$(objs)
    gcc $^ -o $@

在这里插入图片描述

在这里插入图片描述

改进3(使用Makefile函数)

函数1:
$(subst <from>,<to>,<text>)

名称:字符串替换函数——subst。
功能:把字符串<text>中的<from>字符串替换成<to>。
返回:函数返回被替换过后的字符串。

实例:

com:=,
emp:=!
foo:=a!b!c
bar:=$(subst $(emp),$(com),$(foo))

bar的值为:a,b,c
函数2:
$(patsubst <pattern>,<replacement>,<text>)
   
名称:模式字符串替换函数——patsubst。
功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式			<pattern>,如果匹配的话,则以<replacement>替换。
这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包
 含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。
(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)返回:函数返回被替换过后的字符
串。

实例:

$(patsubst %.c,%.o,x.c bar.c)
    
把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”
函数3:
wildcard函数:
使makefile中的变量能识别通配符,否则通配符只能在规则命令那里使用
    
$(wildcard  参数)
函数功能:能够识别参数的通配符 并转换为字符串

在这里插入图片描述
在这里插入图片描述

如上所示:

新建一个project文件夹,在里面新建一个inc文件夹来保存头文件(.h),新建一个src文件夹来保存源文件(.c),新建一个bin文件来保存最终生成的目标文件,将Makefile文件放到project当前路径下。

其中**@表示不显示本身执行代码,只显示结果**

-表示不论该条指令正确与否 ,继续执行后续命令

伪目标

拿clean举例,如果make完成后,自己另外定义一个名叫clean的文件,再执行make clean时,将不会执行rm命令。为了避免出现这个问题,需要伪目标**.PHONY: clean**。

当使用make命令行指定此目标时,这个目标所在规则定义的命令、无论目标文件是否存在都会被无条件执行。也就是说,如果没有定义伪目标,在当前文件夹中存在clean文件时,执行到该指令,由于没有依赖,编译器检查发现clean文件已经是最新的,那它就不会执行下面的rm命令。

声明伪目标:
.PHONY:  clean 
.PHONY: install

其它笔记:
>>变参函数
>>printf源码解读
>>数据在内存中的存储

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值