makefile函数中的变量未正确展开?

makefile函数中的变量未正确展开?,makefile,Makefile,这是一个玩具制作文件。 我想创建文件“a”、“b”、“c”以及“a.out”、“b.out”、“c.out” 当我使用“make-n”版本GNU make 4.1测试运行它时, 实际执行的命令是: echo a > c echo c > c.out echo b > c echo c > c.out echo c > c echo c > c.out 然而,预期结果是: echo a > a echo a > a.out echo b >

这是一个玩具制作文件。 我想创建文件“a”、“b”、“c”以及“a.out”、“b.out”、“c.out”

当我使用“make-n”版本GNU make 4.1测试运行它时, 实际执行的命令是:

echo a > c
echo c > c.out
echo b > c
echo c > c.out
echo c > c
echo c > c.out
然而,预期结果是:

echo a > a
echo a > a.out
echo b > b
echo b > b.out
echo c > c
echo c > c.out

有人可以帮助解释Makefile的行为或如何修复此脚本吗?谢谢。

下面是我试图回答这个问题的答案,它附带了一个冗长的代码修复程序。我之所以在这里发帖是为了等待更好的答案

从GNUMakeManual(),目标和先决条件立即得到评估,配方部分被推迟

在我的示例中,
$$(out):$$(In)
将立即计算。这正是我所期望的。但是
echo$$(in)>$$(out)
稍后会展开。此时,
$$(in)
变为
c
$$(out)
变为
c.out
。但那不是我想要的

在我看来,一个棘手的解决办法是使用特定于目标的变量()。现在,Makefile如下所示:

LIST=a b c
all: $(addsuffix .out,$(LIST))

define FUN
  in := $(1)
  out := $(1).out
  $$(in) : in=$(1)
  $$(in) :
    echo $(1) > $$(in)
  $$(out) : $$(in)
    echo $$(in) > $$(out)
endef
$(foreach p,$(LIST),\
  $(eval $(call FUN,$(p))))
特定于目标的变量在
$$(in):in=$(1)
中指定。
但是,当配方部分中有多个变量时,您必须添加多个特定于目标的变量,这看起来不太好。

下面是我试图回答这个问题的尝试,它附带了一个冗长的代码修复程序。我之所以在这里发帖是为了等待更好的答案

从GNUMakeManual(),目标和先决条件立即得到评估,配方部分被推迟

在我的示例中,
$$(out):$$(In)
将立即计算。这正是我所期望的。但是
echo$$(in)>$$(out)
稍后会展开。此时,
$$(in)
变为
c
$$(out)
变为
c.out
。但那不是我想要的

在我看来,一个棘手的解决办法是使用特定于目标的变量()。现在,Makefile如下所示:

LIST=a b c
all: $(addsuffix .out,$(LIST))

define FUN
  in := $(1)
  out := $(1).out
  $$(in) : in=$(1)
  $$(in) :
    echo $(1) > $$(in)
  $$(out) : $$(in)
    echo $$(in) > $$(out)
endef
$(foreach p,$(LIST),\
  $(eval $(call FUN,$(p))))
特定于目标的变量在
$$(in):in=$(1)
中指定。
但是,当配方部分中有多个变量时,您必须添加多个特定于目标的变量,这看起来不太好。

为什么不到处使用
$1
变量,而不是创建新变量?没有规定必须在展开式中使用变量。你可以这样写:

define FUN
  $1 :
        echo $1 > $1
  $1.out : $1
        echo $1 > $1.out
endef
如果您不想这样做,可以这样使用:

define FUN
  $1 :
        echo $$@ > $$@
  $1.out : $1
        echo $$< > $$@
endef
define FUN
  $1.out : FOO = $(some complex thing)

  $1 :
        echo $$(FOO) > $$@
  $1.out : $1
        echo $$(FOO) from $$< > $$@
endef

为什么不到处使用
$1
变量,而不是创建新变量?没有规定必须在展开式中使用变量。你可以这样写:

define FUN
  $1 :
        echo $1 > $1
  $1.out : $1
        echo $1 > $1.out
endef
如果您不想这样做,可以这样使用:

define FUN
  $1 :
        echo $$@ > $$@
  $1.out : $1
        echo $$< > $$@
endef
define FUN
  $1.out : FOO = $(some complex thing)

  $1 :
        echo $$(FOO) > $$@
  $1.out : $1
        echo $$(FOO) from $$< > $$@
endef

在这个简化的示例中,您的答案非常有效。但对于真正的问题,我确实希望找到一种在
define中使用变量的方法。。。endef
没有一长串特定于目标的变量。你知道解决办法吗?谢谢。在这个简化的例子中,你的答案非常有效。但对于真正的问题,我确实希望找到一种在
define中使用变量的方法。。。endef
没有一长串特定于目标的变量。你知道解决办法吗?谢谢