makefile 执行另一个目标
我有一个类似这样的 makefile 结构:
all :
compile executable
clean :
rm -f *.o $(EXEC)
我意识到在运行“make all”之前,我一直在终端中运行“make clean”,然后运行“clear”。在我尝试筛选讨厌的 C++ 编译错误之前,我喜欢有一个干净的终端。所以我尝试添加第三个目标:
fresh :
rm -f *.o $(EXEC)
clear
make all
这有效,但是这运行了 make 的第二个实例(我相信)。有没有一种正确的方法可以在不运行第二个 make 实例的情况下获得相同的功能?
I have a makefile structured something like this:
all :
compile executable
clean :
rm -f *.o $(EXEC)
I realized that I was consistently running "make clean" followed by "clear" in my terminal before running "make all". I like to have a clean terminal before I try and sift through nasty C++ compilation errors. So I tried to add a 3rd target:
fresh :
rm -f *.o $(EXEC)
clear
make all
This works, however this runs a second instance of make (I believe). Is there a right way to get the same functionality without running a 2nd instance of make?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上你是对的:它运行另一个 make 实例。
一个可能的解决方案是:
通过调用
make fresh
,您首先获得clean
目标,然后获得运行clear
的clearscreen
> 最后是完成这项工作的all
。编辑 8 月 4 日
如果使用 make 的
-j
选项进行并行构建,会发生什么情况?有一种方法可以修复顺序。来自制造手册,第 4.2 节:
因此,makefile 变为
EDIT Dec 5
运行多个 makefile 实例并不是什么大问题,因为任务中的每个命令都将是一个 子 shell 无论如何。但是您可以使用调用函数来获得可重用的方法。
Actually you are right: it runs another instance of make.
A possible solution would be:
By calling
make fresh
you get first theclean
target, then theclearscreen
which runsclear
and finallyall
which does the job.EDIT Aug 4
What happens in the case of parallel builds with make’s
-j
option?There's a way of fixing the order. From the make manual, section 4.2:
Hence the makefile becomes
EDIT Dec 5
It is not a big deal to run more than one makefile instance since each command inside the task will be a sub-shell anyways. But you can have reusable methods using the call function.
您已经有了一个顺序解决方案,可以将其重写为:
这是正确且非常安全的方法。
在 GNU make 中使用适当的依赖关系图可以顺序执行目标:
上述规则定义了以下依赖关系图:
fresh
_all
<-_clear< /code> <-
_clean
保证以下配方执行顺序:clean 配方
、clear 配方
、recipe for all
。可以使用以下方法与多个目标共享配方:将
脚本与上述概念合并会产生:
使用来自 https://github.com/pkoper/mk/ 你可以写:
或者更好:
You already have a sequential solution which could be rewritten as:
This is correct and a very safe approach.
Sequential target execution is possible in GNU make with a proper dependency graph:
The above rules define the following dependency graph:
fresh
<-_all
<-_clear
<-_clean
which guarantees the following recipe execution order:Recipe for clean
,Recipe for clear
,Recipe for all
.Recipes can be shared with multiple targets using:
Merging your script with the above concepts results in:
With syntactic sugar using
chains.mk
from https://github.com/pkoper/mk/ you can write:Or better:
如果您从“fresh”目标中删除了
make all
行:您只需运行命令
make fresh all
,该命令将作为make fresh; 执行;全部制作
。有些人可能认为这是 make 的第二个实例,但它肯定不是 make 的子实例(make 中的 make),而这正是您的尝试似乎导致的结果。
If you removed the
make all
line from your "fresh" target:You could simply run the command
make fresh all
, which will execute asmake fresh; make all
.Some might consider this as a second instance of make, but it's certainly not a sub-instance of make (a make inside of a make), which is what your attempt seemed to result in.