一个简单的makefile编写说明

时间:2022-10-03 09:22:28

makefiel规则模板:
 TARGET... : PREREQUISITES...
 COMMAND
 ...
说明 ...
      1:1target:规则的目标。通常是最后需要生成的文件名或者为了实现这个目的而必需
 中间过程文件名。可以是.o文件、也可以是最后的可执行程序的文件名等。
 如目标“clean” ,我们称这样的目标是“伪目标”。

      2:prerequisites:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依
 赖于一个或者多个文件。

      3:command:规则的命令行。是规则所要执行的动作(任意的 shell 命令或者是可在
 shell下执行的程序) 。它限定了 make执行这条规则时所需要的动作。
 
      4:一个规则可以有多个命令行,每一条命令占一行。 注意: 每一个命令行必须以[Tab]
 字符开始,[Tab]字符告诉 make 此行是一个命令行。make按照命令完成相应的动作。
 这也是书写 Makefile 中容易产生,而且比较隐蔽的错误。

      5:命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。一个目标可
 以没有依赖而只有动作(指定的命令) 。比如Makefile 中的目标“clean” ,此目标没有
 依赖,只有命令。它所定义的命令用来删除 make过程产生的中间文件(进行清理工作)。 

例子:
一:按标准规格编写
 edit : main.o kbd.o command.o display.o \
  insert.o search.o files.o utils.o
  cc -o edit main.o kbd.o command.o display.o \
   insert.o search.o files.o utils.o
 main.o : main.c defs.h
  cc -c main.c 
 kbd.o : kbd.c defs.h command.h
  cc -c kbd.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
 files.o : files.c defs.h buffer.h command.h
  cc -c files.c
 utils.o : utils.c defs.h
  cc -c utils.c
 clean :
  rm edit main.o kbd.o command.o display.o \
   insert.o search.o files.o utils.o
    
 需要创建可执行程序“edit”,所要做的就是
 在包含此Makefile的目录(当然也在代码所在的目录)下输入命令“make”。删除已经
 此目录下之前使用“make”生成的文件(包括那些中间过程的.o文件),也只需要输入
 命令“make clean”就可以了

 以上我们通过一个简单的例子,介绍了 Makefile 中目标和依赖的关系。我们简单
 总结一下:对于一个 Makefile 文件,“make”首先解析终极目标所在的规则(上节例
 子中的第一个规则),根据其依赖文件(例子中第一个规则的8个.o文件)依次(按照
 依赖文件列表从左到右的顺序)寻找创建这些依赖文件的规则。首先为第一个依赖文件
 (main.o)寻找创建规则,如果第一个依赖文件依赖于其它文件(main.c、defs.h),
 则同样为这个依赖文件寻找创建规则(创建 main.c和 defs.h的规则,通常源文件和头
 文件已经存在,也不存在重建它们的规则)……,直到为所有的依赖文件找到合适的创
 建规则。之后 make 从最后一个规则(上例目标为 main.o 的规则)回退开始执行,最
 终完成终极目标的第一个依赖文件的创建和更新。之后对第二个、第三个、第四个……
 终极目标的依赖文件执行同样的过程(上例的的顺序是“main.o”、“kbd.o”、
 “command.o”……)。
二:按标变量编写
 objects = main.o kbd.o command.o display.o \
 insert.o search.o files.o utils.o

 edit : $(objects)
  cc -o $(objects)
 main.o : main.c defs.h
  cc -c main.c 
 kbd.o : kbd.c defs.h command.h
  cc -c kbd.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
 files.o : files.c defs.h buffer.h command.h
  cc -c files.c
 utils.o : utils.c defs.h
  cc -c utils.c
 clean :
  rm edit $(objects)
三:按自动推导规则  
 编译.c源文件规则的命令可以不用明确给出。这是因
 为make本身存在一个默认的规则,能够自动完成对.c文件的编译并生成对应的.o文件。
 它执行命令“cc -c”来编译.c源文件。在Makefile中我们只需要给出需要重建的目标文
 件名(一个.o文件) ,make会自动为这个.o文件寻找合适的依赖文件(对应的.c文件。
 对应是指:文件名除后缀外,其余都相同的两个文件) ,而且使用正确的命令来重建这
 个目标文件。对于上边的例子,此默认规则就使用命令“cc -c main.c -o main.o”来创
 建文件“main.o” 
 objects = main.o kbd.o command.o display.o \
          insert.o search.o files.o utils.o
      
 edit : $(objects)
  cc -o edit $(objects)       
 main.o : defs.h
 kbd.o : defs.h command.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
 files.o : defs.h buffer.h command.h
 utils.o : defs.h
      
 .PHONY : clean
 clean :
 rm edit $(objects)
 书写规则建议的方式是:单目标,多依赖。就是说尽量要做到一个规则中只存在一
 个目标文件,可有多个依赖文件。尽量避免使用多目标,单依赖的方式。这样书写的好
 处是后期维护会非常方便,而且这样做会使Makefile 会更清晰、明了 

 .PHONY : clean
 clean :
 -rm edit $(objects)  
 这两个实现有两点不同: 1. 通过“.PHONY”特殊目标将“clean”目标声明为伪
 目标。避免当磁盘上存在一个名为“clean”文件时,目标“clean”所在规则的命令无
 法执行。2. 在命令行之前使用“-”,意思是忽略命令“rm”的执行错误。
四:按采用通配符号 %.o:%.h
$@    ;$%   ;$<   ;$?   ;$^   ; $+   ;$*   ;$(@D)  ; $@)   ;$(*D)   ;$(*F)   ;$(%D)
$(%F)  ;$(<D)   ;$(<F)   ;$(^D)  ;$(^F)   ;$(+D)   ;$(+F)   ;$(?D)    ;$(?F)