1,以#开头的行为注释行,相当于C语言的// ,在makefile中是区分大小写的,
makeMAKE是不一样的。
如果需要在makefile中使用#的符号,就要用反斜杠\#转义成#本身的意义
2,makefile格式variable怎么记
目标:依赖文件1,依赖文件2
命令依赖文件后缀 依赖文件1,依赖文件2 目标
注意:命令行必须以单个的TAB字符进行缩进,不能是空格
    当然也可以跟 目标和依赖文件在一行,不过要以;隔开
3,宏定义在linux中其实就是变量定义,在引用宏时必须在宏前加上$符号,而且如果变量名的长度超过一个字符,在引用时必须加圆括号()。
注意:$Z=$(Z),$(2),$(CFLAGS)都是有效的变量
4$*,$@,$?,$<四个特殊的宏的值在执行命令的过程中会发生相应的变化(自动化变量)
5,宏的定义很简单,格式为:
  变量=变量值
6,反斜杠(\)有时在makefile中是换行符的意思。
7隐晦规则指的就是.o文件自己推导出同名的依赖文件.c.
8伪目标的格式可以为:
.PHONY: clean
clean:
rm edit $(obiect)
“.PHONY”表示,clean是个伪目标文件。
9,有些是在命令的前面加上减号如:
如上句的:-rm edit $(obiect)
也许某些文件出现问题,但不要管,继续做后面的事,这个减号的作用就是加强保障,还有一个全局的办法就是给make加上“-I”或是“ignore-errors”参数,那么makefile中所有的命令都会忽略错误。还有一个就是make的参数是”-k”或是“-keep-going”,这个参数的意思是如果规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。
10makefile 工作执行的步骤:
1)、读入所有的Makefile。
2)、读入被include的其它Makefile。
3)、初始化文件中的变量。
4)、推导隐晦规则,并分析所有规则。
5)、为所有的目标文件创建依赖关系链。
6)、根据依赖关系,决定哪些目标要重新生成。
7)、执行生成命令。
11,makefile支持三个通配符“*”“?”“[...]如果需要表示真正的符号*,就要在前面加上\*
表示。
12,文件搜索,当Make寻依赖文件时,你可以指定一个路径给male让它自动去寻文件,通常用特殊变量”VPATH”来完成这个功能。
比如:VPATH=scr:…/headers
指定了这两个路径之后make首先会在当前目录寻,然后再到scr…/headers目录下寻。各个目录用: 分隔。
另外一个是vpath,它不是变量,而是makefile关键字,是全小写的。它有三种用法。这里不详细描述。
13,在通常情况下,make会生成一个可执行的最终文件,但是也可以通过伪目标的特性生成多个最终目标。
14%一般是在模式中作通配符的,跟*的作用一样,但应用场合不同。如果想要应用真正的%,就用\%转义。
15,静态模式规则
16,自动生成依赖性。
这个需要用到 –M参数,比如 cc –M main.c
输出就是 main.o: main.c def.h  #def.hmain.cinclude文件
所以上面-M的作用就是查源文件的包含文件,自动生成依赖性。有些情况下也会用到-MM参数。
17,用@字符的时候,命令将不被显示出来,它和echo结合使用类似于dos下的应用。
  makefile执行时,make 带有参数“-n””-just-print”,那么其就只会显示命令,不执行命令。这个功能有利于我们调试Makefile,看看我们书写的命令执行起来是什么样子的或是什么顺序的。
makefile参数“-s”-slient”则是全面禁止命令的显示
18,如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号分隔这两条命令。
比如 cd /home/hchen
  Pwd
和命令 cd /home/hchen; pwd
两条命令执行的效果是不一样的,上面一条PWD是在当前目录之下之行的,但是下面那条目录就是进入到/home/hchen中去执行Pwd.
19,嵌套执行总控Makefile的变量可以传递到下级的Makefile中(如果你显示的声明)但是不会覆盖下层的makefile中所定义的便量。除非指定了“-e”参数
如果你要传递变量到下级makefile中,那么你可以使用这样的声明:
Export<variable…>
如果你不想让某些变量传递到下级makefile中,那么你可以这样声明:
Unexport<variable>
export variable = value
其等价于:
variable = value
export variable
其等价于:export variable := value
需要注意的是:如果你要传递所有的变量,只要一个export就行了,后面什么也不用跟,表示传递所有的变量。
需要注意的是,有两个变量一个是SHELL,一个是MAKEFLAGS,这两个变量不管你是否export,其总是要传递到下层makefile中。Make命令中有几个参数并不往下传递,它们是“-C”
“-f”,”-h”,”-o”和“-W”.
还有一个在“嵌套执行”中比较有用的参数,
-w”或”—print-directory”会在make的过程中输出一些信息,比如进入/home/hchen/gun/make,就会看到:
Make: Entering directory /home/hchen/gnu/make
而在完成后离开会显示:
Make:leaving directory /home/hchen/gnu/make
如果有参数“-s”(slient)或是”—no-print-directory,那么“-w”总是失效的。
20
隐含规则:老式风格的后缀规则,后缀规则有两种方式:单后缀和双后缀。双后缀定义了一对后缀,目标文件和依赖文件的后缀。如.c.o相当于%o:%c.单后缀就定义一个源文件后缀.c就相当于%o:%c.
在使用后缀规则中不允许有任何的依赖文件,例如,.c.o: def.h  这里.c.o就会被认为.c.o是目标文件,而def.h是依赖文件。后缀规则中,如果没有命令,那是毫无意义的。因为他也不会移去内建的隐含规则。要想让make知道一些特定的后缀,我们可以用 伪目标 .SUFFIXS”来定义或删除。
例如:.SUFFIXES: .hack .win  将两个后缀加入后缀列表中,以便让make能识别。
      .SUFFIXES:          删除默认的后缀
      .SUFFIXES: .c .o .h # 定义自己的后缀
    先清除默认后缀,再定义自己的后缀
21, 最后一章使用make更新函数库文件。
函数库文件就是对Obiect的打包文件,一般是由命令”ar”来进行打包的。有.a.lib文件。
一般格式如下:archive(menber)
这不是一个命令,而是一个目标和依赖文件,menber之间如果有多个成员,就用空格隔开。
还有一个就是要注意自动化变量"$%"这是专属的函数库的自动化变量。
22makefile中的变量使用非常灵活,可以在目标,依赖目标,“命令”或其他部分。
  而且makefile对大小写也是敏感的。MakeMAKE是两个不同的变量。
  变量在使用时要在前面加上$,后面引用的变量用括号(),{}包括起来,如果真要使用$,就得用$$来进行转义。
变量会在使用它的地方精确地展开,就像C/C++中的宏一样
Makefile中有两种方式来定义变量,一种是简单的用“=”号。左边是变量,右边是变量值,而且右边的变量值可以在后面定义。
例如:
Foo=$(Bar)
Bar=$(Hun)
Hun=Uk
最后得出的结果就是Foo=Uk
另外一种就是使用”:=”操作符,这种方法的定义就是前面的变量不能利用后面定义的值。形式与上面类似。
注意:对于系统变量MAKELEVEL,其意思是如果我们有一个嵌套执行的动作,这个变量是记录当前makefile的调用层数。
还有一个比较有用的操作符”?=”.
例如Foo?=bar
这句话的意思是如果Foo在之前没有被定义过,它的值就等于bar.如果在之前被定义过,那么就什么也不做。
下面开始变量的高级用法:主要有两种。
一种是变量值的替换,格式为$(var:a=b)意思就是将var中的a字符用b来替换,a可以包含空格和符号。另外的替换还有以“静态模式“定义的。
如:foo :=a.o b.o c.o
Bar :=$(foo:%.o=%.c)
这种就是被替换的字符必须有相同的模式,这种跟上面的效果是一样的。
第二种高级用法是把变量的值再当成变量
例如
x=y
y=z
z=u
a:=$($($(x)))  这里的$(a)的值是”u”
23,使用条件判断
关键字:ifeq,else,endif
ifeq ($(CC),gcc)
Ifeq表示条件语句的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括起else表示条件表达式为假的情况。endif表示一个条件语句的结束,任何
一个表达式都应该以endif结束。 Ifeq的这种关键字有四个,除了ifeq之外,还有ifneq.这两个是相反着用的。第三个是ifdef,第四个是ifndef.这个是判断ifdef <variable-name>
ifndef <variable-name>是否有值。如果有值则为真(另外一个就是没值为真)。
这种条件判断可以有多余的空格,但是不能以Tab键开头,因为容易被当成命令对待。而且#的应用也是安全的。
注意:
在makefile中,你可能会注意到:
目标:依赖目标
  命令
但是有些却是只有:
目标:(没有依赖目标)
  命令
  或者
目标:依赖目标
(没有命令)
这种多样的makefile书写格式。主要讲解一下后面的两种:
1,没有依赖目标:
  这种会被当作伪目标或者标签,makefile不会去寻依赖文件,也不会自动执行后面的命令,只能显式的用make (目标) 来执行命令。
2,没有命令:
  这种make会去寻依赖文件,跟有命令是一样的,只是它执行的是空命令,什么也不做。
注意2:一个工程的编译,往往写进makefile里面的内容跟实际存在磁盘上的文件有对应关系,所以我们描述的时候要注意哪些是描述makefile里面的字符,哪些是描述磁盘上对应的文件。