【问题标题】:Override target in makefile to add more commands?覆盖makefile中的目标以添加更多命令?
【发布时间】:2010-12-11 07:45:00
【问题描述】:

在工作中,我们使用其他 makefile 包含的通用 makefile(通过 include 语句),它有一个通用的“干净”目标,可以杀死一些通用文件。我想在我的新 makefile 中添加到该目标,以便我可以删除一些特定文件,但是如果我在我的 makefile 中添加一个干净的目标,它只会覆盖旧目标。

我知道我可以使用新名称创建一个新目标并将其调用 clean,然后执行其他操作,但为了保持一致性,我希望能够调用 make clean 并让它完成所有操作.

这可能吗?

【问题讨论】:

    标签: makefile


    【解决方案1】:

    我在几家商店都看到过这种做法。最常见的方法是使用双冒号规则,假设您使用的是 GNU make 之类的东西。在你的通用 makefile 中,你会有这样的东西:

    clean::
            # standard cleanup, like remove all .o's:
            rm -f *.o
    

    请注意,clean 后面有 两个 冒号,而不仅仅是一个!

    在您的其他 makefile 中,您只需再次声明 clean,作为双冒号规则:

    clean::
            # custom cleanup, like remove my special generated files:
            rm -f *.h.gen
    

    当您调用 make clean 时,GNU make 将自动运行 clean 规则的这两个“分支”:

    % make clean
    rm -f *.o
    rm -f *.h.gen
    

    它的设置很简单,而且我认为它的组合非常整齐。请注意,特别是因为它是一个双冒号规则,当您为同一个目标定义两个规则时,您不会遇到通常会遇到的“覆盖命令”错误。这就是双冒号规则的意义所在。

    【讨论】:

    • 感谢 Eric,这也可以,但如果可以的话,我宁愿避免修改通用的 makefile。
    • 我只是在寻找那个,就我而言,双冒号是完美的解决方案。非常感谢!
    【解决方案2】:

    您可以编写自己的 clean 并将其作为 common clean 的 preq。

    清洁:myclean 我的清洁: rm 随便

    您的将首先运行。如果出于某种原因您希望先运行 common clean,那么解决方案将更加复杂。

    编辑:

    这是我能看到的在本地规则之前运行通用规则的最佳解决方案:

    include Makefile.common
    
    clean:
        $(MAKE) -f Makefile.common $@
        rm whatever additional things
    

    include 指令是必要的,因为本地 makefile 依赖于公共文件而不是 clean。本地 clean 规则覆盖公共 clean 规则,但在执行额外工作之前调用公共 clean 规则。 (这种覆盖会引起一些警告,这很麻烦;我不知道有什么好的方法可以让它们静音。)

    【讨论】:

    • 看起来有点倒退,需要向公共 makefile 的 clean 目标添加越来越多的 preq。在通用 makefile 中将 clean 目标命名为不同的东西,然后将该目标作为包含 common 的其他 makefile 中的 clean 目标的 preq 似乎既更容易维护,又可以防止通用 makefile 有 preq当子项目消失时消失。将 clean 设为双冒号目标是解决此问题的另一种干净且可预测的方法。
    • @Dave Rawks,你误会了,我写的内容会进入 local makefile,而不是常见的 makefile。此外,OP 说他不想要有两个目标名称。双冒号的想法很聪明,尽管它会涉及修改公共 makefile(并且不允许本地 makefile 覆盖公共规则)。
    • 谢谢,我之前没有意识到这个关系。
    • 如果我想让 'myclean' 在 clean 后运行怎么办?
    • @AleksanderFular:那么,正如我所说,解决方案会更复杂。您这样做是否有真正的原因,或者您只是想提高您的 Make 技能?
    【解决方案3】:

    使用隐式规则:

    existing-target: my-extention
    
    my-extention:
        echo running command 1
        echo running command 2
    

    Very simple make tutorial to ramp up.

    使用 :: 时,您可能会遇到问题,因为当您混合使用单冒号 : 和双冒号 :: 规则时会报错:

    a:
        echo a
    
    a::
        echo aa
    

    将导致:

    . . .
    *** target file `a' has both : and :: entries.  Stop.
    

    【讨论】:

    • 我很好奇你为什么称这条链为隐含规则。
    【解决方案4】:

    似乎通用 makefile 的规则应该称为 common-clean。然后每个主 makefile 都会将它们的 clean 规则声明为

    clean: common-clean
    

    你已经准备好了。

    如果这不是一个选项,您可以查看double colon rules,但它们会引入一系列其他需要考虑的问题。

    【讨论】:

      【解决方案5】:

      添加我为后代看到的另一种可能的解决方案...我知道 OP 对更改通用 makefile 持谨慎态度,但这样的东西可以工作并且涉及的更改很少。

      本地生成文件 1:

      CLEAN=MyExe1 MyExe2
      ....
      include /my/common/makefile
      

      本地生成文件 2:

      CLEAN=MyExe3 MyExe4
      ....
      include /my/common/makefile
      

      通用makefile:

      clean:
           rm -f *.dep *.o *.a $(CLEAN)
      

      基本上,这个想法是在每个本地 makefile 中定义一些变量(在本例中为 CLEAN),其中包含您要删除的所有特定项目。然后通用 makefile 对所有要删除的通用文件类型运行 rm -f,加上通过 CLEAN 变量在每个本地 makefile 中明确标记为删除的任何内容。如果没有具体要删除的内容,只需省略变量声明或将其留空 (CLEAN=)

      所以现在如果我们为本地 makefile 1 运行 make clean,它就会执行

      rm -f *.dep *.o *.a MyExe1 MyExe2
      

      如果我们为本地 makefile 2 运行 make clean,它会执行

      rm -f *.dep *.o *.a MyExe3 MyExe4
      

      【讨论】:

      • 这是一个良好的通用清洁解决方案的起始基础。如果需要同时执行 makefile 1 和 2,也可以使用 += 运算符。
      【解决方案6】:

      对于我们来说,我们定义了一个变量 EXTRAFILESTOCLEAN,然后当 clean 规则运行时,它有一个步骤来删除 EXTRAFILESTOCLEAN 变量中指定的任何内容

      clean:
          rm -f *.o
      ifdef $(EXTRAFILESTOCLEAN)
          rm -f $(EXTRAFILESTOCLEAN)
      endif
      

      如果您将该变量设置为奇怪的值,这可能会导致意外问题,但您可以通过添加前缀或其他测试来防范这些问题。

      【讨论】:

      • 我想我会删除 ifdef 并将变量直接放在第一个 rm 命令上,如果变量扩展为空,这不会改变任何内容。我之所以这么说,是因为我不记得 什么时候 ifdef 被评估了。我怀疑它可能不是在执行规则时而是在解析生成文件时。因此,如果您的变量只是稍后设置,ifdef 将不起作用。
      猜你喜欢
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2018-10-15
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多