makefile整体性的一些概念

来源:互联网 发布:vscode js代码高亮 编辑:程序博客网 时间:2024/06/06 14:03
                                        makefile的规则
/***************************************************************************************************
makefile的规则是makefile最核心的部分,规则的基本格式如下:
        目标 ... : 依赖对象 ...
            命令
            ...

        目标可以是可执行文件、中间文件、标签,"..."意味着一条规则可以包含多个目标
        依赖对象通常就是生成那个目标所需要的文件,"..."意味着一条规则可以包含多个依赖对象
        命令就是任意shell命令,定义了如何基于依赖对象生成目标的一系列规则,"..."意味着一条规则可以包含多条命令
***************************************************************************************************/

                                        makefile中的隐含规则
/***************************************************************************************************
隐含规则,就是早先约定好了,不需要再写出来的规则.

隐含规则会使用makefile的一些预定义变量,比如$(CFLAGS),所以可以通过改变这些预定义变量的值,来定制隐含规则运行时的参数;
要想激活隐含规则,唯一要做的就是不写出目标的规则(规则包括依赖和对应的命令),这样makefile就会试图去自动推导产生这个目标的规则.

以编译C程序为例,常见的隐含规则如下:
    1.     %:%.c
            $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
        释义:所有可执行文件默认都可由对应的".c"文件自动生成
    2.     %:%.o
            $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
        释义:所有可执行文件默认都可由对应的".o"文件自动生成
    3.     %.o:%.c
            $(CC) $(CFLAGS) -c -o $@ $<    
        释义:所有".o"文件默认都可由对应的".c"文件自动生成

    备注:这3条隐含规则只能自动推导相同文件名的不同后缀名文件,如a.o文件必须由a.c文件生成,
          这种一对一的依赖关系导致前2条隐含规则适用条件太单一,所以最常用的往往只有第3条
          

***************************************************************************************************/
                                            
                                        makefile中的模式规则
/***************************************************************************************************
模式规则,就是专门用来定义隐含规则的,以上3条隐含规则就是makefile预定义的模式规则,所以用户也可以使用模式规则自定义/重定义一个隐含规则.

模式规则的目标定义中必须包含"%",否则就是一般的规则;
目标中的"%"表示长度任意的非空字符串,同时目标中的"%"的值决定了依赖对象中的"%"值,make会去匹配当前目录下所有的文件名,
一旦找到,make就会执行该模式规则中的命令.
***************************************************************************************************/

                                        make的工作流程
/***************************************************************************************************
默认方式下,也就是只输入make命令后,其执行流程大致如下:
    1. 在当前目录找名字叫"Makefile"或"makefile"的文件(作为主makefile)
    2. 读入makefile文件中include的其他makefile
    3. 初始化所有变量
    4. 从上往下顺序寻找makefile文件中的第一个目标,并把它作为最终的目标
    5. 基于最终的目标生成依赖关系链
    6. 如果最终目标存在,判断依赖关系链末尾的依赖对象的文件修改时间是否要比最终的目标文件新
    7. 执行生成命令

备注:可以通过"-f"来指定要执行的makefile,特别是执行非标准名称的makefile;
      make命令首先会将include指向的makefile文件中的内容全部原封不动载入到主makefile,所以接下
      来变量初始化和寻找第一目标都是基于全部载入完成后的makefile,也就是说,第一目标不一定在主
      makefile中(虽然估计不提倡这么做);
      所有变量的初始化都先于规则的执行,也就是说,从格式上,变量的初始化可以位于规则之后(虽然
      估计不提倡这么做)
      默认方式将地一个目标作为最终目标,但也可以通过输入"make 目标"来显式地指定最终目标;
      跟最终目标没有直接或间接依赖关系的规则将都不会被自动执行到;



***************************************************************************************************/

                                        makefile函数
/***************************************************************************************************
makefile里的函数使用,和使用变量类似,也是“$()”格式,括号里面是函数名和形参,形参之间一般用“,”隔开

1. wildcard
    用法:    SRC = $(wildcard *.c ./sub/*.c)
    释义:    搜索当前目录和./sub目录下所有以.c结尾的文件,生成一个以空格间隔的文件名列表,并赋值给SRC。当前目录文件只有文件名,子目录下文件名包含相对路径
    
2. notdir
    用法:    SOURCE = $(notdir $(SRC))
    释义:     去除所有的路径信息,返回文件名列表的非目录部分

3. dir
    用法:    DIR = $(dir $(SRC))
    释义:    取目录函数,返回文件名列表的目录部分
        
3. patsubst
    用法:    OBJ = $(patsubst %c,%o,$(SOURCE))
    释义:    将DIR中所有结尾是c字符的变量替换成o字符,这里还有另外一种替换方法,其格式是“$(var:a=b)/${var:a=b}”,含义同patsubst

4. strip
            $(strip $(string))
    释义:    将字符串"string"中多个连续的空字符合并为一个空字符,strip函数通常用在条件判断语句的表达式中,确保表达式的可靠和健壮

5. findstring
    用法:    $(findstring find,string)
    释义:    搜索字符串"string",查找"find"字符串,如果存在则返回"find"字符串,否则返回空

6. call
    用法:    $(call expression,parm1,parm2,...)
    释义:    call函数可以用来向表达式expression传入一系列参数parm,而expression的返回值就是call函数的返回值    

7. subst
    用法:    $(subst from,to,string)
    释义:    把字符串string中的from字符串替换成to字符串,返回被替换过后的字符串
原创粉丝点击