【问题标题】:How to include path prefix in GNU Make pattern rule如何在 GNU Make 模式规则中包含路径前缀
【发布时间】:2015-04-22 13:57:20
【问题描述】:

考虑以下几点:

%.foo: %.bar
    echo $< > $@ 

假设我们有一个文件1.bar,执行的命令就是echo 1.bar &gt; 1.foo。然而,当% 包含一个路径,而不仅仅是一个文件名时,它开始变得很挑剔。我的问题是我想在%.bar 之前添加另一条路径,该模式完全被破坏了。即,当 %.barnice/path/1.bar 时,这变得不可能:

%.foo: /project/something/%.bar
    echo $< > $@

这将运行,但它执行 echo nice/path//project/something/1.bar &gt; 1.foo 而不是 echo /project/something/nice/path1.bar &gt; 1.foo

原因在于 make 如何执行其模式规则。来自文档:

当目标模式不包含斜杠时(通常不包含),文件名中的目录名在与目标前缀和后缀进行比较之前从文件名中删除。 [...] 目录被忽略只是为了找到要使用的隐含规则,而不是在应用该规则时。因此,‘e%t’匹配文件名 src/eat,以‘src/a’作为词干。当先决条件转换为文件名时,主干中的目录被添加到前面,而主干的其余部分被替换为“%”。带有先决条件模式“c%r”的词干“src/a”给出了文件名 src/car

有什么方法可以针对特定规则关闭此功能?

【问题讨论】:

  • 你只是想在配方中使用裸文件名吗?如果是这样,请改用$(notdir $&lt;)$(&lt;F)
  • 你的问题没有说明情况。如果您将此规则写为显式规则,它会是什么样子?你想要的扩展目标路径是什么,你想要的扩展前提路径是什么?
  • 扩展的先决条件路径应该是/project/something/nice/path1.bar。它使nice/path//project/something/1.bar。也就是说,它将 % 拆分为前缀 (nice/path) 和词干 (1.bar),然后将 /project/something/ 添加到词干,然后将前缀添加到该词干。我希望它停止在前缀和词干中拆分 %
  • 你没有回答我的问题。您尝试构建的 target 的完整路径名是什么?只是1.foo 没有路径吗?是nice/path/1.foo吗?我不明白nice/path 来自哪里。 Make从目标开始,从目标确定主干,从目标确定先决条件。因此,如果您的目标是您所说的1.foo,那么先决条件的词干怎么可能是nice/path/1
  • 也许如果您提供一个简短的完整示例来实际显示问题的实际效果,那么查看发生了什么会更简单。

标签: makefile gnu-make


【解决方案1】:

您可能想阅读How Patterns Match:

当目标模式不包含斜杠时(通常不包含),文件名中的目录名在与目标前缀和后缀进行比较之前从文件名中删除。在将文件名与目标模式进行比较之后,目录名以及结束它们的斜线被添加到从模式规则的先决条件模式和文件名生成的先决条件文件名中。忽略目录只是为了找到要使用的隐含规则,而不是在应用该规则时。因此,‘e%t’匹配文件名 src/eat,以‘src/a’作为词干。当先决条件转换为文件名时,主干中的目录被添加到前面,而主干的其余部分被替换为“%”。带有先决条件模式“c%r”的词干“src/a”给出了文件名 src/car。

上面解释了为什么 nice/path/ 被添加到前提条件 /project/something/1.bar 之前。


一种解决方法是在规则中使用完整的文件名,例如:

${CURDIR}/nice/path/%.foo: /project/something/%.bar    

【讨论】:

  • 我知道 为什么 会这样做(因此我在问题中引用了完全相同的文档),但我该如何关闭它呢?原因是在实际用例中我必须使用它,因为我的路径取决于文件名(这是一个有点复杂的文件夹结构)。
  • @Gx1sptDTDa 哎呀,错过了您的报价。为什么不能使用完整的文件名?
猜你喜欢
  • 2022-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多