这是我的Makefile的简化用例。我想要做的是使用这些文件的名称并创建相应的.d和.hpp文件。但是,出于某种原因,我无法做到。
XML_DATA_FILES := a.xml b.xml c.xml d.xml
build:
@for var in $(XML_DATA_FILES); do \
echo "$(basename $$var)";\
$(eval var1 = $(basename $$var)) \
echo "$(join var1,.hpp)"; \
echo "$(join var1,.d)"; \
done
我运行make时得到的输出如下
a.xml
var1.hpp
var1.d
b.xml
var1.hpp
var1.d
c.xml
var1.hpp
var1.d
d.xml
var1.hpp
var1.d
但是对于所有四个xml文件输入,我想要的是a.d, a.hpp
等等。
我已经提到了this问题和GNU Manual,但到目前为止它还没有帮助。我怎么能实现这个目标?
答案 0 :(得分:1)
这里有很多问题:)。但是,从根本上说,你不能将basename
和eval
之类的make函数组合在像for
这样的shell循环中,并期望它能做任何有用的事情。 Make总是扩展所有make变量的整个配方并且首先运行,然后它将整个扩展的字符串传递给shell运行,然后它等待shell完成。
考虑:运行其for
循环的shell如何将var
的当前值传递回来,以便每次都通过shell循环,以便make可以正常运行功能等?这是不可能的。
您需要使用 only shell构造编写整个循环,以及在整个配方中具有相同值的简单make变量。
然而,这对于makefile来说是无用的,因为你只有一个目标可以完成所有事情。为什么不写一个shell脚本?没有必要为此使用make。如果你想用make方式编写它,你需要声明目标和先决条件并创建模式规则,如下所示:
XML_DATA_FILES := a.xml b.xml c.xml d.xml
OUTPUTS := $(foreach X,$(XML_DATA_FILES:.xml=),$X.d $X.hpp)
build: $(OUTPUTS)
%.d %.hpp: %.xml
echo "$*.d $*.hpp"
当然,既然你不能确切地说出真正的命令,我可以确定这是正确的;如果你实际上有两个不同的命令,一个构建.d文件,一个构建.hpp文件,你应该创建两个不同的模式规则。