我正在尝试使用嵌套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)的第一个目录路径。
有人可以建议我是否遗漏了什么?
感谢。
答案 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_A
和DIR_B
为north
和south
。在命令行上,如果您尝试这样做:
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。