【问题标题】:Conditional in makefile that redefines variable?重新定义变量的makefile中的条件?
【发布时间】:2012-06-13 23:05:51
【问题描述】:

我的 makefile 中有一个变量,我想 unset 或重新定义,以便目标 abc 使用正确的 MY_VARIABLE 值(或根本不使用)他们各自的makefile。

如果我使用以下内容运行make foo

export MY_VARIABLE := 'false'
foo: prep_foo dist
prep_foo:
    $(shell export MY_VARIABLE='true')
    echo ${MY_VARIABLE}
dist: a b c
a: 
    make -C a/src
b: 
    make -C b/src
c: 
    make -C c/src

我得到这个输出:

export MY_VARIABLE='true'
echo 'false'
false
...

如果我使用以下 makefile 运行 make foo

export MY_VARIABLE := 'false'
foo: prep_foo dist
prep_foo:
    $(shell unset MY_VARIABLE)
    echo ${MY_VARIABLE}
dist: a b c
a: 
    make -C a/src
b: 
    make -C b/src
c: 
    make -C c/src

我得到以下输出:

make: unset: No such file or directory
echo 'false'
false
...

如何在指定目标时取消设置或重新定义MY_VARIABLE(如foo,在这种情况下)?

编辑

这是我想避免的情况:

dist: a b c 
foo: a_foo b_foo c_foo
a:
    make -C a/src
...
a_foo
    make -C a_foo/src

我只希望a 目标对我的特定变量使用不同的值,以便在该目标的makefile 中以不同方式处理编译。

此外,我似乎无法在目标中使用 exportunset 变量。例如:

dist: a b c 
foo: a_foo b_foo c_foo
a:
    make -C a/src
...
a_foo:
    export MY_VARIABLE='true'; make -C a/src

如果我尝试这样做,我会在export MY_VARIABLE='true' 行上收到类似于以下错误的内容(如果我尝试使用unset,则类似):

Makefile:16: *** unterminated variable reference.  Stop.

这是否有助于澄清我想要做什么?

编辑 2

我尝试了一个touch-es 文件的目标,并尝试运行子目标的makefile(检查文件是否存在):

foo: prep_foo
prep_foo:
    touch a/src/.foo
    make -C a/src

当我尝试通过make foo 运行它时,我收到以下错误:

Makefile:14: *** commands commence before first target.  Stop.

如果我从prep_foo 中删除make 语句,那么我可以touch 文件而不收到错误消息,但我无法触发创建a 目标,所以这似乎没有帮助。

以下产生相同的commands commence before first target 错误消息:

foo: prep_foo a
prep_foo:
    touch a/src/.foo

是否有使用touch 将状态传达给子目标的示例?

【问题讨论】:

  • 不同目标中的命令不能相互影响。您甚至无法保证目标的顺序(例如,在您的情况下,make -j 将尝试一次运行所有目标)。你不能使 abc 不同,这取决于你是尝试 make foo 还是只是 make dist
  • 我认为这与我的问题无关。当我调用父目标时,我只希望所有子目标有条件地为特定变量使用不同的值。我并不真正关心在父目标中评估子目标的顺序。这有助于澄清事情吗?

标签: bash unix build makefile sh


【解决方案1】:

Makefile 中的目标之间通信的常用方式是通过文件。只需touch 一个目标中的文件并在另一个目标中检查它。这可以帮助您解决问题吗?

【讨论】:

  • 不,我将使用该方法产生的错误消息来编辑我的问题。
  • @AlexReynolds:我无法复制您的问题。哪一行是 14 号?
  • 为简洁起见,我的 makefile 与我发布的不同。它很长。您有时间发布一个使用touch 的工作示例吗?
【解决方案2】:

不要忘记make 中的每一个shell 执行都是在一个新进程中完成的。试图摆弄像这样的配方的环境变量并没有多大意义 - 您在任何给定行中修改的环境在 shell 死后,在执行下一行之前 已经消失

你也许可以像这样完成这项工作:

a:
    unset MY_VARIABLE; $MAKE -C a/src

a:
    $MAKE MY_VARIABLE=foo -C a/src

【讨论】:

  • 我正在寻找一种在一个目标中设置变量的干净方法,然后将其传递给其他目标。如何在不设置自定义目标的情况下做到这一点(即如何避免为aa_foobb_foo等编写目标来处理每种情况)?
  • 您的建议似乎不起作用。如果我将unset MY_VARIABLE; echo ${MY_VARIABLE} 放在prep_foo 中,我仍然会在运行make foo 时得到MY_VARIABLE 的旧值。
  • 哦,该死的。我知道我应该先测试一下,但它似乎很清楚......你能否在问题描述中添加一两句话关于a vs a_foo 目标,然后我将删除这个答案?这似乎太有用了——尽管我不完全理解为什么你会有两种不同的方式来构建a:一种通过foo,另一种没有foo。 (你能解释一下吗?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 2012-01-14
  • 2010-10-07
相关资源
最近更新 更多