给定一个路径列表,我想分离出makefile中列表中每个元素的目录部分和文件名部分。如下所示
MYLIST = \
/home/folder1/folder2/fileName1 \
/home/folder3/folder4/fileName2 \
/home/folder5/folder6/fileName3 \
MYLIST:
@for elems in $(MYLIST); \
do \
echo $(dir $$elems); \
echo $(notdir $$elems); \
done
但是变量解除引用存在问题。我得到输出为
./
home/folder1/folder2/fileName1
./
home/folder3/folder4/fileName2
./
home/folder5/folder6/fileName3
而我希望它是
/home/folder1/folder2/
fileName1
/home/folder3/folder4/
fileName2
/home/folder5/folder6/
fileName3
不知何故$(@ D)和$(@ F)没有给出列表中的第一个所有dir和fileName部分。 有人可以告诉你如何解决这个问题吗?
答案 0 :(得分:4)
这是因为你混合了两个扩展阶段。在调用shell来执行规则之前,所有make变量和函数都会被扩展。因此$$elems
变为$elems
,然后此字符串将用作$(dir ...)
和$(notdir ...)
函数的输入。此字符串不包含/
,因此dir
返回./
,notdir
返回$elems
。最后,在shell中执行以下命令。
@for elems in /home/folder1/folder2/fileName1 /home/folder3/folder4/fileName2 /home/folder5/folder6/fileName3; \
do \
echo ./; \
echo $elems; \
done
William Pursell通过使用shell函数给出了可能的解决方法。另一种可能性是在执行规则之前执行扩展,如:
MYLIST = \
/home/folder1/folder2/fileName1 \
/home/folder3/folder4/fileName2 \
/home/folder5/folder6/fileName3 \
MYDIRS = $(dir $(MYLIST))
MYFILES = $(notdir $(MYLIST))
MYLIST:
@for elems in $(MYDIRS) $(MYFILES); \
do \
echo $$elems; \
done
$(@D)
和$(@F)
没有提供所有dir和fileName部分,因为它们提供了当前规则调用目标的文件和目录。每个时刻只有一个目标。但是,您可以使用这些自动变量来执行您想要的操作,方法是让make
执行循环,而不是shell,如下所示:
MYLIST = \ /home/folder1/folder2/fileName1 \ /home/folder3/folder4/fileName2 \ /home/folder5/folder6/fileName3 \ all: $(MYLIST) $(MYLIST): @echo $(@D) @echo $(@F)
答案 1 :(得分:1)
我建议使用shell而不是make:
MYLIST = \ /home/folder1/folder2/fileName1 \ /home/folder3/folder4/fileName2 \ /home/folder5/folder6/fileName3 MYLIST: for elems in $(MYLIST); \ do \ echo $$(dirname $$elems); \ echo $$(basename $$elems); \ done
当然,在这一点上,回声是多余的,你也可以这样做:
for elems in $(MYLIST); \ do \ dirname $$elems; \ basename $$elems; \ done
答案 2 :(得分:0)
我现在找到了另一种方法......
MYLIST = \
/home/folder1/folder2/fileName1 \
/home/folder3/folder4/fileName2 \
/home/folder5/folder6/fileName3
MYLIST:
@$(foreach ELEMS,$(MYLIST), echo $(dir $(ELEMS)); echo $(notdir $(ELEMS));)
不知道我之前是怎么错过的。