【问题标题】:make : rule call rulemake : 规则调用规则
【发布时间】:2012-01-28 14:55:17
【问题描述】:

在 makefile 中,我可以从另一个规则中调用一个规则吗?

类似于:

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"
        rule1

【问题讨论】:

    标签: makefile


    【解决方案1】:

    要么使用依赖关系,要么使用递归来从一个规则连接到另一个规则。

    依赖关系会像这样完成(尽管顺序会有所不同):

    rule1:
            echo "bye"
    rule2:
            date
    rule3: rule1
            @echo "hello"
    

    递归make会像这样完成(虽然它确实涉及一个子进程):

    rule1:
            echo "bye"
    rule2:
            date
    rule3:
            @echo "hello"
            $(MAKE) rule1
    

    两者都不完美;事实上,如果你建立一个循环,使用递归 make 你可能会遇到严重的问题。您可能还应该添加一个.PHONY 规则,以便将上面的这些规则标记为合成,这样目录中的流浪rule1(等)就不会引起混淆。

    【讨论】:

      【解决方案2】:

      Makefile 不是程序化的; “规则”不像函数。也就是说,您可以指定一个规则是另一个规则的先决条件:

      rule1:
          @echo "Rule 1"
      
      rule2: rule1
          @echo "Rule 2"
      

      如果你使用make rule2,你应该会看到:

      Rule 1
      Rule 2
      

      【讨论】:

      • 令人沮丧的是,您无法从中获得“规则 2\n规则 1”
      • @Tomalak:取决于你对“令人沮丧”的定义!一旦 OP 接受规则不是程序功能,那么就没有什么可沮丧的了。
      • 它没有回答问题。它应该输出规则 2,然后输出规则 1。这是作者想要实现的。
      • @nosbor - OP 没有说明需要什么具体输出。
      【解决方案3】:

      GNU Make 中有两个高级函数可以做到这一点,尽管它应该只在情有可原的情况下使用。此 SO 在 google 中评分最高。

      更推荐使用规则先决条件,但有时您需要一个后置先决条件。

      GNU Make Call function

      GNU Make Eval function

      从本质上讲,Eval 允许您动态构建目标,而 Call 允许创建类似“定义”的函数。

      【讨论】:

        【解决方案4】:

        只需添加一条带有您想要的顺序的新规则..

        rule1:
                echo "bye"
        rule2:
                date
        rule3:
                @echo "hello"
        
        rule4: rule3 rule1
        

        【讨论】:

        • 恕我直言,这是一个比其他答案更好的解决方案。
        • 简单——我喜欢。
        • 这不会强加排序。它只会保证 rule1 和 rule3 在 rule4 之前完成,不保证排序
        • 我赞同 CristianDonosoC 的评论。由于这里的 rule1 和 rule3 之间没有排序,因此执行并行 make(例如make -j2)会给您不确定的执行顺序。
        • 有一种方法可以按指定顺序运行先决条件:gnu.org/software/make/manual/html_node/Prerequisite-Types.html – 使用此规则,rule4 应为:rule4: | rule3 rule1
        【解决方案5】:

        一个简单的方法是:

        ifeq (a, b)
            build_target:=one
        else
            build_target:=two
        endif
        
        mytarget: $(build_target)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多