分享

Makefile笔记

 海漩涡 2014-05-24

tanxiaohai
########################################################################

    一、Makefile中可以使用系统shell提供的任何命令来完成想要的工作

    二、make通过比较对应文件(规则的目标和依赖)的最后修改时间,来决定哪些文件需要更新、哪些文件不需要更新。对需要更新的文件make就执行数据库中所记录的相应命令来重建它,对于不需要重建的文件make什么也不做。


    三、make会重编译的情况:
    1.所有源文件没有被编译过,则对各个C源文件进行编译并进行链接,生成最后的可执行程序;
    2.每一个在上次执行make之后修改过的C源代码文件在本次执行make时将会被重新编译;
    3.头文件在上一次执行make之后被修改。所有包含此头文件的C源文件都会被重新编译;

--------------》》》》》》》》Makefile

target:                 #目标
clean:               #伪目标
prerequisites: #规则的依赖
command:         #规则的命令行,必须Tab开头(shell命令或可执行程序)


    " \ "可将较长行分解成多行,注:\后不可有空格
    只有执行动作,没有依赖的目标都称为"伪目标"。


    四、make的第一个规则的第一个目标为最终目标
            即Makefile最终需要更新或者创建的目标

            终极目标一般用   all:  表示


    五、Makefile中常用的变量

            RM := -rf      
            CXXFLAGS            #g++/gcc 的编译选项列表
            CPP_SRCS            #c++的源程序列表
            OBJS                        #编译的(".o" )目标列表
            LIBS                          #链接库列表

     六、.PHONY:clean    将clean目标声明为伪目标,即将后的目标列表都声明为伪目标

    七、Makefile主要包含5个内容:显示规则、隐含规则、变量定义、指示符、注释
            
            # 可以实现注释本行后面的内容,如果行尾有“\”时将下一行也注释,
            \#   为对特殊字符"#"的转义,此时无注释功能。

     八、第一个规则之后所有以[Tab]开头的行都会被交给系统shell程序去解析执行。

     九、执行make时按照文件名顺序读取文件并执行:“GNUmakefile”、“makefile”、”Makefile“
             第一个只有GNU  make才能识别

     十、通过命令指定目标使用make的隐含规则:
    
       1.有file.c或file.cpp时,   使用make file.o   会执行  gcc/g++ -o file.o file.c/file.cpp  

    十一、可执行文件的格式为“ELF”格式



#########################################################################


    十二、“include”指示符告诉make暂停读取当前的Makefile,而转去读取“include”指定的一个或者多个文件,完成以后再继续当前Makefile的读取。Makefile中指示符“include”书写在独立的一行
        1. 有多个不同的程序,由不同目录下的几个独立的Makefile来描述其重建规则。
        2. 当根据源文件自动产生依赖文件时;我们可以将自动产生的依赖关系保存在另外一个文件中

        如果指示符“include”指定的文件不是以斜线开始(绝对路径,如/usr/src/Makefile...),而且当前目录下也不存在此文件;make将根据文件名试图在以下几个目录下查找

      -include FILENAMES...
使用这种方式时,当所要包含的文件不存在时不会有错误提示、make也不会退出;除此之外,和第一种方式效果相同

    为了和其它的make程序进行兼容。也可以使用“sinclude”来代替“-include”(GNU所支持的方式)。


   十三、如果在当前环境定义了一个“MAKEFILES”环境变量,make执行时首先将此变量的值作为需要读入的Makefile文件,多个文件之间使用空格分开。


    十四、make程序在读取多个makefile文件时,包括由环境变量“MAKEFILES”指定、命令行指、当前工作下的默认的以及使用指示符“include”指定包含的,在对这些文件进行解析执行之前make读取的文件名将会被自动依次追加到变量“MAKEFILE_LIST”的定义域中。


    十五、特殊变量
    一个重要的特殊的变量是“.VARIABLES”。它被展开以后是此引用点之前、makefile文件中所定义的所有全局变量列表。包括:空变量(未赋值的变量)和make的内嵌变量


    十六、makefile文件的重建???????????????????????
    



########################################################################


    十七、make 如何解析Makefile文件
      
      第一阶段:读取所有的makefile文件(包括“MAKIFILES”变量指定的、指示符“include”指定的、以及命令行选项“-f(--file)”指定的makefile文件),内建所有的变量、明确规则和隐含规则,并建立所有目标和依赖之间的依赖关系结构链表。
     
      第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新,并使用对应的规则来重建这些目标。




***************************************************************************************************************
                                                              第四章:Makefile的规则
**************************************************************************************************************

1、除了makefile的“终极目标”所在的规则以外,其它规则的顺序在makefile文件中没有意义
          
 2、多个目标中的第一个将会被作为make的“终极目标”。
有两种情况的例外:
(1) 目标名以点号“.”开始的并且其后不存在斜线“/”(“./”被认为是当前目录;“../”被认为是上一级目录);
(2) 模式规则的目标。当这两种目标所在的规则是Makefile的第一个规则时,它们并不会被作为“终极目标”。


3.有时,需要定义一个这样的规则,在更新目标(目标文件已经存在)时只需要根据依赖文件中的部分来决定目标是否需要被重建,而不是在依赖文件的任何一个被修改后都重建目标。

规则依赖列表中管道符号“|”左边的是常规依赖,管道符号右边的就是“order-only”依赖及修改后目标不需重建。

4.Maekfile中表示文件名时可使用通配符。可使用的通配符有:“*”、“?”和“[…]”。不过只可以出现在下面两个地方。

(1). 可以用在规则的目标、依赖中,make在读取Makefile时会自动对其进行匹配处理(通配符展开);

(2). 可出现在规则的命令中,通配符的通配处理是在shell在执行此命令时完成的。


5、在变量的定义和函数引用时,通配符将失效。所以需要使用“wildcard”函数(变量定义为“objects=$(wildcard *.o)”)使object为.o文件列表


6、Makefile的搜索变量VPATH,。make搜索目录的顺序是按照变量“VPATH”定义中的目录顺序进行的.


7、关键字vpath,可以为不同类型的文件(由文件名区分)指定不同的搜索目录.
(1)、vpath PATTERN DIRECTORIES
为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者冒号(:)分开。类似上一小节的“VPATH”变量。

(2)、vpath PATTERN
清除之前为符合模式“PATTERN”的文件设置的搜索路径。

(3)、vpath
清除所有已被设置的文件搜索路径。

例:vpath %.h ../headers


8.自动化变量“$^”代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表。
  “$@”代表规则的目标。自动化变量“$<”代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件。


9、“-lNAME”的依赖文件名
(1). make在执行规则时会在当前目录下搜索一个名字为“libNAME.so”的文件;

(2). 如果当前工作目录下不存在这样一个文件,则make会继续搜索使用“VPATH”或者“vpath”指定的搜索目录。

(3). 还是不存在,make将搜索系统库文件存在的默认目录,顺序是:“/lib”、“/usr/lib”和“PREFIX/lib”(在Linux系统中为“/usr/local/lib”,其他的系统可能不同)。


10、伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时也可以将一个伪目标称为标签。
此目标的目的为了执行执行一些列命令,而不需要创建这个目标。

将一个目标声明为伪目标的方法是将它作为特殊目标.PHONY”的依赖。


11、伪目标的另外一种使用场合是在make的并行和递归执行过程中。此情况下一般会存在一个变量,定义为所有需要make的子目录。对多个目录进行make的实现方式可以是:在一个规则的命令行中使用shell循环来完成。如下:
SUBDIRS = foo bar baz
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done


12、在Makefile中,一个伪目标可以有自己的依赖(可以是一个或者多个文件、一个或者多个伪目标)


13 make存在一个内嵌隐含变量“RM”,它被定义为:“RM = rm –f”

14、强制目标(没有命令或依赖的规则)
clean: FORCE
rm $(objects)
FORCE:

15、空目标文件
print: foo.c bar.c
lpr -p $?
touch print

16、Makefile的特殊目标:.PHONY:标识伪目标

17、多目标
kbd.o command.o files.o: command.h

18、多规则目标
objects = foo.o bar.o
foo.o : defs.h
bar.o : defs.h test.h
$(objects) : config.h

19、执行“make extradeps=foo.h”那么“foo.h”将作为所有的.o文件的依赖文件。
extradeps=
$(objects) : $(extradeps)

20、静态模式:规则存在多个目标,并且不同的目标可以根据目标文件的名字来自动构造出依赖文件。
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@

21、filter函数
过滤不符合“%.o”
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<



22、双冒号规则(惹为普通规则时因两个相同目标而报错)
Newprog :: foo.c
$(CC) $(CFLAGS) $< -o $@
Newprog :: bar.c
$(CC) $(CFLAGS) $< -o $@

23、自动产生依赖
-M”选项gcc将自动找寻源文件中包含的头文件,并生成文件的依赖关系。
其输出结果中也包含对标准库的头文件的依赖关系描述。当不需要在依赖关系中考虑标准库头文件时,对于gcc需要使用“-MM”参数。




##########################################################################

                                                            第五章:规则的命令
##########################################################################


1、规则的命令由一些shell命令行组成,它们被一条一条的执行。规则中除了第一条紧跟在依赖列表之后使用分号隔开的命令以外,其它的每一行命令行必须以[Tab]字符开始。


2、命令回显:以@开头的命令将不会回显。

3、使用make的命令行参数“-n”或“--just-print”,那么make执行时只显示所要执行的命令,但不会真正的去执行这些命令

4、make参数“-s”或“--slient”则是禁止所有执行命令的显示,就好像所有的命令行均使用“@”开始一样。

5、在Makefile中书写在同一行中的多个命令属于一个完整的shell命令行,书写在独立行的一条命令是一个独立的shell命令行。因此:在一个规则的命令中,命令行“cd”改变目录不会对其后行的命令的执行产生影响。


6、并发执行命令,通过make的命令行选项“-j”或者“--job”来告诉make在同一时刻可以允许多条命令同时被执行(make的并发会产生非常多的问题)

7、命令执行的错误,命令之前加一个减号“-”(在[Tab]字符之后),来告诉make忽略此命令的执行失败。

8、在执行make时,如果使用命令行选项“-i”或者“—ignore-errors”, make将忽略所有规则中命令执行的错误。

9、一般make的“-k”参数在实际应用中,主要用途是:当同时修改了工程中的多个文件后,“-k”参数可以帮助我们确认对那些文件的修改是正确的(可以被编译),那些文件的修改是不正确的(不能正确编译)


10、make的递归执行
make的递归过程指的是:在Makefile中使用“make”作为一个命令来执行本身或者其它makefile文件的过程。
例:
subsystem:
cd subdir && $(MAKE)
其等价于规则:
subsystem:
$(MAKE) -C subdir

11、“CURDIR”,此变量代表make的工作目录。当使用“-C”选项进入一个子目录后,此变量将被重新赋值。

12、需要将一个在上层定义的变量传递给子make,应该在上层Makefile中使用指示符“export”对此变量进行声明。格式如下:

export VARIABLE...

不传给子make时:
unexport VARIABLE...

13、一个不带任何参数的指示符“export”指示符:export
含义是将此Makefile中定义的所有变量传递给子make过程。

14、在多级递归调用的make执行过程中。变量“MAKELEVEL”代表了调用的深度。


##########################################################################

                                                   第六章:Makefile中的变量
##########################################################################

1、在Makefile的目标、依赖、命令中引用变量的地方,变量会被它的值所取代(与C语言中宏引用的方式相同,因此其他版本的make也把变量称之为“宏”。

2、变量可以用来代表一个文件名列表、编译选项列表、程序运行的选项参数列表、搜索源文件的目录列表、编译输出的目录列表和所有我们能够想到的事物。

3、变量名是不包括“:”、“#”、“=”、前置空白和尾空白的任何字符串。

4、另外有一些变量名只包含了一个或者很少的几个特殊的字符(符号)。称它们为自动化变量。像“$<”、“$@”、“$?”、“$*”等

5、变量的引用方式是:“$(VARIABLE_NAME)”或者“${ VARIABLE_NAME }”来引用一个变量的定义。


6、一般在我们书写Makefile时,各部分变量引用的格式我们建议如下:
(1). make变量(Makefile中定义的或者是make的环境变量)的引用使用“$(VAR)”格式,无论“VAR”是单字符变量名还是多字符变量名。

(2). 出现在规则命令行中shell变量(一般为执行命令过程中的临时变量,它不属于Makefile变量,而是一个shell变量)引用使用shell的“$tmp”格式。

(3). 对出现在命令行中的make变量我们同样使用“$(CMDVAR)” 格式来引用。


7、递归方式展开变量
用=或define定义的,


8.“直接展开”式。这种风格的变量使用“:=”定义。在使用“:=”定义变量时,变量值中对其他量或者函数的引用在定义变量时被展开(对变量进行替换)。所以变量被定义后就是一个实际需要的文本串,其中不再包含任何变量的引用。

x := foo
y := $(x) bar
x := later
就等价于:
y := foo bar
x := later

9."?="操作符
只有此变量在之前没有赋值的情况下才会对这个变量进行赋值。例如:
FOO ?= bar
其等价于:
ifeq ($(origin FOO), undefined)
FOO = bar
endif

10.变量的替换引用
foo := a.o b.o c.o
bar := $(foo:.o=.c)
变量“bar”的值就为“a.c b.c c.c”

11.






    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多