上次随着信号学习告一段落,也标志着linux系统编程相关的知识学完了,而学了这么多知识点,是需要用一个综合的项目来将其进行串起来的,这样学习的技术才会不那么空洞,所以接下来会以一个实际例子来综合运用下所学的知识,该知识点就是涉及到linux系统编程,在开始这个项目之前,还得补充一个知识点,因为会用到它,因为一个项目的源文件往往是由多个.c文件组成的,所以不可能一个个手动去用gcc去编译,所以这个高效工具就产生了-----Make工具

make与Makefile介绍:
 
Makefile基本规则:
简单的Makefile编写:
上面的理论先了解一下,下面会用实例来一步步阐述它的强大之处,首先先创建多个.c文件:
然后在main.c中写一个主方法,由于只是为了演示make工具的使用,所以里面都是空实现,只要能编出可执行文件既可:
这时,在同一级文件夹下,新建一个Makefile文件,这里描述了其生成可执行文件的规则:
那规则如何编写呢?如下:
这时, 我们开始编译:
从这结果可以很直观地感受到make命令的便捷之处,只要编写好Makefile之后,之后不管多少.c文件,编译起来都是比较简单的,和不使用make来编译文件,生成是比较麻烦的,所以,这就是为什么要学习它的原因,在实际项目开发中用它来做源代码编译是非常方便的。
其实从make的输出行中就可以发现,实际上就是按我们的规则去执行了一些编译命令,如下:
如果这时我们再次make会怎样呢?
那如果更改内容再来make呢?
对于编译生成的中间.o文件,如果我们想全部删除该怎么办呢?可能大家都知道可以用rm命令,一个个去删除,但是如果每次编译之后删除都得手动去用rm命令去删是不是非常麻烦呢?所以可以采用make的伪目标,具体用法如下:
这时来看一下效果:
如果我们只想生成某个文件的.o文件呢?可以这样办:
基于这个规则,我们就可以解释为什么我们敲入一个make既可生成一个main执行文件呢?因为make其实上是生成第一个目标,而我们编写的Makefile的第一个目标就是生成可执行文件,所以就生成了main可执行文件了。
对于伪目标,还有一个值得说明的地方,下面来看现象:
这是由于它发现本地已经存在clean文件了,所以就不执行伪目标了,这时我们可以显示指定伪目标:
这时再执行:
从现在我们编写的Makefile文件中,可以发现一些问题,如:
所以,解决这个问题,在Makefile中使用变量则产生了。
Make自动化变量:
下面用实际Makefile文件来说明上面的变量:
 
 
 
下面,我们用上面自动化变量的方式,来改编一下Makefile,达到同样的效果:
思考这种方式用什么好处呢?
1、更加专业【感观上,呵呵】
2、代码量更加精简
3、更加灵活,因为自动化变量不是手动写死的
 
【说明】:
①、一般情况下Makefile文件中文件名首字母都是用大小的,但是用小写的m也未尝不可。
②、如是有多个Makefile存在同级目录下,可以指定用哪一个进行编译,如下:
\
③、可以在make时给出一些自己的提示,如下:
 
 
 
 
Makefile编译多个可执行文件:
如果一个目录下有多个.c文件都要生成多个可执行文件,那该怎么办呢?下面来研究这种情况,有两个.c文件,都有main函数,也就是都得要生成可执行文件:
这作何解释呢?实际上,这里面隐含着一些推导规则:
从Makefile文件中,可以看到all依赖于我们的bin,而all并非真正的目标,而是一个伪目标,实际上可以在Makefile中这样声明:
而要生成all,则需要生成bin,由于我们并没有指定生成all的规则,所以,Make就会生成BIN里面的文件,而我们又并没有给出01test、02test的生成规则,所以编译器将自动推导将同名的.c文件生成同名的可执行文件,所以就生成了01test和02test,当然我们也可以不用系统的这种推导规则,我们自己来写生成规则,具体如下:
如果上面.o的生成,我们不想用系统推导的,改用我们自己的呢?可以用一个比较通用的写法,规则如下:
下面用来实践下:
另外,还可以用一个等价的规则,如下:
至此,通过这个Makefile就可以生成多个可执行文件了,但是,如果我们要做一个更加专业的Makefile,则还需稍加修改下,得加入一些自定义的变量,达到更加的灵活通用:
\
至此,一个很好用的Makefile就诞生了,怎么好用法呢?基于这个我们在新建一个新的.c文件,如果想让其快速生成可执行文件,用这个Makefile实在是太方便了,如下:
这时,想要编译新增的文件,只需要在Makefile简单修改下既可:
这时只要执行make既可:
如果03test.c还依赖于其它的.c文件,也很方便,如:它依赖于pub.c文件,这时在Makefile上修改一下依赖文件既可:
实际上,对于可执行文件的生成,完成可以由系统去推导,这个之前我们有证明过,这里我们将我们写的可执行文件的依赖代码去掉就知道了:
这时执行一下:
根据这个规则,如果之后再加入一个04test.c,而它又没有依赖其它.c,那只要在Makefile中修改一处既可很方便的生成可执行文件了,如下:
好了,今天就学到这,下节见~

Makefile学习一的更多相关文章

  1. [转]Windows平台下Makefile学习笔记

    Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...

  2. makefile 学习归纳

    makefile 学习归纳 一直希望 好好整理下 makefile的写法,这在linux编程界是必备技能.下面就好好的说道说道. 可以参考的大神总结 整理 makefile是供make命令执行的 脚本 ...

  3. <转>Windows平台下Makefile学习笔记(二)

    本文转自:http://blog.csdn.net/clever101/article/details/8286066 上次我们学习了怎么用Makefile编译一个控制台工程.这次我们学习一下如何使用 ...

  4. makefile学习(1)

    GNU Make / Makefile 学习资料 GNU Make学习总结(一) GNU Make学习总结(二) 这篇学习总结,从一个简单的小例子开始,逐步加深,来讲解Makefile的用法. 最后用 ...

  5. (二)我的Makefile学习冲动&&编译过程概述

    前言 一 年轻的冲动 二 学习曲线 1 Makefile基本语法 2 bash基础 3 world 三 编译过程概述 1 主机预装工具 2 编译host工具 3 编译交叉工具链 4 编译内核模块 5 ...

  6. Makefile学习笔记

    ls -l 查看文件详细信息 1.gcc -E test.c -o test.i//预编译gedit test.i //查看:高级C 2.gcc -Wall -S test.i -o test.s// ...

  7. makefile学习笔记(多目录嵌套调用、变量使用)

    http://blog.csdn.net/leexiang_han/article/details/9274229   学习了几天的makefile的嵌套调用编写也有一些心得,先声明,我也是初学者写文 ...

  8. Makefile学习(一)变量

    鉴于之前有一些了解,还有自己的学习习惯,我一上来就看Makefile的变量这一章.主要脉络是根据GNU make中文手册. 第六章:Makefile中的变量 6使用变量 定义:变量是一个名字,代表一个 ...

  9. makefile 学习一

    近期在学习nginx,由于实在linux下,一些代码须要用makefile文件来编译,比較节省时间. 由于在nginx中加入一个新的模块假设用./configure方法来加入,特别是当你的代码有错时, ...

  10. Makefile学习总结

    Makefile用法分析     在linux开发中,应用程序的编译基本都采用GNU的make工具,而make搭配Makefile来实现工程代码的编译,在越是大型复杂的项目中,make的强悍之处越是明 ...

随机推荐

  1. [LeetCode] 224. Basic Calculator 基本计算器

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  2. polynomial&generating function学习笔记

    生成函数 多项式 形如$\sum_{i=0}^{n}a_i x^i$的代数式称为n阶多项式 核函数 {ai}的核函数为f(x),它的生成函数为sigma(ai*f(i)*x^i) 生成函数的加减 {a ...

  3. springboot集成mybatisplus小例子

    集成mybatisplus后,简单的CRUD就不用写了,如果没有特别的sql,就可以不用mapper的xml文件的. 目录 pom.xml文件 <?xml version="1.0&q ...

  4. SecureCRT字体、界面优化

    SecureCRT字体.界面优化 本文是secureCRT的第三篇博文,也是目前secureCRT优化的最终篇.首次使用该软件时候.应该会设置字体和编码,接下来,将演示如何设置. 1. 字体.编码设置 ...

  5. IDEA一个工程如何启动多次

  6. Java基础笔试练习(八)

    1. 以下关于构造函数的描述错误的是 ( ) A.每个类有且只能有一个构造函数. B.构造函数是类的一种特殊函数,它的方法名必须与类名相同 C.构造函数的主要作用是完成对类的对象的初始化工作 D.一般 ...

  7. 解决elementui日期时间选择器提交时与后台date类型不匹配问题

    问题描述: 在前端使用elementui的日期时间选择器后,在通过axios进行提交的时候,前端控制台出现了400(数据类型不匹配的错误)的错误. <el-form-item label=&qu ...

  8. 数组中重复的数字(Golang)

    使用哈希表 package main import "fmt" func main() { a := [...]int{2,3,1,0,2,5,3} num := make(map ...

  9. 1. Spark SQL概述

    1.1 什么是Spark SQL Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用 它是将Hive SQL转换成 ...

  10. Codeforces Round #568 Div. 2

    没有找到这场div3被改成div2的理由. A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long ...