如何在make文件中途添加一个假目标

时间:2015-03-10 17:05:51

标签: makefile gnu-make

我正在研究一个项目的预先存在的,工作的,复杂的makefile,它将在多个操作系统上构建和部署代码。

我正在为构建过程查看一些单独的IDE支持(Visual Studio)(即已经完成了一半的make),因此需要为部署操作插入虚假目标,以便旧流程( make all)仍然有效,包括deloy步骤,但make deploy将为使用IDE的用户执行最终部署步骤。

不熟悉make,我很难看到make如何允许这样的入口点,如果是,如何实现它。

目前的代码有:

$(BUILT_INS): git$X
    $(QUIET_BUILT_IN)$(RM) $@ && \
    ln $< $@ 2>/dev/null || \
    ln -s $< $@ 2>/dev/null || \
    cp $< $@

其操作是部署步骤。

从概念上讲,我认为我需要

.PHONY: deploy
$(BUILT_INS): git$X
  deploy

deploy:
    $(QUIET_BUILT_IN)$(RM) $@ && \
    ln $< $@ 2>/dev/null || \
    ln -s $< $@ 2>/dev/null || \
    cp $< $@

这显然是不对的,因为虚假的目标不能成为一种行动。

总结;如何在makefile中创建一个入口点来执行规则的操作? (一个关键的愿望是避免重复动作代码)

1 个答案:

答案 0 :(得分:2)

你&#34;概念上&#34;解决方案比使用目标作为一个配方有更多的问题(你正确,赢得了工作,但你可以通过使用$(MAKE) deploy作为调用递归make的配方来解决);另一件事就是:

$(BUILT_INS):
        ... using $@ ...

表示为BUILT_INS变量中的每个单词运行该配方一次,并且每次将自动变量$@分配给该单词(目标)。

您的替代品:

deploy:
        ... using $@ ...

完全不同:它运行配方一次$@的值设置为deploy。不会工作。

您问题的简单答案是,您只需声明一个新目标deploy,列出您希望作为先决条件运行的目标:

.PHONY: deploy
deploy: $(BUILT_INS)

现在,当您运行make deploy时,它会尝试构建BUILT_INS目标,并为每个目标运行安装规则。

然而,我怀疑这对你来说是一个问题,取决于git$X先决条件是什么......它可能会导致你的其余makefile的很大一部分运行。但是,你不能提供任何相关的信息,所以我不能说。

ETA 果然,git$X是个问题。因此,您似乎希望VS生成git$X文件(大概是git.exe)。然后你想运行make deploy来复制它。这里的诀窍是在使用git$X目标时保持make重建deploy。你可以这样做;用以下内容替换构建git$X的规则:

.PHONY: deploy
deploy: $(BUILT_INS)

ifeq (,$(filter deploy,$(MAKECMDGOALS)))
git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) git.o \
            $(BUILTIN_OBJS) $(LIBS)
endif

这会创建一个新的目标deploy,这取决于BUILT_INS目标,如上所示。然后,我附上规则以在测试中创建git$X,以便在运行make deploy时未定义该规则。现在让我们根本不知道如何构建git$X,所以如果它不存在,那么make deploy将会失败,但如果它确实存在则make会复制它,而不会尝试重建它。