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

    第3课 - makefile伪目标的引入

    1. makefile 中的目标究竟是什么?

      (1)默认情况下,make 认为目标对应着一个文件  ==>  目标即文件名

      (2)make 首先会检测目标对应的文件是否存在,若不存在则执行依赖和命令。若存在则会比较目标文件和依赖文件的新旧关系,决定是否执行命令。

          在 make 中,通过比较目标文件和依赖文件的时间戳,来判断两者的新旧关系。make 程序使用的时间戳的类型是 mtime(modify time),即文件发生修改的时间。

          在 linux 中,有三个时间的概念,修改时间 mtime(modify time)、访问时间 atime(access time)、状态改动时间 ctime(change time)。

      (3)make 以文件处理作为第一优先级。

    2. 伪目标的引入

      下面的代码有什么意义?   

      

      执行 make clean 会将第2课中编译生成的中间 .o 文件和 hello.out 目标文件删除。但如果该目录下存在名为 clean 的文件就会导致删除命令执行失败

      有时我们并不希望目标对应的都是文件,而只是把目标当作一个标签来使用,这就引入了makefile中的伪目标。

      (1)makefile 中的伪目标

      • 通过 .PHONY 关键字声明一个伪目标
      • 伪目标不对应任何实际的文件(目录下有同名的文件也不会影响执行
      • 不管伪目标的依赖是否更新,命令总是执行

      (2)makefile 伪目标的语法:先声明,后使用

        本质伪目标是 make 中特殊目标 .PHONY 的依赖

        

    编程实验

     1 # makefile伪目标的引入
     2 
     3 hello.out all : func.o main.o
     4     gcc -o hello.out func.o main.o
     5     
     6 func.o : func.c
     7     gcc -o func.o -c func.c
     8     
     9 main.o : main.c
    10     gcc -o main.o -c main.c
    11 
    12 .PHONY : clean
    13 clean :
    14     rm *.o hello.out

      (3)makefile 伪目标的妙用:规则调用(函数调用)

      

     原理:当一个目标的依赖包含伪目标时,伪目标所定义的命令总是会被执行。当执行 make rebuild 时首先会删除之前编译生成的垃圾文件,然后重新编译整个工程。

     1 # makefile中利用伪目标实现规则调用
     2 
     3 hello.out : func.o main.o
     4     gcc -o hello.out func.o main.o
     5     
     6 func.o : func.c
     7     gcc -o func.o -c func.c
     8     
     9 main.o : main.c
    10     gcc -o main.o -c main.c
    11 
    12 .PHONY : rebuild clean all
    13 
    14 rebuild : clean all
    15 
    16 all : hello.out
    17 
    18 clean :
    19     rm *.o hello.out

      (4)技巧:绕开 .PHONY 关键字定义伪目标

        .PHONY 关键字只有标准的make(GNU make)才拥有,在使用非标准的make时可以使用如下技巧定义伪目标。   

        

      原理:如果一个规则只有一个目标,并且该目标不是一个存在的文件名,则在执行此规则时,目标总会被认为是最新的。

            当执行 make clean 时,由于 FORCE 会被认为是最新的(FORCE 比 clean 要新),clean 下的命令必然被执行。

     1 #非GNU make下伪目标的实现方法
     2 
     3 hello.out : func.o main.o
     4     gcc -o hello.out func.o main.o
     5     
     6 func.o : func.c
     7     gcc -o func.o -c func.c
     8     
     9 main.o : main.c
    10     gcc -o main.o -c main.c
    11 
    12 clean : FORCE
    13     rm *.o hello.out
    14 FORCE :   

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

    狄泰QQ群:199546072

  • 相关阅读:
    《Fluent Python》 CH.06_函数_使用一等函数实现设计模式 (函数式策略模式+命令模式)
    《Python+Spark 2.0+Hadoop》第10章 Python Spark RDD 读书笔记 (转换/动作运算、广播变量、累加器、示例略)
    《Fluent Python》 CH.05_数据结构-一等函数 (函数对象的各种内置函数、operator模块、itemgetter 和 attrgetter迭代/取值函数)
    JAVA时间字符串去空格、冒号和横杠
    Maven 构建生命周期(compile与install的区别)
    MySQL-进程占用CPU资源高问题分析
    K8S-二进制安装部署高可用集群环境
    Oracle-DG环境中Gap
    MySQL-主从复制环境升级小版本软件
    SequoiaDB
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/6750299.html
Copyright © 2011-2022 走看看