我有一个类似的makefile:
file1 = "path/to/some/file"
header="col1;col2;col3"
$(file1):
some steps to create the file
call_perl_script:$(file1)
${perl} script.pl in=header
标头当前是硬编码的,它也在生成的file1中。我需要从file1获取标头。不知何故,我改变了它,如
file1 = "path/to/some/file"
$(file1):
some steps to create the file
$(eval header="$(shell $(sed) -n "/^col1;col2;col3/Ip" $(file1))")
call_perl_script:$(file1)
${perl} script.pl in=$(header)
它工作正常,但想知道它是否是使用目标特定变量的正确方法。在与eval一起使用之前,标头不会传递其值。 此外,如果我在call_perl_script目标中打印$(标题)它正确打印但如果我使用“if”条件来检查变量是否为空并设置默认值,则它不起作用。它设置“if”块中标题的值,而不管“sed”输出中标题中的值。
call_perl_script:$(file1)
${echo} $(header)
ifeq "$(header)" ""
$(eval header="col1;col2;col3")
endif
${perl} script.pl in=$(header)
答案 0 :(得分:1)
我不认为特定于目标的变量会对您有所帮助,因为它们通常是静态的。例如,如果您需要为一个特定C文件静音一种类型的警告,则可以添加foo.o: CFLAGS+=-Whatever
之类的规则。
您遇到的问题是$(eval header=...)
仅在$(file1)
生效时执行。如果它已经存在,那么目标将不会重建,并且header
将不会被设置。
在Makefile中执行此操作的更自然的方法是将标头保存到单独的文件中。这样,只要$(file)
更改,它就会自动重新生成:
.DELETE_ON_ERROR:
file = foo.txt
call_perl_script: $(file) $(file).header
echo perl script.pl in="$(shell cat $(file).header)"
$(file):
echo "col1;col2;col3;$$(head -c1 /dev/random)" > $(file)
%.header: %
sed -n '/^col1;col2;col3/p' $< > $@
clean::
rm -f $(file)
rm -f *.header
导致:
echo "col1;col2;col3;$(head -c1 /dev/random)" > foo.txt
sed -n '/^col1;col2;col3/p' foo.txt > foo.txt.header
perl script.pl in="col1;col2;col3;?"
然而,这仍然是一个问题,所以对于长期可维护性,您可能需要考虑更新script.pl
来解析标题本身。