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

第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\n", "Hello World");
6 }

func.c

1 SRCS := $(wildcard *.c)
2 OBJS := $(SRCS:.c=.o)
3
4 app.out : $(OBJS)
5     $(CC) -o [email protected] $^
6     $(RM) $^
7     @echo "Target ==> [email protected]"

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 [email protected] $^
 9     $(RM) $^
10     @echo "Target ==> [email protected]"
11
12 # 这里手动添加规则,进行验证
13 %.o : %.c
14     @echo "my rule"
15     $(CC) -c -o [email protected] $^
16     

Makefile(修改)

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

 

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

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

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

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

    echo  "$(.VARIABLES)"  

     

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

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

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

  

原文地址:https://www.cnblogs.com/shiwenjie/p/8321678.html

时间: 2024-11-13 21:55:56

第15课 - make的隐式规则(上)的相关文章

makefile(06)_隐式规则

15.Make的隐式规则 15.1.命令覆盖 问题1:通过各目标的命令拆分写到不同的地方,会发生什么?Makefile中出现同名目标时:依赖:所有的依赖将合并到一起,成为目标的最终依赖命令:当多处出现同一目标的命令时,make发出警告,所有之前定义的命令被最后的命令取代.注意:当使用include包含其他文件(makefile)时,需要确保被包含的文件中的同名目标只有依赖,没有命令:否则,同名目标的命令将被覆盖! 15.2.隐式规则 Make中提供了一些常用的,例行的规则实现,当目标的规则未提供

Makefile中的隐式规则

Makefile中的隐式规则 1.隐式规则中的变量 隐式规则中使用的变量分成两种:一种是命令相关的,如"CC":一种是参数相关的,如"CFLAGS". 与命令相关的变量 变量 含义 AR 函数库打开包程序.默认命令是"ar" AS 汇编语言编译程序.默认命令是"as" CC C语言编译程序.默认命令是"cc" CXX C++语言编译程序.默认命令是"g++" CO 从RCS文件中扩展文件

make 的隐式规则(十一)

如果我们将同一个目标的命令拆分的写到不同地方,会发生什么呢?我们来看看下面的代码 .PHONY : all all :     @echo "command-1" VAR := test          all :     @echo "all : $(VAR)" 我们来分析下,这份代码中有两个目标 all,那么我们在执行 make 的时候.它到底是执行哪个呢?一个可能是两个都执行,另一个就是执行第一个,因为默认的是执行第一个目标.下来我们来看看执行结果 我们看到

make--隐式规则 路径搜索及实例

一.隐式规则 问题一 .PHONY : all all: @echo "command-1" VAR:=test all: @echo "all:$(VAR)" make之后的结果如图所示可以得出的结论是A.makefile中出现同名目标时依赖:所有的依赖将合并在一起,成为目标的最终依赖命令:当多处出现同一目标时,make发出警告:所有之前定义的命令被最后定义的命令取代注意:当使用include关键字包含其他文件时,需要确保被包含文件中的同名目标只有依赖,没有命令:

hdu1818 It&#39;s not a Bug, It&#39;s a Feature!(隐式图最短路径Dijkstra)

题目链接:点击打开链接 题目描述:补丁在修bug时,有时也会引入新的bug,假设有n(n<=20)个潜在的bug和m(m<=100)个补丁,每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug.第一个串表示打补丁之前的状态('-'表示在该位置不存在bug,'+'表示该位置必须存在bug,0表示无所谓),第二个串表示打补丁之后的状态('-'表示不存在,'+'表示存在,0表示不变).每个补丁都有一个执行时间,你的任务是用最少的时间把一个所有bug都存在的软件通过打补丁的方式变得没

第5课:彻底精通Scala隐式转换和并发编程及Spark源码阅读

隐式转换函数implicit def function例如implicit def rddToPairRDDFunctions[K, V](rdd: RDD[(K, V)]) scala> class Person(val name: String)defined class Person scala> class Enginner(val name: String, val salary: Double) { | def code = println(name + " Coding

大数据Spark蘑菇云前传第15课:Scala类型参数编程实战及Spark源码鉴赏(学习笔记)

前传第15课:Scala类型参数编程实战及Spark源码鉴赏 本課課程: Spark源码中的Scala类型系統的使用 Scala类型系統编程操作实战 Spark源码中的Scala类型系統的使用 classOf[RDD[_]] 這個也是类型系統 這里的意思是說 B 這種類型必需至少是 A 這樣類型 Ordering Scala类型系統编程操作实战 作為類型系統最大的就可以對類型進行限制,在Scala 中的類型系統,他本身也作為對象.e.g. 我們可以建立 Person 這個類,現在可以建立一個什麼

selenium python 显式和隐式等待方法

1 # -*- coding:utf-8 -*- 2 from selenium import webdriver 3 from selenium.webdriver.common.action_chains import ActionChains 4 from selenium.webdriver.support.ui import WebDriverWait 5 6 import time 7 8 driver = webdriver.Firefox(executable_path='/Us

代理扩展-隐式代理和多播代理

代理这东西,真的不想再谈了,估计是个iOS开发人员都能熟练使用,跟Notification和Block一样,都用的滚瓜烂熟了. 这里小小的谈论一下代理的扩展:隐式代理和多播代理,其实非常简单. 隐式代理:就是定义协议的属性时不用再遵守协议了,实现方法的类也不用在遵守协议了,因为协议方法定义在NSObject的分类中. 直接上代码吧,真的是十分的简单: 1.Person类的头文件: 1 #import <Foundation/Foundation.h> 2 3 /** 4 NSObject的一个