如何编写简单的Makefile文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37964547/article/details/81911445

一、什么是Makefile

1.GNU make是一个命令工具,是一个用来控制软件构建过程的自动化管理工具。Make工具通过称为Makefile的文件完成并自动维护编译工作。

3、makefile定义了一系列的规则来指定,一个工程中的哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

总之,makefile为我们带来了极大地好处—–“自动化编译”,一旦编译成功,只要我们使用一个make工具,整个工程就完全自动化编译,为软件开发提高了效率。

二、Makefile文件编写规则

1、基本构成

目标文件列表 分隔符 依赖文件列表

[命令]
[命令]

  • 单独的命令行要以tab键开始
  • # 代表注释行标志
  • 目标可以是一个或多个,可以是Object File,也可以是执行文件,甚至可以是一个标签。
  • 依赖文件列表就是生成目标所需要的文件或目标
  • 命令就是生成目标所需要执行的脚本

2、Makefile的组成部分

一个完整的Makefile文件主要有以下及部分构成:

(1)显式规则

所谓显式规则就是显式指定依赖文件或命令,例如:

 test:test.c
     gcc  -o  test test.c

当我们想生成一个可执行文件test时,这个test文件依赖与test.c文件,就可以用上面的格式进行编写,切记要在命令行前面加上tab键

(2)隐含规则

所谓隐含规则就是需要自动推导文件以及依赖文件后面的命令,不需要我们把每一个文件都写全,只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一 个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile再也不用写得这么复杂。
一个例子来帮助我们理解一下:

objects = main.o  command.o display.o /
              insert.o search.o 

    edit : $(objects)
            cc -o edit $(objects)



    main.o : defs.h
    command.o : defs.h command.h
    display.o : defs.h buffer.h
    insert.o : defs.h buffer.h
    search.o : defs.h buffer.h

  clean :
            rm edit $(objects)

这里有很多[.o]文件的依赖关系,看起来代码很复杂,很多,那么我们就可以使用隐含规则的推导功能重新写这个Makefile:

objects = main.o  command.o display.o /
              insert.o search.o

    edit : $(objects)
            cc -o edit $(objects)

    $(objects) : defs.h
     command.o : command.h
    display.o insert.o search.o : buffer.h
    clean :
            rm edit $(objects)

这样看起来就简单很多,但是也有缺点,这样修改会破坏文件本身的依赖关系

(3)伪目标

它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标称为标签。

使用伪目标有两点原因:
1. 避免在我们的Makefile中定义的只执行命令的目标(此目标的目的为了执行一系列命令,而不需要创建这个目标)和工作目录下的实际文件出现名字冲突。
2. 提高执行make时的效率,特别是对于一个大型的工程来说,编译的效率也许你同样关心。

例如:

clean:
    rm -f .o temp

这里的“rm”并不是创建“clean”文件,而是删除当前目录下的所有.o和temp文件,但是当当前目录下没有clean文件时,当我们输入“make clean”时,rm这一行命令总会被执行,但是当存在clean文件时,在我们输入“make clean”时。规则没有依赖文件,所以目标被认为是最新的而不去执行规则作定义的命令,命令“rm”将不会被执行。
但这并不是我们期望的结果,所以这时候就可以将clean文件定义成伪目标,就不会存在这种情况了;

.PHONY : clean 

这样,不管是否存在clean文件,我们输入“make clean”之后。“rm”命令都会被执行。

(3)特殊目标

  • .PHONY 所有的依赖被作为伪目标
  • .IGNORE 后面的依赖文件,生成这些文件的命令在执行时如果出现错误,将被忽略继续执行
  • .SUFFIXES 该目标的依赖文件被认为是一个后缀列表
  • .SILENT 执行生成依赖文件的命令时不会打印所执行的命令
  • .PRECLOUS 该目标的依赖文件会受到特殊对待,如果make被终止,或者终止,这些依赖并不会被删除,如果是中间文件,不需要时也不会删除
  • .INTERMEDIATE 目标依赖文件在make执行时被当做中间文件对待

(4)使用变量

  • 定义变量的形式:变量名 赋值符 变量值
  • 引用变量:(),要使用$$来表示

猜你喜欢

转载自blog.csdn.net/qq_37964547/article/details/81911445