Linux应用(二)——Makefile

目录

一、什么是Makefile?

二、如何编写Makefile文件

三、工作原理

四、变量

五、模式匹配 

六、函数

一、什么是Makefile?

        在一个工程中的源文件不计其数,为了方便管理,我们将其按类型、功能、模块分别放在若干个目录中。Makefile 文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编 译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

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

        好处:自动化编译;使用:make命令;效果:自动化编程;作用:提高软件开发效率;简单来说:为了方便多文件管理,编写的一个拥有编译规则的文件。

二、如何编写Makefile文件

1、命名:

文件命名:Makefile或者makefile;

2、Makefile规则

一个Makefile文件中可以有一个或者多个规则

规则:

目标...:依赖...

        命令(shell命令)

        ...

目标:最终要生成的文件(伪目标除外)

依赖:生成目标所需要的文件或是目标

命令:通过执行命令对依赖操作生成目标(命令前必须 Tab 缩进

此外,Makefile中的其他规则一般都是为第一条规则服务的;

在lesson07中编写Makefile文件:

使用make进行编译,第一次使用需要安装make指令;

make进行编译:

 运行结果:

三、工作原理

1、命令在执行之前,需要先检查规则中的依赖是否存在 

Yes: 执行命令;

No:,向下检查其它的规则,检查有没有一个规则是用来生成这个依赖的, 如果找到了,则执行该规则中的命令(所以说:Makefile中的其他规则一般都是为第一条规则服务的;)

例如上面的Makefile文件中:第一个规则中的依赖都是.o文件,而.o文件根本不存在,在执行的时候,需要检查是否存在,这时不存在,就要检查底下的规则中是否能够产生依赖,如果能够产生,就可以执行。显然是可以产生的,底下的5个规则就产生了5个依赖。这也就显然,底下的规则是为了第一条规则服务的。

如果下面的规则与第一条规则无关,则不会执行,除非进行手动的调动,因为默认情况下,make执行Makefile中的第一条规则。

2、 检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间

        什么意思呢?我们知道在写代码的时候,代码需要不断的更新修改,这样产生的可执行程序也就需要不断的更新。那什么时候需要更新?什么时候不需要更新呢?

        如果依赖的时间比目标的时间晚,需要重新生成目标。也就是在规则中,对依赖进行命令产生目标,只要依赖的生成时间比目标的生成时间晚,就证明了更新,就需要更新目标。

上述代码中,一旦.c文件发生更新,则.o文件就需要重新更新,因为依赖新产生。进一步.o作为app的依赖也会进行更新。

四、变量

变量是干什么呢?

先说出来变量的作用,在较为减到的Makefile文件中,变量的作用还不太明显,然而一旦Makefile中的内容过于复杂,则需要变量进行简化。如何简化呢?

首先是进行变量的规则介绍:

自定义变量:

        变量名=变量值 例如:var=hello

预定义变量:

         AR : 归档维护程序的名称,默认值为 ar

         CC : C 编译器的名称,默认值为 cc,gcc作用

         CXX : C++ 编译器的名称,默认值为 g++

         $@ : 目标的完整名称

         $< : 第一个依赖文件的名称

         $^ : 所有的依赖文件

获取变量的值:

        $(变量名)

举例:

相对来说是简化了一些,但是Makefile中的还有较多的内容没有简化,就比如说,底下的四条规则,结构具有什么相似的结构吗,,那么如何简化呢?就需要用到模式匹配;

五、模式匹配 

add.o:add.c

        gcc -c add.c

div.o:div.c

        gcc -c div.c

sub.o:sub.c

        gcc -c sub.c

mult.o:mult.c

        gcc -c mult.c

main.o:main.c

        gcc -c main.c

我们利用%进行匹配;%.o:%.c

%: 通配符,匹配一个字符串;

两个%匹配的是同一个字符串;进过匹配符的介入,上述规则就成了下面的指令:

%.o:%.c

        $(CC) -c $< -o $@

运行结果:

六、函数

        在经过模式匹配与变量的介入后,我们发现之前的Makefile文件已经简化了不少,但是我们发现,如果说一个文件中的.c文件或则说.o文件过多的时候,定义变量一个一个定义也是一个十分麻烦的事情,为了对其再次进行简化,在这里我们引入两个函数进行操作。

1、 $(wildcard PATTERN...)

功能:获取指定目录下指定类型的文件列表

参数:PATTERN 指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔

返回:得到的若干个文件的文件列表,文件名之间使用空格间隔

示例:

        $(wildcard *.c ./sub/*.c)

        返回值格式: a.c b.c c.c d.c e.c f.c

例如将上述的函数进行简化;

        当然,上述代码是有问题的,因为我们在第一个规则中,所有的依赖是.o文件,就算获取了.c文件也没有用。

2、$(patsubst <pattern>,<repalcement>,<text>)

功能:查找text中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合 模式,如果匹配的话,则以替换。

pattern可以包括通配符`%`,表示任意长度的字串。如果 中也包含`%`,那么,repalcement中的这个`%`将是pattern中的那个% 所代表的字串。(可以用`\`来转义,以`\%`来表示真实含义的`%`字符)

返回:函数返回被替换过后的字符串

示例: $(patsubst %.c, %.o, x.c bar.c) 返回值格式: x.o bar.o

        在第一个函数中,我们只是对文件中的.c依赖进行了利用函数的获取,但是我们知道,还有第一部分依赖是由底下的规则产生的,这时就需要再用一个函数。

运行结果:

最后再介绍一下清楚,我们在上述代码执行的时候,会在文件夹中产生.o文件,我们可以再Makefile文件中加入删除规则,然后单独调用;

必须直接调用,因为它对于第一条规则没有关系,默认条件使用make下不会被执行,只能专门调用才会被使用。

 总结:本节我们学习了Linux中Makefile文件的相关基础知识以及相关操作的使用,大家学习完后一定要自己动手试试,操作操作!如有问题欢迎评论区交流。

创作不易,还请大家多多点赞支持!!!

  • 12
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
详细易懂的Linux makefile教程 一、概述 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。 在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX下的GCC和CC。 、关于程序的编译和链接 —————————— 在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。 ...

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值