Makefile 为目标扩展生成通配符

Makefile 为目标扩展生成通配符,makefile,gnu-make,Makefile,Gnu Make,我的项目中有一个目标,可以有大量不同的扩展,也有一个没有扩展的目标: target target.a target.b ... target.x 我希望能够使用一个通配符为扩展指定目标,因此我不需要为每个目标扩展指定一个配方。我想我可以通过模式规则这样做: target%: VAR=1 $(MAKE) MY_VARS += $(VAR) $@ 但是,当我运行make时,这不会生成目标。有谁能建议一种方法,我可以做这个通配符吗?你有三个问题。首先,不能将特定于目标的变量与配方

我的项目中有一个目标,可以有大量不同的扩展,也有一个没有扩展的目标:

target
target.a
target.b
...
target.x
我希望能够使用一个通配符为扩展指定目标,因此我不需要为每个目标扩展指定一个配方。我想我可以通过模式规则这样做:

target%: VAR=1
         $(MAKE) MY_VARS += $(VAR) $@

但是,当我运行make时,这不会生成目标。有谁能建议一种方法,我可以做这个通配符吗?

你有三个问题。首先,不能将特定于目标的变量与配方组合在同一规则定义中。其次,模式必须至少匹配一个字符,因此模式
target%
与目标
target
不匹配。最后,在命令行上提供变量赋值时,不能在变量名、赋值运算符和值之间使用空格:它们必须是同一个单词

你可以用这个:

targe%: VAR=1
targe%:
        $(MAKE) MY_VARS+='$(VAR)' $@

你有三个问题。首先,不能将特定于目标的变量与配方组合在同一规则定义中。其次,模式必须至少匹配一个字符,因此模式
target%
与目标
target
不匹配。最后,在命令行上提供变量赋值时,不能在变量名、赋值运算符和值之间使用空格:它们必须是同一个单词

你可以用这个:

targe%: VAR=1
targe%:
        $(MAKE) MY_VARS+='$(VAR)' $@

您还可以对目标执行
target.%:
,而不是删除最后一个字符。您不能编写一个既包含隐式规则又包含显式规则的规则;你必须写两条不同的规则。过去有一个bug,在某些有限的情况下允许这样做,而在其他情况下则不允许这样做,但这个bug在GNU make 3.82中已经修复。现在,如果您尝试这样做,GNU make将直接失败或打印一条关于不推荐使用的语法的警告。有趣的。。。我在发布之前就试过了,但我现在运行的是3.81,所以它没有抱怨。为什么这会被认为是一个bug?好吧,读一下这个。显然,在4.1版中,混合隐式和显式规则的能力已经恢复,尽管似乎对此存在一些争论。在任何情况下,我的建议都是不可移植的,虽然我认为它看起来更好,但应该避免。这是一个不正确的实现意外,从未完全起作用:例如,在任何版本的GNU make中,您都不能编写
target.%target:
并将显式目标放在第二位,而不是第一位。而且,只有当您没有先决条件或先决条件是明确的(没有模式)时,它才会起作用。此外,尽管该语法在4.1及以上版本中再次被接受(因为较旧的Linux内核makefiles使用该语法),但它始终会打印一个无法禁用的大警告。您也可以对目标执行
target.%:
,而不是删除最后一个字符。您不能编写一个既包含隐式规则又包含显式规则的规则;你必须写两条不同的规则。过去有一个bug,在某些有限的情况下允许这样做,而在其他情况下则不允许这样做,但这个bug在GNU make 3.82中已经修复。现在,如果您尝试这样做,GNU make将直接失败或打印一条关于不推荐使用的语法的警告。有趣的。。。我在发布之前就试过了,但我现在运行的是3.81,所以它没有抱怨。为什么这会被认为是一个bug?好吧,读一下这个。显然,在4.1版中,混合隐式和显式规则的能力已经恢复,尽管似乎对此存在一些争论。在任何情况下,我的建议都是不可移植的,虽然我认为它看起来更好,但应该避免。这是一个不正确的实现意外,从未完全起作用:例如,在任何版本的GNU make中,您都不能编写
target.%target:
并将显式目标放在第二位,而不是第一位。而且,只有当您没有先决条件或先决条件是明确的(没有模式)时,它才会起作用。此外,尽管该语法在4.1及更高版本中再次被接受(因为较旧的Linux内核makefiles使用该语法),但它总是打印一个无法禁用的大警告。