如何在makefile

时间:2017-11-17 19:39:59

标签: loops makefile scripting gnu-make

考虑下面的makefile:

CFG_DIR = /media/test/
all:
    for list in $(CFG_DIR); do \
      echo "list is $$list"; \
      for file in $(shell ls $${list}); do \
        echo "file is $$file"; \
      done \
    done

执行make时,会生成以下结果:

list is /media/test/
file is Makefile

不打印/ media / test /目录的目录列表,而是打印执行make命令的当前目录的目录列表。

似乎在shell函数中,$$列表被评估为空值。如果有人可以指出在shell函数中访问循环变量的正确方法,那将会很有帮助。

1 个答案:

答案 0 :(得分:0)

您不能在make函数中使用shell变量。

考虑make如何工作:当它想要运行配方命令FIRST时,它会扩展命令中的所有make变量和函数,然后它获取生成的字符串并将其传递给shell运行,然后它等待shell退出。如果shell以成功代码(0)退出,则表示“yay it working!”如果shell以失败代码(非0)退出,那么make表示“boo it failed。”

这是你的食谱:

for list in $(CFG_DIR); do \
  echo "list is $$list"; \
  for file in $(shell ls $${list}); do \
    echo "file is $$file"; \
  done \
done

因此,FIRST make将扩展包括所有变量和函数。您有一个$(CFG_DIR)变量和一个$(shell...)函数。变量只是/media/test/。当make扩展函数时,它会看到传递给shell的命令是ls ${list}。所以make run:

/bin/sh -c 'ls ${list}'

好吧,除非你在你的环境中将shell变量list设置为空字符串,否则shell会执行ls并返回当前目录的所有内容。然后,将其替换为您的配方,并将结果交给shell运行:

/bin/sh -c 'for list in /media/test; do
  echo "list is $list";
  for file in <current-wd-files>; do
    echo "file is $file";
  done
done'

因此。故事的道德:在配方命令中,你已经已经在一个shell中。所以你应该从不使用$(shell ...) make函数。它只会导致混乱和悲伤。

你应该使用shell语法,因为你已经有了一个shell:

all:
      for list in $(CFG_DIR); do \
          echo "list is $$list"; \
          for file in `ls $${list}`; do \
            echo "file is $$file"; \
          done \
        done