Makefile文件:Makefile介绍
本文介绍Makefile的一些基本概念以及简单的用法。本文所用的编译器是Hightec tricore v4.9.1.0。
文章目录
- 1 Makefile的作用
- 2 Makefile的规则
- 3 一个简单的Makefile
- 3.1 帮助文档中的例子
- 3.2 例1:一个简单的Makefile
- 4 make是如何执行Makefile的
- 4.1 默认目标
- 4.2 例2:使用默认目标
- 5 使用变量让Makefile更简洁
- 5.1 变量的简单用法
- 5.2 例3:在Makefile中使用变量
- 6 通过make推导规则
- 6.1 隐式规则
- 6.2 例4:省略源文件
- 7 另一种风格的Makefile
- 8 清空路径的规则
- 9 总结
1 Makefile的作用
简单来说,Makefile的作用是告诉make如何编译和链接程序。我们在Eclipse界面中写好代码后,会点击一下rebuild按钮来将工程重新编译和链接,这背后就是通过Makefile来实现的。本文会结合编译器的帮助文档make.pdf,并且自己编写Makefile,来学习Makefile的基本概念和用法。
2 Makefile的规则
Makefile的规则如下所示:
其中的含义如下:
- target是生成的文件的名称,可以是编译器生成的目标文件,或者链接器生成的可执行文件。另外也可以是执行的动作,例如clean;
- prerequisite是用于生成文件的输入,例如生成目标文件的输入是C文件和头文件,生成可执行文件的输入是目标文件;
- recipe是需要执行的动作,可以理解成命令。recipe前面要加上一个Tab制表符。
知道了以上规则,就可以写一个简单的Makefile了。
3 一个简单的Makefile
3.1 帮助文档中的例子
Hightec的帮助文档中举了个例子来演示Makefile,如下图所示。
该Makefile主要做了一下几件事:
- 将8个源文件编译成目标文件;
- 将8个目标文件链接成一个可执行文件edit;
- 用clean清除掉目标文件和可执行文件。
3.2 例1:一个简单的Makefile
帮助文档中只是个演示,并没有附带源文件供我们练习。因此博主自己写了简单的源文件头文件和Makefile,研究Makefile的执行过程和结果。另外,由于链接过程需要编写复杂的链接脚本,所以在下面的例子中只尝试编译的过程。
1)首先在同一个路径下建立三个文件:hello.c,hello.h,Makefile。
2)在hello.c中写入简单的变量和函数定义,如下所示。
/* hello.c */
#include "hello.h"int a = 10;int main(void)
{return 0;
}
在hello.h中写入对应的变量和函数声明,如下所示。
/* hello.h */
extern int a;
extern int main(void);
根据上文提到的规则,在Makefile中尝试写入编译hello.c的命令语句,如下所示。
hello.o : hello.c hello.htricore-gcc -c hello.cclean : rm hello.o
Makefile中包含了两个功能:调用tricore-gcc把hello.c编译成hello.o,以及移除hello.o。
3)打开命令提示符,切换到这三个文件所在的路径。然后输入make并回车,如下图所示。
命令窗口会显示tricore-gcc -c hello.c这一行命令语句。然后回到文件夹路径下,看到成功生成了hello.o文件。
4)在窗口中输入make clean并回车,就会执行Makefile中的clean命令,如下图所示。
命令窗口会显示rm hello.o这一行命令语句。然后回到文件夹路径下,之前的hello.o文件就被移除了。clean的功能在软件编译的过程中很常用。在这里,clean不是一个目标文件,而是一个动作。clean的冒号后面没有跟其他的文件,因而被称为伪目标。
5)当路径下已经有了hello.o文件的时候,再去执行make命令会发生什么呢?尝试执行两次make命令,如下图所示。
第二次执行make命令的时候,编译器返回了"make: ‘hello.o’ is up to date"这句话,表示hello.o文件已经是最新的了。这里就要提到一个Makefile的机制,就是如果target文件(冒号前的文件)的时间晚于prerequisite文件(冒号后的文件)的时间,就表示输入文件没有被更新过,所以不会进行重新编译。
4 make是如何执行Makefile的
4.1 默认目标
默认情况下,make从第一个target开始,这个target被称为默认目标。
例如在3.1中所述的帮助文档中的例子。当我们敲下了make指令的时候,会从第一条规则开始,也就是重链接出edit文件。但是在链接之前,make必须首先处理edit文件所依赖的输入文件,也就是.o文件。所以make会先编译所有需要重新编译的源文件,直到.o文件齐全。这有点像是一个金字塔结构,底层的target完成以后才能做顶层的target。
clean伪目标是个例外,因为它不是edit所依赖的输入,需要使用make clean指令来处理clean。
4.2 例2:使用默认目标
把例1中的Makefile进行修改,在编译hello.c之前做一个默认目标project.elf,依赖于输入文件hello.o文件,如下。
project.elf : hello.otricore-gcc -o project.elf hello.ohello.o : hello.c hello.htricore-gcc -c hello.cclean : rm project.elf hello.o
首先运行make clean,将当前路径的hello.o清除掉,只剩下hello.c,hello.h,Makefile三个文件。
然后,运行make。
在路径下就会生成project.elf和hello.o两个文件。
这个Makefile中就是以开头的project.elf作为默认目标。make先检测到默认目标所依赖的hello.o在当前路径中不存在,所以先去以hello.o为目标进行编译。编译完成后再以project.elf为目标去链接。
注意,这里的链接elf文件只是做一个演示,是为了说明默认目标的概念。实际上,链接过程非常复杂,不要被这个例子中的只言片语所误导。
5 使用变量让Makefile更简洁
5.1 变量的简单用法
在3.1帮助文档中的例子中,edit所依赖的.o文件有很多。如果Makefile中重复出现大量相同的字段,会很容易写错。这时就可以用一个变量来指代这一系列.o文件,如下图所示。
然后,在后文用到这一系列.o文件的地方,就可以用$(objects)来替换,如下图所示。
5.2 例3:在Makefile中使用变量
把例1中的Makefile进行修改,将hello.c和hello.h赋值给变量inputfile,然后再后面用到的地方换成$(inputfile),如下。
inputfile = hello.c hello.hhello.o : $(inputfile)tricore-gcc -c hello.cclean : rm hello.o
然后打开命令行运行make,效果和例1相同,都能生成hello.o文件。
6 通过make推导规则
6.1 隐式规则
在Makefile文件中可以不用把编译的所有规则写出来,因为make中有个概念叫隐式规则,可以自动推导依赖关系。例如,在make看到了一个.o文件的时候,会自动推导它的源文件是同名的.c文件,就不需要把.c文件也写进去了。所以3.1 帮助文档中的例子也可以写成下面这样。
main.o文件后面就不再写上输入文件main.c了,下面的cc规则也省略了。
6.2 例4:省略源文件
将例1中的Makefile修改,冒号后面的输入文件不带hello.c了,只带一个hello.h,如下。
hello.o : hello.htricore-gcc -c hello.cclean : rm project.elf hello.o
然后打开命令行,用make执行,效果和例1相同。
7 另一种风格的Makefile
由于有了Makefile的隐式规则,就可以不用把源文件清楚地写出来了。因此,诞生了另一种风格的Makefile,如下。
在编译规则中,冒号左边的目标是很多个.o文件,右边是头文件。这样的Makefile也是可以正确地执行的,但是依赖关系非常复杂,写的时候很容易出错。
8 清空路径的规则
上面的例子也说到,可以用make clean来清空路径下的文件。实际应用中最好按照以下方式来写clean。
这里包含了两个要素。首先,.PHONE表示clean是个伪目标,这样就不会把clean和名为clean的文件搞混淆。其次,在rm前面添加一个减号,表示即使rm出现错误也可以使make继续。
注意,诸如clean这样的规则不应放在makefile的开头,因为我们不希望它成为默认目标。
9 总结
本文学习了Makefile的基本概念,并且通过一些实例的操作,熟悉了Makefile的基本用法。
>>返回个人博客总目录
Makefile文件:Makefile介绍相关推荐
- makefile文件简要介绍
到此为止,读者已经了解了如何在Linux下使用编辑器编写代码,如何使用Gcc把代码编译成可执行文件,还学习了如何使用Gdb来调试程序,那么,所有的工作看似已经完成了,为什么还需要Make这个工程管理器 ...
- Makefile 文件详细介绍
Makefile 文件 Linux下: gcc 编译的时候 不会 检查 文件是否被修改过 直接 所有源文件 重新编译(会造成 大量的重复 编译) make: 编译的时候 会 检查 文件是否被修改过 只 ...
- CUDA和LAPACK混编的MakeFile文件
最近在写CUDA和LAPACK混编的程序,贴出Makefile文件和源程序文件,供大家参考. Makefile文件 # Makefile for GPU program based on SU# Ho ...
- 很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序...
很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用m ...
- makefile文件编写教程
技术交流QQ群:1027579432,欢迎你的加入! 1.make介绍 gcc:编译器(gcc根据菜谱进行编译) make: linux自带的构建器(相当于一个菜谱) 构建的规则(菜谱)在makefi ...
- Makefile文件的编写规则
欢迎大家关注笔者,你的关注是我持续更博的最大动力 Makefile文件编写规则 文章目录: 1 makefile文件介绍 2 makefile文件编写 1 makefile文件介绍 makefile是 ...
- Linux编程——入门级Makefile文件编写
前言 1.在Linux开发环境中,编写Makefile文件是一个必须的技能,虽然现在有好多IDE可以自动生成所需要的Makefile文件,但有时能看懂Makefile文件也是更好的了解项目的编译过程. ...
- C语言makefile文件
文章目录 一.makefile的编写 二.make命令 三.makefile文件中的变量 四.应用经验 五.课后作业 六.版权声明 在软件的工程中的源文件是很多的,其按照类型.功能.模块分别放在若干个 ...
- 【Linux】Makefile文件
Makefile文件 1. Makefile定义 一个工程中的源文件不计其数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译 ...
最新文章
- 在 Kubuntu 21.04 中安装和升级 KDE Plasma 5.2
- 手机自动化测试:Appium源码分析之跟踪代码分析四 1
- 【Vegas原创】outlook发送时,报550 5.7.1 client does not have permissions to send as this sender解决方法...
- java lwjgl3_java-LWJGL 3鼠标移动
- GraphSAGE 模型解读与tensorflow2.0代码实现
- mysql 重启_windows下重启mysql的方法
- 7月31日云栖精选夜读 | 在浏览器上也能训练神经网络?TensorFlow.js带你玩游戏~...
- TikTok是下一个流量蓝海吗?用户规模超抖音?
- 计算机等级考试四级--软件工程
- 数据结构(C语言版清华严蔚敏)
- 直销模式系统开发|双轨制度跟级差制度哪个模式比较好?
- android-倒计时工具类
- 安装服务器系统提示加载驱动程序,启动sqlserver服务时,总是出现“系统错误(126),指定驱动程序无法加载,...
- B帧对视频清晰度/码率的影响
- 将一个数组分成2个数组,使得2个数组的差值最小
- 美国邓白氏集团与邓氏编码
- java-net-php-python-4java个人博客系统计算机毕业设计程序
- 【物联网中间件平台-05】YFIOs策略开发指南
- html 案例 --- 网页简历 、简历信息填写
- AD入门学习—元件库的创建2
热门文章
- PhpMyadmin利用源代码及root账号泄露漏洞秒获系统权限
- 阿里云 mysql emoji_如何在 MySQL 中存储 emoji ?
- linux 查询文件大小大于1g_常用Linux命令
- 从新建文件夹开始构建ShadowPlay Engine游戏引擎(6)
- 小米Air笔记本以UEFI模式硬盘GPT分区启动Win7_64位系统
- Win10我的电脑图标怎么调出来?1分钟解决!
- 乐鑫esp32-c2开发演示
- 【信息】宁波银行金融科技部:常见问题解答
- 3-2加法器、4-2压缩器、5-2压缩器
- cannot create temp file for here-document: No space left on device