【问题标题】:Make: Pattern in target/pattern-specific variable definitionsMake:目标/模式特定变量定义中的模式
【发布时间】:2016-12-18 07:40:43
【问题描述】:

我有一个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、...重复目标特定变量定义 "moduleA.z: var=moduleA"。也许我可以使用 pattern - 特定变量?我猜是这样的

%.z: var=%

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

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

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.z 将通过 moduleB.y --> moduleB.z 构建。现在var 变量应该在第一个构建链中设置为“moduleA”,但在第一步,moduleB.x --> moduleB.y,使用$*$(basename $@) 会给我“moduleB”取而代之。

【问题讨论】:

  • 简单的echo $* 可以接受吗?也就是说,如果变量总是等价于基本名称,则根本不需要单独的变量。
  • 不接受使用$*。请查看编辑。
  • 你是说moduleA 应该优先于moduleB?这开始看起来像the XY problem。你如何使用var
  • 不,moduleA 通常不应优先。但是,按照我的示例,如果我执行make all 甚至make moduleA.z,则var 变量将在构建moduleA.z 的第一步中设置为“moduleB”(即moduleB.x --> moduleB .y)。对于后面的步骤,var 将采用正确的值。

标签: makefile gnu-make


【解决方案1】:

如果我没有误会,您希望 $(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

然后从 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

【讨论】:

    【解决方案2】:

    以下解决方案取自this post

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 2016-11-25
      • 1970-01-01
      相关资源
      最近更新 更多