makefile 执行另一个目标
Posted
技术标签:
【中文标题】makefile 执行另一个目标【英文标题】:makefile execute another target 【发布时间】:2011-03-17 01:54:07 【问题描述】:我有一个类似这样结构的生成文件:
all :
compile executable
clean :
rm -f *.o $(EXEC)
我意识到在运行“make all”之前,我一直在终端中运行“make clean”,然后是“clear”。在尝试筛选令人讨厌的 C++ 编译错误之前,我喜欢有一个干净的终端。所以我尝试添加第三个目标:
fresh :
rm -f *.o $(EXEC)
clear
make all
这可行,但是这会运行第二个 make 实例(我相信)。是否有正确的方法可以在不运行第二个 make 实例的情况下获得相同的功能?
【问题讨论】:
我不确定这是否应该是一个单独的问题,但为什么调用嵌套的 make 命令不好? 【参考方案1】:实际上你是对的:它运行另一个 make 实例。 一个可能的解决方案是:
.PHONY : clearscr fresh clean all
all :
compile executable
clean :
rm -f *.o $(EXEC)
fresh : clean clearscr all
clearscr:
clear
通过调用make fresh
,您首先会获得clean
目标,然后是运行clear
的clearscreen
,最后是完成这项工作的all
。
8 月 4 日编辑
在使用 make 的 -j
选项进行并行构建的情况下会发生什么?
有一种固定顺序的方法。来自制作手册,第 4.2 节:
但是,有时您会遇到这样的情况,即您希望对要调用的规则施加特定的顺序,而不是在执行这些规则之一时强制更新目标。在这种情况下,您想要定义仅订单的先决条件。可以通过在先决条件列表中放置管道符号 (|) 来指定仅订单先决条件:管道符号左侧的任何先决条件都是正常的;右侧的任何先决条件都是仅订购的:目标:正常先决条件|仅订购的先决条件
正常的先决条件部分当然可能是空的。此外,您仍然可以为同一目标声明多行先决条件:它们被适当地附加。请注意,如果您将同一个文件声明为普通先决条件和仅订单先决条件,则普通先决条件优先(因为它们是纯订单先决条件行为的严格超集)。
因此makefile变成了
.PHONY : clearscr fresh clean all
all :
compile executable
clean :
rm -f *.o $(EXEC)
fresh : | clean clearscr all
clearscr:
clear
12 月 5 日编辑
运行多个 makefile 实例并不是什么大不了的事,因为任务中的每个命令无论如何都是sub-shell。但是您可以使用call function 来拥有可重用的方法。
log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)
install:
@[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
command1 # this line will be a subshell
command2 # this line will be another subshell
@command3 # Use `@` to hide the command line
$(call log_error, "It works, yey!")
uninstall:
@[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
....
$(call log_error, "Nuked!")
【讨论】:
@sas4740:基本上.PHONY :
之后的所有内容都被视为始终执行的某个关键字,而非虚假目标则旨在成为文件。
@fantastory,不,我认为他们是独立的。 t2
将取决于 t0
、t1
和 t3
。如果您需要这个,您应该按照t2
的要求输入t3
,按照t3
和t0
的要求按照t1
的要求输入t1
。这意味着 3 个不同的规则。但是,您应该验证这一点。我不是 100% 确定。
“仅订购的先决条件”是独立的
我看不出“干净”在“全部”之前执行的保证在哪里?事实上,你把它们从 |不会使它们按顺序执行。仅订单依赖意味着在此类操作之后不需要更新目标。它与依赖元素的排序无关......或者?
你是对的@CygnusX1,order-only依赖与按一定顺序执行依赖无关;仅在引用它的目标之前对依赖项进行排序。这个答案的EDIT Aug 4
部分是错误的。【参考方案2】:
如果您从“新鲜”目标中删除了 make all
行:
fresh :
rm -f *.o $(EXEC)
clear
您可以简单地运行命令make fresh all
,它将以make fresh; make all
执行。
有些人可能会认为这是 make 的第二个实例,但它肯定不是 make 的子实例(make 中的 make),这正是您的尝试似乎导致的结果。
【讨论】:
make -j12 fresh all
失败了。不要破坏并行制作!以上是关于makefile 执行另一个目标的主要内容,如果未能解决你的问题,请参考以下文章
如果另一个配方在 Makefile 中创建目标,如何跳过目标的配方