Makefile的使用

MAKE 的使用

     当编译单个文件时,使用GCC已经绰绰有余,但对于有几十个甚至上百个源文件的大工程来讲,单纯用GCC命令进行编译肯定就不行了,那样编译一次太麻烦,这就要求有一种自动化的方法,于是在Linux系统中Make工具就诞生了。

1、 什么是Make makefile  shell

      什么是Make,可以将Make理解为一种脚本,这种脚本主要是用于多文件编译,在传统的命令行式编译方式中,如果修改了工程中的某一个头文件,有时候不需要重新编译整个工程,而只需要编译与这个头文件相关联的源文件即可,但如何以手动的方式从一个大工程里将这些文件找出,并手动编译,是件很麻烦的事情。

       为了解决这一问题,设计了Make,make程序可以维护具有相互依赖性的源文件,当某些文件发生改变时,它能自动识别出,并只对相应文件进行自动编译。

        虽然make工具有很多智能识别机制,但它无法自动了解他所面对的工程源文件的组成以及依赖规则,这些都需要开发人员编写makefile脚本,告诉make工具。MakeFile编写好以后,就可以在每次修改源文件之后,执行make命令就好了。Makefile make

        什么又是makefile了,很多windows的程序开发人员都不知道这个东西,因为那些Windows的IDE都为你做了这些工作,但我觉得要作为一个好的和专业的程序员,makefile还是要懂得,这就好像在有这么多的HTML的编辑器,但如果你想成为一个专业人士,就必须了解HTML的标识的含义。特别在Linux下的软件编译,你就必须自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成某个大型大工程的能力。

2、 makefile的组成

一个完整的makefile文件通常由五个部分组成:

◆显示规则

      显示规则是指主动编写描述规则,用于指示在何种状态下更新哪些目标文件,即编写makefile时需要明确指出各目标文件所依赖的源文件的集合,以及编译本目标文件所需的命令。

◆隐含规则

      指用make中默认的编译方式进行编译,即make工具可以根据目标文件的类型自动推导出的规则(由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略书写Makefile ,这是由make所支持的)

  abc.o abc.c cc -o abc.o -c abc.c

◆变量定义

      为提升语句的灵活性,在make脚本中可以使用变量,来代表一个字符串,一组编译命令或一组文件名。(在makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点类似于C语言中的宏,当makefile 被执行时,其中的变量都会被扩展到相应的引用位置上)

◆makefile指示符

      指示符告诉make工具,当程序在读取makefile文件时要执行的动作。

(文件指示包括三部分,一个是在一个makefile中引用另外一个makefile,就像C语言中的include一样,另一个是指根据某些情况制定MakeFile中的有效部分,就像C语言中的预编译#if一样,还有就是定义一个多行的命令,)

◆ 注释

      Makefile中将#作为注释标识符

     【注】如果此行的第一个非空字符为#,则此行为注释

           如果此行的结尾存在一个反斜杠(\),则下一行也被视为注释行

           如果在代码中需要使用字符#,就要使用转义字符\#来表示此字符并非一个注释符

 

 

3、 makefile的基本语法

makefile主要由规则组成,即编写makefile要遵循一定的规则,在makefile中规则是用于描述在何种状态下,用何种命令创建何种文件。

一条makefile的规则原型:

Target … : dependency…

<Tab>Command





◆ Target代表目标文件,既可以是一个目标代码文件,也可以是一个可执行文件,还可以是一个伪目标

◆ Dependency代表生成上述目标文件所需要的文件(即依赖文件)

◆ Command代表响应命令,即由依赖文件生成目标文件所需要的命令

【注意】规则中的命令必须以Tab键开头,make 工具会将所有以Tab键开头的行当

成命令交给shell 执行。

为方便阅读,对于一个较长的命令行可以书写到多行上,注意行与行之间要

用“\”链接。

      在makefile中,规则主要包括两部分,一是依赖关系,一是生成目标的方法。

      其中规则的顺序很重要,因为,makefile中只应该有一个最终目标,其他的目标都是

被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么,一般来

说,定义在Makefile中的目标可能会很多,但是第一条规则中的目标将被确立为最

终的目标,如果第一条规则中目标有多个,那么,第一个目标将会成为最终目标,

make所要完成的也就是这个目标。

4、 Makefile变量

相比于C语言,Makefile中的变量更像C语言中的宏定义。在引用变量的地方,变量会被其定义的数据所代替。

1、 变量的定义

◆ 递归展开式变量

递归展开式变量是通过“=”或“define”定义的,它的展开是在引用时严格的字符串或数字的替换。

#var1="first var1 define"

#var2:=$(var1) "var2 define"

#var1="second var1 define"

#clean:

#    @echo $(var1)

#    @echo $(var2)

 

#define var1

#first

#endef

#define var2

#$(var1) "var2 define"

#endef

#define var1

#second

#endef

#clean:

#    @echo $(var1)

#    @echo $(var2)

 

#var1=$(var2)

#var2=$(var3)

#var3=bss

#clean:

#    @echo $(var1)

◆ 直接展开式变量

在变量的定义时就完成对其引用变量的展开,就确定了引用变量的值,这个值不会随着其他变量的变化而变化。

2、 变量的引用

定义了一个变量之后,就可以在很多地方使用它,变量的引用方式是:

$(VAR_NAME)或者${VAR_NAME}

对于一些简单变量的引用,也可以不用括号进行变量名德标记就可以直接使用,但此类型的引用方式只是用于变量名为单个字符的情况,当变量名为多个字符而不加括号时,实际引用的是以变量名第一个字符为变量名德变量,为了不造成混乱,建议所有的变量引用都加上括号。

五、Make的执行

          1、make的执行原理

              针对于makefile的原型表达式中,target这一个或多个的目标文件依赖于Dependency中的文件,其生成规则定义在Command中,说白一点就是,dependency中如果有一个以上的文件比target文件要新的话,Command所定义的命令就会被执行,这是makefile的规则,也是makefile中最核心的内容。

2、 指定makefile文件

默认情况下,make会在当前的工作目录下搜索MakeFile文件,并读取、执行MakeFile文件,查找顺序为:makefile、MakeFile。如果当前工作目录下没有找到上述两个文件中的任何一个,Make将不读取任何文件,而可以通过命令行指定一个目标,如果当前工作目录下存在符合此目标的依赖文件,则采用默认的命令创建或更新目标文件。

Make –f Filename   Or   make –file FileName

3、 使用make进行编译测试

Make在执行MakeFile时,如果出现命令执行错误,就会立即停止执行,也就是说错误发生之后的命令将不会被执行。

Make –k      Or    make –keep-going

 六、伪目标

           伪目标并不代表一个真正的文件名,在执行make时,可以通过指定一个伪目标来执行其所在规则中定义的命令。

           有时候也将伪目标称为标签,经常会定义一个伪目标clean,用于清理工程编译的文件:

            Clean:

                      Rm *.o myapp

           规则中rm是shell中的删除命令,用于删除当前目录下所有的.o文件和可执行文件myapp,当进行重新编译时,通常会输入make clean调用命令 rm *.o myapp
来删除旧的文件。

【注意】在定义一个为目标时,如果当前的目录下存在clean文件,则输入 make clean 时,由于伪目标规则中没有依赖文件,而且clean文件总是最新的,因此按照MakeFile文件的运行规则,rm *.o myapp是不会被执行的,这显然是有问题的,为了解决这种问题,要用到.PHONY,使用这个字符串可以显示指定clean为伪目标,而不将其视为文件。

.PHONY 的格式为:

.PHONY :clean

这样,clean就被定义为一个伪目标,不管当前目录下有没有名为clean的文件,输入命令make clean后其对应的命令总会被执行,不在去检查其依赖源文件列
表,而是直接执行命令,这在无形中叶提高了执行效率。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值