不良行为:makefile在解析时执行shell脚本

时间:2013-06-04 09:29:07

标签: shell makefile gnu-make

我有一个脚本可以为我的c ++项目生成一些源文件。 脚本本身如下:

echo "total args: $#"
if [ $# -eq 7 ]; then
echo "in if"
$1/../tools/xsde [...]
fi

当运行目标smt_response_files并且文件.xsd.files.make不存在或者它早于.xsd文件时,它从makefile执行。

$(smt_path) ?= .
$(smt_build) ?= $(smt_path)/build
$(common_build) ?= ../build

-include $(smt_build)/$(smt_gen_response_xsd).files.make

smt_response_files : | $(smt_build)/$(smt_gen_response_xsd).files.make
    @:

$(smt_build)/$(smt_gen_response_xsd).files.make : $(smt_gen_response_path)/$(smt_gen_response_xsd)
    @$(common_build)/generate_xml.sh $(smt_path) $(smt_gen_response_path) $(smt_gen_response_xsd) xml::$(smt_gen_response_class) make_list $(smt_build)/$(smt_gen_response_xsd).files.make smt_response_files

问题:在我清理项目并删除* .xsd.files.make后,在解析makefile时重新创建它们(我已经翻译了俄语的输出):

Reading make-files...
total args: 7
in if
...
total: 2193
Updating makefile goals...
 File `smt_clean' does not exist.
... (and a normal clean proccess goes next)

干净的目标会删除自动生成的文件,但我不认为它们是在此过程中创建的。

据我所知,唯一的方法是排除重新创建* .xsd.files.make的规则,这些规则包含在makefile中:

inc_gen ?= true
ifeq ($(MAKECMDGOALS),clean)
    inc_gen := false
endif
# ... other excluded targets here (smt_clean, etc.)

ifeq ($(inc_gen),true)
$(smt_build)/$(smt_gen_response_xsd).files.make : $(smt_gen_response_path)/$(smt_gen_response_xsd)
    @$(common_build)/generate_xml.sh $(smt_path) $(smt_gen_response_path) $(smt_gen_response_xsd) xml::$(smt_gen_response_class) make_list $(smt_build)/$(smt_gen_response_xsd).files.make smt_response_files
endif

还有其他方法可以解决我的问题吗?也许存在一些更通用的方法?

提前感谢大家。

1 个答案:

答案 0 :(得分:0)

从技术上讲,它们不是在解析makefile时构建的。请参阅GNU make手册,如何重新制作Makefile 部分。一旦make完成解析所有makefile,它将执行一个pass,确保所有包含的makefile都是最新的,将它们全部视为目标并尝试重建它们。这就是你所看到的。

如果任何makefile已更改,那么make将从头开始重新执行,以便它可以重新读取更新的makefile的内容。

您拥有的解决方案(您检查clean目标的位置,以及您不希望强制重建makefile的任何其他目标,如果发现它您要么不执行{{1}或者你没有提供重建makefile的规则)是推荐的解决方案。

请注意,includeclean等规则只是惯例:它们与allfoo等规则无关。所以,让他们不知道要特别对待他们。