Makefile Make:目标/模式特定变量定义中的模式

Makefile Make:目标/模式特定变量定义中的模式,makefile,gnu-make,Makefile,Gnu Make,我有一个生成文件,它通过一个构建链,比如moduleA.x-->moduleA.y-->moduleA.z,依次为许多模块a、B、。。。我想要一个变量var在整个构建链中为每个模块获取当前正在构建的模块名称的值。目前,一个有效的解决方案是使用特定于目标的变量,如下所示: modules = moduleA moduleB moduleC moduleA.z: var=moduleA moduleB.z: var=moduleB moduleC.z: var=moduleC all: $(ad

我有一个生成文件,它通过一个构建链,比如moduleA.x-->moduleA.y-->moduleA.z,依次为许多模块a、B、。。。我想要一个变量
var
在整个构建链中为每个模块获取当前正在构建的模块名称的值。目前,一个有效的解决方案是使用特定于目标的变量,如下所示:

modules = moduleA moduleB moduleC

moduleA.z: var=moduleA
moduleB.z: var=moduleB
moduleC.z: var=moduleC

all: $(addsuffix .z, $(modules))

$(addsuffix .z, $(modules)): %.z: %.y
    echo $(var)
    # Build .z from .y

$(addsuffix .y, $(modules)): %.y: %.x
    echo $(var)
    # Build .y from .x
moduleA.z: moduleB.y
这不是一个很好的解决方案,因为我必须对每个模块a、B……重复特定于目标的变量定义“moduleA.z:var=moduleA”。。。。也许我可以用特定于模式的变量来代替?我猜是这样的

%.z: var=%
但是,当我尝试类似的操作时,右边的%被解释为一个文字百分比符号

编辑 我上面的例子不太完整。在规则中简单地使用
$*
$(basename$@)
并不是一个解决方案,因为我的模块实际上并不独立。也就是说,我可以有这样一个额外的依赖项:

modules = moduleA moduleB moduleC

moduleA.z: var=moduleA
moduleB.z: var=moduleB
moduleC.z: var=moduleC

all: $(addsuffix .z, $(modules))

$(addsuffix .z, $(modules)): %.z: %.y
    echo $(var)
    # Build .z from .y

$(addsuffix .y, $(modules)): %.y: %.x
    echo $(var)
    # Build .y from .x
moduleA.z: moduleB.y

当我现在
make all
在只有moduleB.x发生变化的情况下,moduleB.z和moduleA.z都将被构建,如下所示:第一个moduleA.z将通过链moduleB.x-->moduleB.y,moduleA.y+moduleB.y-->moduleA.z构建。然后将通过moduleB.y-->moduleB.z构建moduleB.z。现在,在第一个构建链中,
var
变量应该设置为“moduleA”,但在第一步中,moduleB.x-->moduleB.y,使用
$*
$(basename$@)
将给我“moduleB”代替。

如果我没有误解,您希望
$(var)
,per
%.y
.z
目标,成为 目标的basename。如果我像这样完成您的makefile:

modules = moduleA moduleB moduleC

moduleA.z: var=moduleA
moduleB.z: var=moduleB
moduleC.z: var=moduleC

%.x:
    touch $@

all: $(addsuffix .z, $(modules))

$(addsuffix .z, $(modules)): %.z: %.y
    echo $(var)
    # Build .z from .y

$(addsuffix .y, $(modules)): %.y: %.x
    echo $(var)
    # Build .y from .x

clean:
    rm -f *.x
然后从clean开始,输出为:

touch moduleA.x
echo moduleA
moduleA
# Build .y from .x
echo moduleA
moduleA
# Build .z from .y
touch moduleB.x
echo moduleB
moduleB
# Build .y from .x
echo moduleB
moduleB
# Build .z from .y
touch moduleC.x
echo moduleC
moduleC
# Build .y from .x
echo moduleC
moduleC
# Build .z from .y
在这种情况下,您可以免除
var
赋值,如:

modules = moduleA moduleB moduleC

%.x:
    touch $@

all: $(addsuffix .z, $(modules))

$(addsuffix .z, $(modules)): %.z: %.y
    echo $(basename $@)
    # Build .z from .y

$(addsuffix .y, $(modules)): %.y: %.x
    echo $(basename $@)
    # Build .y from .x

clean:
    rm -f *.x

如果我没有误解的话,您希望
$(var)
,per
%.y
%.z
目标 目标的basename。如果我像这样完成您的makefile:

modules = moduleA moduleB moduleC

moduleA.z: var=moduleA
moduleB.z: var=moduleB
moduleC.z: var=moduleC

%.x:
    touch $@

all: $(addsuffix .z, $(modules))

$(addsuffix .z, $(modules)): %.z: %.y
    echo $(var)
    # Build .z from .y

$(addsuffix .y, $(modules)): %.y: %.x
    echo $(var)
    # Build .y from .x

clean:
    rm -f *.x
然后从clean开始,输出为:

touch moduleA.x
echo moduleA
moduleA
# Build .y from .x
echo moduleA
moduleA
# Build .z from .y
touch moduleB.x
echo moduleB
moduleB
# Build .y from .x
echo moduleB
moduleB
# Build .z from .y
touch moduleC.x
echo moduleC
moduleC
# Build .y from .x
echo moduleC
moduleC
# Build .z from .y
在这种情况下,您可以免除
var
赋值,如:

modules = moduleA moduleB moduleC

%.x:
    touch $@

all: $(addsuffix .z, $(modules))

$(addsuffix .z, $(modules)): %.z: %.y
    echo $(basename $@)
    # Build .z from .y

$(addsuffix .y, $(modules)): %.y: %.x
    echo $(basename $@)
    # Build .y from .x

clean:
    rm -f *.x

以下解决方案取自:


以下解决方案取自:


是否可以简单地
echo$*
接受?也就是说,如果变量始终与basename相等,则根本不需要单独的变量。使用
$*
是不可接受的。请参见编辑。您是说一般来说,
moduleA
应该优先于
moduleB
?这开始看起来像。如何使用
var
?不,
moduleA
通常不应优先使用。但是,按照我的示例,如果我执行
makeall
或甚至
makemodulea.z
,则在构建moduleA.z(即moduleB.x-->moduleB.y)的第一步期间,
var
变量将设置为“moduleB”。对于后面的步骤,
var
将采用正确的值。只需
echo$*
即可接受吗?也就是说,如果变量始终与basename相等,则根本不需要单独的变量。使用
$*
是不可接受的。请参见编辑。您是说一般来说,
moduleA
应该优先于
moduleB
?这开始看起来像。如何使用
var
?不,
moduleA
通常不应优先使用。但是,按照我的示例,如果我执行
makeall
或甚至
makemodulea.z
,则在构建moduleA.z(即moduleB.x-->moduleB.y)的第一步期间,
var
变量将设置为“moduleB”。对于后面的步骤,
var
将采用正确的值。