第一次运行时忽略规则

时间:2014-04-08 11:59:39

标签: linux makefile

SO

我无法找到为什么第一次运行'make'时没有调用这些行但是下次调用它们:

sb_path = sb
sb_src := $(sb_path)/src
sb_build := $(sb_path)/build
ifndef DO_NOT_GENERATE_COMMIT_INFO
commit_sb: | $(sb_bin)
        @$(sb_build)/generate-commit-info $(sb_path)

$(sb_src)/last_git_commit_info.h: | commit_sb ;
endif

我只是很好奇,因为没有文件generate-commit-info文件,并且当我第二次调用它时会崩溃,但它会在第一次尝试时编译我的程序。

我在本地计算机上使用脚本将ssh上的源代码复制到另一台机器并在那里运行compile.sh脚本:

...
scp -r $sbfolder/build $sbfolder/Makefile "$buildserver:$root/$curdate"
check_retcode
scp -r $sbfolder/sb/Makefile "$buildserver:$root/$curdate/sb/"
...
ssh $buildserver "$root/compile.sh $curdate $debug"

compile.sh:

# fix Makefile: we don't have git installed here
#DO_NOT_GENERATE_COMMIT_INFO=true

#now we can compile sb
curdir="/home/tmp/kamyshev/sb_new/$1"
cd $curdir
check_retcode
t_path=$curdir
debug=$2
config=RELEASE
if [[ debug -eq 1 ]]; then
        config=DEBUG
fi
echo "building sb... CONFIG=$config"
make -j2 CONFIG=$config
check_retcode

如您所见,DO_NOT_GENERATE_COMMIT_INFO=true已被注释掉。所以当我第一次调用make或脚本时(无论是从远程脚本还是从命令行的myselft),我都没有看到为什么代码没有运行的原因。

你有线索吗?

关于Etan Reisner评论的更新:

commit_sb target被选中,它不存在,所以它的规则正在运行并且它会更新last_git_commit_info.h。因此它强制更新.h文件。它还给了我一个.PHONY目标commit_sb,所以我可以通过调用make commit_sb直接完成。

generate-commit-info还会在$(sb_bin)文件夹中创建一个文件。

我的另一个猜测是,您正在谈论组织此代码的更好方法。 我可以直接使用以下规则更新last_git_commit_info.h

commit_sb $(sb_src)/last_git_commit_info.h: FORCE | $(sb_bin)
    @$(sb_build)/generate-commit-info $(sb_path)

FORCE:

1 个答案:

答案 0 :(得分:1)

感谢我提问的评论者,我做了一些额外的研究:我试图做一个最小的完整例子。这导致了我的答案。

我的代码生成依赖项文件(查看-MMD中的SB_CXXFLAGS命令):

# just example - in real Makefile these are calculated on the fly
sb_deps := file1.d file2.d [...]

# rules with dependances of .o files against .h files
-include $(sb_deps)

SB_CXXFLAGS = $(CXXFLAGS) [...] -MMD
# compile and generate dependency info;
$(sb_obj)/%.o:$(sb_src)/%.cpp
    $(CXX) $(SB_CXXFLAGS) $< -o $@

当我第一次运行make时没有*.d个文件,因此没有*.cpp取决于last_git_commit_info.h文件,并且不应用该规则。 在随后的运行中,依赖关系规则出现在*.d个文件之一中,执行规则并得到错误。

更新:这不直接涉及问题,但这是编写这些规则的更好方法:

ifndef DO_NOT_GENERATE_COMMIT_INFO
commit_sb $(sb_src)/last_git_commit_info.h: FORCE | $(sb_bin)
    @$(sb_build)/generate-commit-info $(sb_path)

FORCE:
endif