• makefile 中竖线 “|” 管道符的作用


    目录
    1. makefile基本语法复习
    2. 命令前提目标 order-only prerequisites
    3. 例子
    在makefile中,有时会在依赖关系中看到竖线“|”管道符,它是作用是用来指示命令前提目标 order-only prerequisites。

    1. makefile基本语法复习
    这里,我们简单复习一下makefile基本语法。其中的[TAB]就是键盘上的Tab键,不可以用空格替代。

    target : prerequisites
    [TAB]command1
    [TAB]command2
    [TAB]...
    [TAB]commandN

    其中,
    target,称为生成目标。可以是Object File,也可以是执行文件,还可以是一个标签(Label)。
    prerequisites ,称为前提目标。
    command*,是make需要执行的命令,任意的Shell命令。

    2. 命令前提目标 order-only prerequisites
    在makefile中,有时会在依赖关系中看到竖线“|”管道符,它是作用是用来指示命令前提目标 order-only prerequisites。

    事实上make工具能理解两种类型的前提目标:
    Type I: 正常前提目标(normal prerequisites)
    正常前提目标能达成两个目的:
     i. 影响build command执行顺序,即:在生成目标(target)的命令被执行前,所有的需要生成的前提目标(prerequisites)的命令都需要被执行。
    ii. 影响依赖关系,即:如果任何一个前提目标(prerequisites)比生成目标(target)新时,生成目标都将被认为太旧而需要被重新生成。
    通常,上面的这两个目的正是你所需要的:当前提目标更新时,生成目标也需要更新。

    Type II: 命令前提目标(order-only prerequisites)
    偶尔的,我们会遇到这样的情况:我们需要执行某个或某些规则,但不能引起生成目标(target)被重新生成。此时你就需要使用命令前提目标。命令前提目标由一个管道符号即竖线“|”指示,位于前提目标列表中。竖线左边的目标就是正常前提目标,竖线右边的目标就是命令前提目标,形式如下:

    target : normal-prerequisites | order-only-prerequisites
    注1:竖线“|”左边的正常前提目标列表可以是空。
    注2:如果前提目标中同时存在正常前提目标和命令前提目标,则正常前提目标(normal prerequisites)优先生成。
    注3:规则依赖文件列表中如果一个文件同时出现在常规列表和“order-only”列表中,那么此文件被作为常规依赖处理。
    注4:只有在生成目标文件不存在时,命令前提目标才会参与规则的执行。
             但是,当生成目标文件存在时,命令前提目标不会参与规则的执行。

    3. 例子
    3.1. 例子1:

    LIBS = libtest.a
    foo : foo.c | $(LIBS)
    $(CC) $(CFLAGS) $< -o $@ $(LIBS)

    make在执行这个规则时,如果生成目标文件“foo”已经存在。当“foo.c”被修改以后,目标“foo”将会被重建。但是,当“libtest.a”被修改以后,将不执行规则的命令来重建目标“foo”。
    就是说,规则中命令前提目标$(LIBS)只有在生成目标“foo”文件不存在的情况下,才会参与规则的执行。当目标文件存在时此依赖不会参与规则的执行过程。

    3.1. 例子2:
    创建如下三个文件

    func.c,main.c内容随意,保证编译通过就行。
    makefile内容如下:(makefile没有什么实际意义,仅仅为了演示命令前提目标的用法)

    TEST_DIR=dirTest
    all:main.o //规则1
    @echo "this is all"
    main.o : main.c func.o | ${TEST_DIR} //规则2
    @echo "gcc process"
    gcc -c main.c -o $@
    func.o : func.c //规则3
    @echo "func gcc process"
    gcc -c func.c -o $@
    ${TEST_DIR}: //规则4
    @echo "creat the dirTest directory"
    mkdir -p dirTest

    测试1:直接make all


    从make命令的输出log可以看出,五个规则的执行顺序是:规则3 --> 规则4 --> 规则2 --> 规则1。这个顺序,刚刚好证明了第1节中“注2”的说明,正常前提目标(normal prerequisites)优先生成。
    执行make all后,当前路径内容如下:

    测试2:修改func.c的内容,然后再执行make all

    因为func.o是常前提目标(normal prerequisites),则修改了func.c,规则3 --> 规则2 --> 规则1 又重新执行了一遍。

    测试3:在dirTest文件夹里新建一个文件,然后再执行make all

    因为dirTest是命令前提目标(order-only prerequisites),虽然修改了dirTest,但是只有规则1被执行了,规则2并没有被执行。
    可以看出,dirTest的改动,并没有影响规则2的执行。

    测试4:删掉main.o,然后再执行make all

    删掉了main.o后,规则2被执行了。

    from:https://blog.csdn.net/yangjizhen1533/article/details/113681130

  • 相关阅读:
    通过field:global给子元素添加css样式
    TP5 调用邮箱接口
    php数组使用json_encode函数中文被编码成null的原因和解决办法
    UNIX系统上的抓包工具tcpdump常用命令说明
    快速搭建ELK7.5版本的日志分析系统--搭建篇
    Kubernetes实战之部署ELK Stack收集平台日志
    k8s实战之部署Prometheus+Grafana可视化监控告警平台
    Linux防火墙firewalld安全设置
    在zabbix中实现发送带有图片的邮件和微信告警
    用Dockerfile部署zabbix
  • 原文地址:https://www.cnblogs.com/lidabo/p/14818003.html
Copyright © 2020-2023  润新知