【问题标题】:Force a makefile rule to be executed based on value of a makefile variable根据 makefile 变量的值强制执行 makefile 规则
【发布时间】:2018-02-15 05:02:31
【问题描述】:

我正在尝试编写一个在命令行参数更改时强制执行的生成规则。我将此命令行参数分配给生成文件变量 ARG

当我第一次执行makefile时,dep.mk的规则被执行。但是当命令行参数改变时,不会触发这条规则

这是我的代码:

temp.mk的内容

ARG := $(basename $(filter %.ext,$(MAKECMDGOALS)))

# I want this rule to depend on value of ARG
# if the value from commandline changes then the rule should trigger dep.mk rule
# if I replace dep.mk rule with the below commented line , then it goes into infinite loop

#dep.mk : $(ARG)

dep.mk :  
    mkdir -p $(dir $@)
    $(shell touch $@)
    @echo "Creating dep.mk"

include dep.mk

%.ext : 
    @echo "in ext rule"

.PHONY : $(ARG)

调用makefile的命令:

make -f temp.mk foo.ext

输出:

mkdir -p ./
Creating dep.mk
in ext rule

下次我使用不同的参数执行 makefile 时:

make -f temp.mk bar.ext

输出:

in ext rule

预期输出:

mkdir -p ./
Creating dep.mk
in ext rule

如果我直接依赖$(ARG),makefile 将进入无限循环。谁能帮我解决这个问题?

【问题讨论】:

  • 你为什么要这样工作?这里有实际的依赖关系吗? Make 将检查文件系统并为相对于它们的依赖项丢失或过时的目标运行配方。
  • 在我试图解决的问题中,我希望 dep.mk 保存一些使用传递的命令行参数制定的信息。这些信息将在以后用于一些进一步的操作
  • 如果dep.mk 真的是一个目录,那么你想依赖于那个目录in 的东西。一个常见的技巧是touch dep.mk/.$@$@ 标记为已制作,并有一个类似%: dep.mk/.% 的规则,但我真的仍然不假装理解你真正想要完成的事情。
  • 对于make -f temp.mk foo.ext,没有与foo 匹配的规则,这是$(ARG) 的扩展值。 make -f temp.mk bar.ext 也是如此。

标签: makefile command-line-arguments infinite-loop


【解决方案1】:

在第一次运行时,dep.mk 不存在并且是因为 include dep.mk 的行而构建的。在随后的运行中,它存在并且没有依赖项来检查它,因此没有理由重新制作它。

将其声明为.PHONY,因此无论如何都会构建它:

ARG := $(basename $(filter %.ext,$(MAKECMDGOALS)))

dep.mk :  
    mkdir -p $(dir $@)
    $(shell touch $@)
    @echo "Creating dep.mk"

include dep.mk

%.ext : 
    @echo "in ext rule"

.PHONY : $(ARG) dep.mk

然而,这不是你想要的,因为你希望 dep.mk 依赖于 $(ARG)。但是make 怎么知道 dep.mk 是针对哪个目标构建的?您必须为每个目标保留单独的 *-dep.mk 文件,这样:

ARG := $(basename $(filter %.ext,$(MAKECMDGOALS)))

$(ARG)-dep.mk :  
    mkdir -p $(dir $@)
    $(shell touch $@)
    @echo "Creating $@"

include $(ARG)-dep.mk

%.ext : 
    @echo "in ext rule"

.PHONY : $(ARG)

当然,一旦构建,这个 Makefile 将永远不会再次构建 *-dep.mk,除非您包含一个删除所有 *-dep.mk 的 clean: 目标或指定真正的依赖关系,当其中一些依赖项强制重建时变得太老了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多