【问题标题】:For loop in makefile not workingmakefile中的for循环不起作用
【发布时间】:2018-05-02 22:48:37
【问题描述】:

在我的 makefile 中有:

all:
  for i in {20..50000..10} ; do \
    echo "Computing $$i" ;\
  done

应该在单独的行上分别打印数字 20、30、40、...、50000。

这适用于 Debian oldstable(GNU Make 4.0、GNU Bash 4.3),但不适用于 Debian stable(GNU Make 4.1 和 GNU Bash 4.4.12)。

Debian stable 只打印字符串“{20..50000..10}”。为什么是这样?在 makefile 中编写这个 for 循环的可移植方式是什么?

【问题讨论】:

  • 对我来说,在我将 $$i 替换为 $i 后,它起作用了。你能试试吗?
  • @dmadic 这对我不起作用。我的软件什么都不打印(它可能将$i 视为makefile 变量并打印空字符串)。
  • 你为什么不用seqseq 20 10 50000
  • seq 并不比大括号更标准,因此它增加了一个并非绝对必要的外部依赖项。
  • 大括号是一种 bashism,因此您应该安装 bash - 另一个外部依赖项 :) 参见 MadScientist 的回答 (stackoverflow.com/a/50144927/934599)

标签: bash makefile gnu-make


【解决方案1】:

如果你在 shell 提示符下运行:

/bin/sh -c 'for i in {20..5000..10}; do echo $i; done'

您会发现它并没有像您希望的那样工作。 Make 总是调用/bin/sh(它应该是一个 POSIX shell)来运行配方:如果它使用调用 makefile 的人碰巧使用的任何 shell,这将是可移植性的灾难。

如果你真的想用 bash 语法编写你的 makefile 配方,那么你必须通过添加明确要求:

SHELL := /bin/bash

到你的makefile。

【讨论】:

    【解决方案2】:

    坚持使用与 POSIX 兼容的循环:

    all:
      i=20; while [ "$$i" -le 50000 ]; do \
        echo "Computing $$i"; i=$$((i + 10));\
      done
    

    【讨论】:

    • 就我而言,它适用于循环条件[ "$$i" -le 5000 ];。此外,使用冒号:,它始终与$i = 20 进行无限循环。没有冒号,它可以完美地工作。是这些错别字还是我应该担心便携性?
    • 是的,只是拼写错误。我不习惯在 Makefile 中编写扩展 shell,所以忘记了双 $$。最初,我使用算术表达式 ($(( i = i + 10))) 进行赋值,然后才发现它不必要地复杂,但忘记删除 : 以将其转换为常规 shell 赋值。
    猜你喜欢
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 2013-12-31
    • 2011-03-08
    • 2015-07-05
    • 2016-01-18
    相关资源
    最近更新 更多