使用makefile
最近在学习一个处理二维相场问题的c++程序,遇到了makefile文件,之前没有接触过,这里做一个简单的整理。
什么是makefile?
大多程序员使用的windows操作系统,IED都完成了makefile的工作,所以对于makefile了解不多,而linux下使用的全是命令行,要完成一个工程化项目,就不得不使用到makefile了。
我们知道一个程序中包括各种不同的源文件,根据不同用途,放在不同的目录下,而makefile文件就可以决定哪个文件先编译、哪个文件后编译、哪个文件重新编译,这样,我们就可以通过makefile按照顺序执行。 一般来说,大多数IDE都有这个命令,比如Delphi的make,Visual C++的nmake,Linux下GUN的make。
简单的说: makefile是告诉系统如何编译和链接程序。
为什么需要makefile?
因为通过makefile我们可以方便地执行一个工程型文件,即使项目工程化,即通过makefile自动编译工程文件,而不需要我们在命令行中一个一个命令的敲。对于C++程序,和JavaScript是不同的,因为JavaScript是解释型语言,而C++是编译型语言,所以,需要先编译成可执行文件,接着才可执行。那么,具体的编译过程是怎样的呢?
程序的编译和链接是怎样的?
一般来说c和c++语言过程如下:
首先都是要先把源文件编译成中间代码文件,在windows下表现为.obj文件,unix下是.o文件,即object file,这个动作叫做编译(compile);
然后再把所有的object file合成可执行文件,这个动作叫做链接(link)。
编译须知:在编译c、c++程序时,编译器需要的是(1)语法正确变量和(2)函数声明的正确。 对于后者,通常是你要告诉编译器头文件的位置,显然,头文件都是声明而已,而其中的定义是在c、c++文件中的,这时只要所有的语法正确,编译器就可以编译出中间目标文件(object file)了。一般来说,每一个源文件都会对应于一个中间文件。
链接须知:链接时,主要是链接函数和全局变量。所以,我们可以使用中间目标文件来链接我们的程序。在连接的过程中,我们并不管函数所在的源文件,只管函数的目标文件,在大多数时候,由于中间目标文件太多,所以会比较繁琐,这时一般就会将多个中间目标文件打包在一起, 在windows下即为库文件(library file),也就是.lib文件;在unix下,是archive文件,即.a文件。
于是,我们可以总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),不能生成最终的文件,在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File。
makefile的规则是怎样的?
<target> : <prerequisites>
[tab] <commands>
如上所示,这就是makefile最基本的规则了。
target即为目标,可以是一个目标文件(object file), 也可以是一个标签(label)。
prerequisites是前置条件,是要生成target所需要的文件或目标,所以称之为前置条件。
tab说明这里需要一个空格。
commands即为需要执行的命令。
ok! 这就是makefile的基本规则了,即生成target需要一个或多个prerequisites的情况下执行commands命令。
makefile实例讲解
a.txt: b.txt c.txt
cat b.txt c.txt > a.txt
这个例子就是说: 希望生成a.txt需要b.txt和c.txt为前置条件。 那么怎么生成呢,就是将b.txt和c.txt合并起来,即cat命令。
更多阅读 && 参考文章
最新文章
- 关于Extjs MVC模式上传文件的简单方式
- How to Call SharePoint 2013 API Service to Query The Lists
- 如何在Ubuntu下安装”.deb“、”.bin“、”.tar.gz“、”.tar.bz2“格式的软件包!
- Struts2笔记——struts.xml配置详解
- int型长度
- Come and join us at English corner
- mysql的分区技术
- 【转】【Android】HAL分析
- 关闭显卡快捷键 CTRL+ALT+方向键
- JavaScript 反柯里化
- Android网络服务发现(NSD)协议的使用
- 多线程学习之三生产者消费者模式Guarded Suspension
- Python学习笔记——基础篇【第七周】———类的静态方法 类方法及属性
- 05浏览器-02-操作DOM
- UIDatePicker在swift中的使用
- 运行PHP后台项目:xampp下载,安装,配置,运行PHP的web项目
- django中url路由配置及渲染方式
- 解决微信浏览器无法使用window.location.reload刷新页面
- [NOI2002] 贪吃的九头龙
- LeetCode #001# Two Sum(js描述)
热门文章
- warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY
- IntellJ IDEA 2017 激活编译器配置,读取多个配置文件
- hadoop Hive 的建表 和导入导出及索引视图
- Struts2-result
- Linux常用备份恢复工具
- android上的i-jetty (1)环境搭建
- cpu、内存、raid初识
- 第二天:Javascript事件
- 用fastreport在进行多列打印时,默认是先行后列,如何改成先列后行排记录?
- Asp .Net core 2 学习笔记(3) —— 静态文件