zoukankan      html  css  js  c++  java
  • 第15课

    第15课 - make的隐式规则(上)

    1. 问题

      如果把同一个目标的命令拆分的写到不同地方,会发生什么?

      

      执行make all

      

      这个实验表明了:如果同一个目标的命令拆分的写到不同地方,那么 make 会覆盖之前的目标对应的命令,使用最新出现的目标对应的命令。

      makefile 中出现同名目标时

        — 依赖:

        • 所有的依赖将合并在一起,成为目标的最终依赖      

        — 命令:

        • 当多处出现同一目标的命令时,make 发出警告
        • 所有之前定义的命令被最后定义的命令取代   

      注意:当使用 include 关键字包含其它文件时,需要确保被包含文件中的同名目标只有依赖没有命令;否则,同名目标的命令将被覆盖!

         target 的下一行,以 tab 开头,该行也会被当做一条空命令。

      下面的示例代码就是当主makefile包含了其它makefile导致目标重名,引发了 bug。

      

      

    2. 什么是隐式规则(built-in rules)?  

      (1)make 提供了一些常用的,例行的规则实现

      (2)当相应目标的规则未提供时,make 尝试使用隐式规则

      思考:下面的 makefile 能成功编译吗?为什么?

      

      对应的源文件如下:

     1 #include <stdio.h>
     2 
     3 extern void foo();
     4 
     5 int main()
     6 {
     7     foo();
     8 
     9     return 0;
    10 }    
    main.c
    1 #include <stdio.h>
    2 
    3 void foo()
    4 {
    5     printf("void foo() : %s
    ", "Hello World");
    6 }
    func.c
    1 SRCS := $(wildcard *.c)
    2 OBJS := $(SRCS:.c=.o)
    3 
    4 app.out : $(OBJS)
    5     $(CC) -o $@ $^
    6     $(RM) $^
    7     @echo "Target ==> $@"
    Makefile

      执行 make app.out 成功得到 app.out 可执行程序。

      

      这个 Makefile 中没有 .o 中间文件对应的规则也没有定义 CCRM 变量,但是 make 成功执行并且生成了最终的 app.out 这个可执行程序。

      这表明了 make 调用了隐式规则中的 cc  -c  -o  xx.o  xx.c 以及 CC RM 变量

      修改上面的Makefile

     1 SRCS := $(wildcard *.c)
     2 OBJS := $(SRCS:.c=.o)
     3 
     4 # 这里将 cc 改为 gcc
     5 CC := gcc
     6 
     7 app.out : $(OBJS)
     8     $(CC) -o $@ $^
     9     $(RM) $^
    10     @echo "Target ==> $@"
    11 
    12 # 这里手动添加规则,进行验证
    13 %.o : %.c
    14     @echo "my rule"
    15     $(CC) -c -o $@ $^
    16     
    Makefile(修改)

     执行 make app.out 后的输出,这就验证了之前的隐式规则。

     

    3. 总结上面实验的隐式规则

      (1)make 提供了生成目标文件的隐式规则

      (2)隐式规则会使用预定义变量完成编译工作

        make 中的 .VARIABLES 预定义变量中包含了 make 的其它预定义变量

        echo  "$(.VARIABLES)"  

         

      (3)改变预定义变量将部分改变隐式规则的行为

      (4)当已经存在自定义规则时,不再使用隐式规则

    注:本文整理于《狄泰12月提升计划》课程内容

    狄泰QQ群:199546072

  • 相关阅读:
    分模块开发创建service子模块——(八)
    分模块开发创建dao子模块——(七)
    分模块开发创建父工程——(六)
    Html设置html与body元素高度问题
    原生JS给元素添加class属性
    【雪花点】雪花点的显示——(二)
    【雪花点】雪花点的显示——(一)
    Dom4j用Xpath获取节点——(六)
    Dom4j向XML中指定位置添加、删除、修改节点——(五)
    [置顶] 详细解读:技术有没有前途之分
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/8321678.html
Copyright © 2011-2022 走看看