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

时间:2016-03-13 02:54:59

标签: makefile gnu-make

我有一个makefile,它通过一个构建链,比如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

这不是一个非常好的解决方案,因为我必须为每个模块A,B,...重复特定于目标的变量definiton“moduleA.z:var = moduleA”。也许我可以使用 pattern < / em> - 特定变量而不是?我会想到像

这样的东西
%.z: var=%

但是,当我尝试这样的事情时,右边的%被解释为字面百分号。

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

moduleA.z: moduleB.y

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

2 个答案:

答案 0 :(得分:0)

如果我没有误会,您需要$(var),每%.y%.z目标, 目标的基名。如果我完成你的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

然后从清洁输出是:

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

答案 1 :(得分:0)

以下解决方案取自this post

$(foreach module,$(modules),$(eval $(module).z: var = $(module)))