一、makefile简介

定义:makefile定义了软件开发过程中,项目工程编译链、接接的方法和规则。

产生:由IDE自动生成或者开发者手动书写。

作用:Unix(MAC OS、Solars)和Linux(Red
Hat、Ubuntu)系统下由make命令调用当前目录下的makefile文件执行,可实现项目工程的自动化编译。

二、语法规则

target:prerequisites

command

其中,target为需要生成的目标,prerequisites为依赖项,command为make需要执行的命令(任意的Shell命令)。

注意:其中command前必须以tab键开始。

三、makefile内容

Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

1.显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

2.隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。

3.变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。

4.文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,请参考文末的参考资料。

5.注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“\#”。

四、make的工作流程

在默认的方式下,也就是我们只输入make命令,则相当于make first_objname_in_makefile。意思是生成出现在makefile中第一个目标文件。或者指明生成的目标名称,如make [objname]。

按默认方式,输入make命令,其工作方式是:

1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2.如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,并把这个文件作为最终的目标文件。

3.如果target不存在,则根据target后的依赖项和command生成target。如果target已存在,则make检测target依赖项是否有修改,若修改,则跟新target。

四、实例讲解

鄙人将以实际工作项目的makefile为例为大家讲解makefile的创建过程。Makefile内容如下:

CCFILES += $(wildcard src/*.cpp)

SRCDIR := ./src/

VPATH = src:./include:./src/xmlparser:./lib

# Compilers

#CC        := /opt/intel/composer_xe_2013.0.079/bin/intel64/icpc

CC := icpc

# Compilers para

FLAGS := -openmp -openmp-report -vec-report-O2

OBJECT :=file_interface.o tinyxml2.omic_decomposer.o Charset.o network.o buffer.o \ task_queue.o common.o main.omic_function.o hashtree.o nodeconfig.o md5_mic.o ntlm_mic.o

ALG.out : $(OBJECT)

$(CC)$(FLAGS) -o ALG.out $(OBJECT) ./lib/libxmlextern.a

file_interface.o :global.h tinyxml2.hfile_interface.h $(SRCDIR)file_interface.cpp

$(CC)$(FLAGS) -c $(SRCDIR)file_interface.cpp

tinyxml2.o :tinyxml2.h$(SRCDIR)tinyxml2.cpp

$(CC)$(FLAGS) -c $(SRCDIR)tinyxml2.cpp

mic_decomposer.o :$(SRCDIR)mic_decomposer.cppmic_decomposer.h mic_define.h cnre.h \ common.h hashtree.h

$(CC)$(FLAGS) -c $(SRCDIR)mic_decomposer.cpp

Charset.o :Charset.h cnre.h$(SRCDIR)Charset.cpp

$(CC)$(FLAGS) -c $(SRCDIR)Charset.cpp

network.o :network.h task_queue.hnetwork_packet.h nodeconfig.h $(SRCDIR)network.cpp

$(CC)$(FLAGS) -c $(SRCDIR)network.cpp

buffer.o :network.h task_queue.hnetwork_packet.h nodeconfig.h buffer.h $(SRCDIR)buffer.cpp

$(CC)$(FLAGS) -c $(SRCDIR)buffer.cpp

task_queue.o :task_queue.h$(SRCDIR)task_queue.cpp

$(CC)$(FLAGS) -c $(SRCDIR)task_queue.cpp

common.o :common.h mic_define.hmic_function.h $(SRCDIR)common.cpp

$(CC)$(FLAGS) -c $(SRCDIR)common.cpp

main.o :task_queue.h global.h network.hnetwork_packet.h common.h nodeconfig.h \ mic_define.h mic_function.hfile_interface.h $(SRCDIR)main.cpp

$(CC)$(FLAGS) -c $(SRCDIR)main.cpp

mic_function.o :mic_function.h$(SRCDIR)mic_function.cpp

$(CC)$(FLAGS) -c $(SRCDIR)mic_function.cpp

hashtree.o :hashtree.h$(SRCDIR)hashtree.cpp

$(CC)$(FLAGS) -c $(SRCDIR)hashtree.cpp

nodeconfig.o :nodeconfig.h./src/xmlparser/tinyxml.h $(SRCDIR)nodeconfig.cpp

$(CC)$(FLAGS) -c $(SRCDIR)nodeconfig.cpp

md5_mic.o :simd.h mic_define.h common.hshare_macro.h md5_macro.h md5_mic.h \ file_interface.h $(SRCDIR)md5_mic.cpp

$(CC)$(FLAGS) -c $(SRCDIR)md5_mic.cpp

ntlm_mic.o :simd.h mic_define.h common.hshare_macro.h ntlm_macro.h ntlm_mic.h

$(CC)$(FLAGS) -c $(SRCDIR)sha256_mic.cpp

.PHONY clean:

rm-f *.o *.out

具体讲解:

1.      CCFILES += $(wildcardsrc/*.cpp)

利用wildcard函数获取src目录下所有.cpp文件,并赋值给自定义变量CCFILES。其中#号是makefile的注释符号。

2.      SRCDIR:= ./src/

用于指明.cpp源文件所在目录。SRCDIR变量在command中出现时,以类似于宏替换的方式将其载入command中。

3.      VPATH= src:./include:./src/xmlparser:./lib

指明makefile寻找依赖项时,若当前目录不存在,则去VPATH指明的目录去寻找。各目录以“:”号隔开。

4.      CC := icpc,自定义变量CC指明为icpc,表示使用Intelc++ Compiler编译项目。

5.      FLAGS := -openmp -openmp-report-vec-report -O2,指明编译选项。

6.      OBJECT :=file_interface.otinyxml2.o mic_decomposer.o Charset.o network.o buffer.o \

task_queue.o common.o main.o mic_function.o hashtree.onodeconfig.o md5_mic.o ntlm_mic.o指明目标文件;其中反斜杠\表示一行还未结束。

7.      ALG.out : $(OBJECT)

$(CC) $(FLAGS) -o ALG.out$(OBJECT) ./lib/libxmlextern.a

此处表示makefile需要生成的第一个目标文件,也是不指明目标文件的make命令默认生成的目标文件。加入icpc的编译选项,并指明目标ALG.out依赖的目标文件和静态链接库项./lib/libxmlextern.a后,进行链接生成可执行文件ALG.out。

8.      file_interface.o :global.htinyxml2.h file_interface.h $(SRCDIR)file_interface.cpp

$(CC) $(FLAGS) -c$(SRCDIR)file_interface.cpp

指明file_interface.o的依赖项并编译成二进制文件file_interface.o。后面的每个目标文件皆是如此做法。

9.      .PHONY clean:

rm -f *.o *.out

使用.PHONY关键字,指明clean是伪目标,仅作标签使用。此处不依赖与任何项,使用方法是显示调用make clean,用于执行rm操作。但也可以添加依赖项,如:

all : prog1 prog2 prog3

.PHONY : all

则all依赖于ALG.out,那么使用 makeall则可以生成三个目标文件prog1、prog2和prog3。若将all放在所有目标文件的前面,则使用make即可,无需指明make all,原因是make命令将makefile中第一个出现的目标作为最终目标,若不放在最前面,则必须指明make all。

注意事项:

1.      makefile赋值符号= := +=?=的区别

= 是最基本的赋值,以makefile中最后赋值为准;

:= 是覆盖之前的值,以当前赋值为准;

?= 是如果没有被赋值过就赋予等号后面的值;

+= 是添加等号后面的值,即拼接等号后面的值。

其中=和:=的区别见如下代码:

(1)“=”

make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:

x = foo

y = $(x) bar

x = xyz

在上例中,y的值将会是 xyz bar,而不是 foo bar 。

(2)“:=”

“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

x := foo

y := $(x) bar

x := xyz

在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。

2.makefile中目标文件一定要把依赖的头文件包含进去吗?

不一定,可以不包含进去。makefile是根据依赖项是否被修改决定是否重新执行command。如果不把头文件写入依赖项中,则面临的风险就是修改了头文件,目标文件不会被重新编译。我们的原则是,自己定义的头文件写入依赖项,库的头文件无需包含,除非你要修改库的头文件。

3.VPATH环境变量只能用来makefile寻找目标文件的依赖项,不能帮助编译器寻找所需编译的文件。

参考资料:

[1] http://blog.csdn.net/ruglcc/article/details/7814546/

[2] makefile百度百科

版权声明:本文为博主原创文章,未经博主允许不得转载。

makefile基础实例讲解 分类: C/C++ 2015-03-16 10:11 66人阅读 评论(0) 收藏的更多相关文章

  1. 改变HTML中超链接的显示样式 分类: C1_HTML/JS/JQUERY 2014-08-27 10:11 595人阅读 评论(0) 收藏

    更详细的内容请参考:http://www.w3school.com.cn/tags/tag_a.asp HTML中的代码如下: <a class="news_title" t ...

  2. OC基础知识总结 分类: ios学习 OC 2015-06-26 17:58 58人阅读 评论(0) 收藏

    //OC: Objective-C, 面向对象的C语言 //OC与C的区别 //1.OC是C的超集, C语言的所有语法都可以在OC中使用 //2.OC是面向对象 //3.OC是一门运行时语言 //4. ...

  3. UI基础:UILabel.UIFont 分类: iOS学习-UI 2015-07-01 19:38 107人阅读 评论(0) 收藏

    UILabel:标签 继承自UIView ,在UIView基础上扩充了显示文本的功能.(文本框) UILabel的使用步骤 1.创建控件 UILabel *aLabel=[[UILabel alloc ...

  4. OC基础:NSString NSNumber 分类: ios学习 OC 2015-06-17 17:55 77人阅读 评论(0) 收藏

    OC中的基本数据类型 NSString  在64位系统下,相当于long,在非64位系统下,想当于int. CGFloat   在64位系统下,相当于double,在非64位系统之下,想当与float ...

  5. UI基础:UIButton.UIimage 分类: iOS学习-UI 2015-07-01 21:39 85人阅读 评论(0) 收藏

    UIButton是ios中用来响应用户点击事件的控件.继承自UIControl 1.创建控件 UIButton *button=[UIButton buttonWithType:UIButtonTyp ...

  6. JavaScript、Ajax与jQuery的关系 分类: C1_HTML/JS/JQUERY 2014-07-31 10:15 3388人阅读 评论(0) 收藏

    简单总结: 1.JS是一门前端语言. 2.Ajax是一门技术,它提供了异步更新的机制,使用客户端与服务器间交换数据而非整个页面文档,实现页面的局部更新. 3.jQuery是一个框架,它对JS进行了封装 ...

  7. 全面解析sizeof(下) 分类: C/C++ StudyNotes 2015-06-15 10:45 263人阅读 评论(0) 收藏

    以下代码使用平台是Windows7 64bits+VS2012. sizeof作用于基本数据类型,在特定的平台和特定的编译中,结果是确定的,如果使用sizeof计算构造类型:结构体.联合体和类的大小时 ...

  8. 全面解析sizeof(上) 分类: C/C++ StudyNotes 2015-06-15 10:18 188人阅读 评论(0) 收藏

    以下代码使用平台是Windows7 64bits+VS2012. sizeof是C/C++中的一个操作符(operator),其作用就是返回一个对象或者类型所占的内存字节数,使用频繁,有必须对齐有个全 ...

  9. MS SQL 合并结果集并求和 分类: SQL Server 数据库 2015-02-13 10:59 92人阅读 评论(0) 收藏

    业务情景:有这样一张表:其中Id列为表主键,Name为用户名,State为记录的状态值,Note为状态的说明,方便阅读. 需求描述:需要查询出这样的结果:某个人某种状态的记录数,如:张三,待审核记录数 ...

随机推荐

  1. JDBC Thin Driver 的formats三种格式

    格式一:  Oracle JDBC Thin using a ServiceName: jdbc:oracle:thin:@//<host>:<port>/<servic ...

  2. 分享Windows Server 2012 R2的获取正版密钥方法

    然后使用“我有ISIC卡”验证,目前可用号码:S420546009858. 分享Windows Server 2012 R2的获取正版密钥方法. 首先登陆dreamspark注册一个账号https:/ ...

  3. (转)UIApplication sharedApplication详细解释-IOS

    iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...

  4. Ajax的post方法,模拟 从后台读取数据小demo

    $(document).ready(function() { //定义一个函数 function timer() { $.post("1.json", function(data, ...

  5. iOS LaunchScreen启动图设置

    新建的iOS 项目启动画面默认为LaunchScreen.xib 如果想实现一张图片作为启动页,如下图 如果启动不行  记得clear 一下工程 是启动页停留一段时间  只需要在 AppDelegat ...

  6. (Your)((Term)((Project)))

    Description You have typed the report of your term project in your personal computer. There are seve ...

  7. 简单的多线程(活用OD解决运行时错误)

    代码源自<VC++深入详解>第15章 “多线程”,位于第563页 - 566 页. 程序的目的是展示多线程运行的效果: #include <windows.h> #includ ...

  8. GIT之二 基础篇(2)

    远程仓库的使用 要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库.远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某个项目时,需要管 ...

  9. Android 学习第1课,JDK工具包的安装

    1. jdk 的下载 目前为止,jdk的最新版是jdk8,http://www.oracle.com/technetwork/java/javase/downloads/index.html 到这里下 ...

  10. 基于 OpenSSL 的 CA 建立及证书签发 【转】

    建立 CA 建立 CA 目录结构 按照 OpenSSL 的默认配置建立 CA ,需要在文件系统中建立相应的目录结构.相关的配置内容一般位于 /usr/ssl/openssl.cnf 内,详情可参见 c ...