Linux下Makefile的基础知识

1.Makefile简介

Makefile文件中写的是:工程编译的规则以及编译顺序。

只需要每次执行make命令,make就会自动在当前目录下搜索Makefile或makefile。

然后按照makefile中指定的规则编译整个工程。

注意:如果文件不修改,则不需要重新编译!!!

例如:

//makefile

main:main.o

        gcc  main.o  -o main

main.o:

        gcc  -c  main.c

(从“main:”进入,先找到main.o执行gcc  -c  main.c,然后再回到main执行gcc  main.o  -o  main)

1.1主要的五部分

  • 显示规则
  • 隐晦规则
  • 变量定义
  • 文件指示
  • 注释

Makefile基本格式:

target ... : condition ...
    command
        ...
        ...
  • target是目标文件,即生成的目标文件或可执行文件的名称
  • condition为生成target所需要的文件或目标文件
  • command是需要执行的全部命令 MakeFile中的命令必须以TAB键开头
  1. 显示规则 :显式规则说明了,如何生成一个或多的的目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
  2. 隐晦规则:由于我们的 make 有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile,这是由 make 所支持的。
  3. 变量定义:在 Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点你 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。
  4. 文件指示:Makefile中的目标文件编译依赖其他的头文件;或是依赖其他makefile
  5. 注释:Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符,这个就像 C/C++中的“//”一样。如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行转义,如:“\#”。

          还值得一提的是,在 Makefile 中的命令,必须要以[Tab]键开始

1.2 GNU make 的工作流程

  1. 读入文件中的主Makefile
  2. 读入被引入的其他Makefile文件
  3. 初始化文件的变量
  4. 推倒隐晦规则,并分析文件当中其他的规则
  5. 为所有的目标文件创建依赖关系链
  6. 根据依赖关系,确定哪些目标要重新生成
  7. 执行生成命令

2.Makefile基本语法

2.1Makefile规则

2.1.1 规则语法

语法有以下两种

target ... : condition ...
    command
    ...
    ...

target ... : condition ... ;command
    command
    ...
    ...

target也就是一个目标文件,可以使Object  File,也可以是可执行文件。还可以是一个标签,即伪目标

2.1.2 规则中的通配符

*   标识任意一个或多个字符

?  表示任意一个字符

~  表示用户的home目录

输入' \ '可在下一行继续输入

2.1.3 路径搜索

当Makefile文件中依赖的文件有不在当前路径下时则要标明文件路径。

所以要在Makefile文件中标明文件的路径,Makefile中有一个特殊的标量VPATH或vpath就是完成这个功能的。

指定了路径之后,如果有文件在当前目录没有找到时,就会到VPATH指定的路径下去找。

  • VPATH和vpath的使用方法:

VPATH = ./src : ./sum : ./public : ...

//大写的VPATH可以直接赋值要找的路径,每个路径之间用 : 号隔开

vpath  sum.c  ./sum

vpath  main.c  ./public

vpath  %.h  ./public

vpath  %.c  ./max : ./sum : ./sub : ./public

//使用vpath可以对指定文件或指定的类标明路径

vpath  %.c  

//清楚符合%.c文件的搜索路径

vpath

//清楚所有设置的搜索路径

2.2Makefile 中的变量

2.2.1 变量定义

OBJS = sum.o  sub.o  max.o  min.o  main.o

OBJS2 = $(OBJS)  program.o

//目标OBJS包含了sum.o ... main.o

//目标OBJS2包含了OBJS的所有内容以及 program.o

测试:

OBJS  =  main.o  max.o  min.o\

                                        sub.o

objects  =   $(OBJS)  +  sum.o

PATH  =  ./main : ./max : ./min : ./sub : ./sum

edit: $(objects)

        gcc  -o  edit  $(objects) 

# bash中执行make命令

$ make

edit  main.o  max.o  min.o  sub.o  sum.o

好处:如果有新的 .o 文件加入,我们只需简单地修改一下 objects 变量就可以了。

2.2.2 目标变量

objects = main.o  command.o  display.o \
                                          insert.o  search.o
edit : $(objects)
         gcc  -o  edit  $(objects)
main.o : main.c defs.h
         cc -c main.c
command.o : command.c defs.h command.h
         cc -c command.c
display.o : display.c defs.h buffer.h
         cc -c display.c
insert.o : insert.c defs.h buffer.h
         cc -c insert.c
search.o : search.c defs.h buffer.h
         cc -c search.c


clean :
         rm edit $(objects)

//edit就是一个目标变量,即最后生成的目标文件或可执行文件名就是edit

3. Makefile的自动推倒

GNU 的 make 很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的 make 会自动识别,并自己推导命令。
只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make 找到一个 whatever.o,那么 whatever.c,就会是 whatever.o 的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的 makefile 再也不用写得这么复杂。我们的是新的 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


.PHONY : clean
clean :
rm edit $(objects)

这种方法就是 make 的“隐晦规则”。上面文件内容中,“.PHONY”表示,clean 是个伪目标文件。

执行clean命令,所生成的文件就会全部删除。



4. 清空目标文件的规则

每个 Makefile 中都应该写一个清空目标文件(.o 和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。

例如:

clean:
        rm edit $(objects)

更为完全的做法是

.PHONY : clean
clean :
        -rm edit $(objects)

.PHONY 意思表示 clean 是一个“伪目标”,。而在 rm 命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然,clean 的规则不要放在文件的开头,不然,这就会变成 make 的默认目标,

记住——clean从来都是放在文件的最后

暂时就先整理了这么多,初学者知识能力有限,还望大佬们指教,谢谢!

猜你喜欢

转载自blog.csdn.net/judgejames/article/details/83003411