嵌套for循环在makefile中不起作用

时间:2017-11-17 13:50:02

标签: shell makefile gnu-make

我正在尝试使用嵌套for循环来搜索和复制makefile中其中一个目标的配方中的一些文件:

DIR = $(DIR_A) $(DIR_B)

install:
      for dirs in $(DIR); do \
        for file in $(shell find $(dirs) -type f -and -not -path "*/.svn*" | sed -e "s|$(dirs)||"); do \
        folder=$${file%/*}; \
          $(INSTALL) -d $(DEST_DIR)$$folder/log; \
          $(INSTALL) $(dirs)/$$file $(DEST_DIR)$$folder/log; \
        done \
      done

然而,$(dirs)变量总是在第二个for循环中计算为空,并且当前工作目录被传递给" find"而不是来自$(DIR)的第一个目录路径。

有人可以建议我是否遗漏了什么?

感谢。

2 个答案:

答案 0 :(得分:1)

find命令中的$(dirs)正在通过make扩展为未设置的make变量dirs,因而是空字符串。要引用shell变量,您需要转义$

 for file in $$(find $${dirs} -type f -and \
      -not -path "*/.svn*" | sed -e "s|$${dirs}||"); do

但不要这样做。明确列出要安装的文件要清晰得多。如果有很多,可以编写一个脚本来生成Makefile。你正在做的是一个脆弱的混乱。

答案 1 :(得分:0)

你犯了几个错误,你会发现几乎不可能把它们解决为l; ong,因为你坚持试图一次性解决它们。

让我们分阶段尝试。假设您的DIR_ADIR_Bnorthsouth。在命令行上,如果您尝试这样做:

for dirs in north south; do echo $dirs; done

您将获得正确的输出:

north
south

如果您将其作为makefile规则尝试:

install:
    for dirs in $(DIR); do echo $$dirs; done

再次,它正常工作。

如果您尝试使用makefile配方:

install:
    for dirs in $(DIR); do \ for file in $(shell ls $$dirs); do \ echo "file is $$file"; \ done \ done

失败,因为在将$(shell ...)命令传递给shell之前,当for尚未分配值时,Make会扩展dirs命令。构造合理shell命令的一种方法是使用反引号:

for dirs in north south; do for file in `ls $dirs`; do  echo "file is $file";  done  done

这适用于命令行。围绕它构建的makefile规则:

install:
    for dirs in $(DIR); do for file in `ls $$dirs`; do  echo "file is $$file";  done  done

也有效。

这应该足以让你重写你的makefile。