Makefile 目标 运行 并行目标并在做更多事情之前等待它们完成
Makefile target running parallel targets and waiting for them to complete before doing more stuff
我正在尝试让 "parent target" 等待 "parallel children targets" 完成,然后再在 "parent target" 的 "body" 中执行某些操作。
在下面的示例中,消息 @echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
应该仅在 在 所有目标 foo-task1
、foo-task2
和 [=18= 之后打印] 已完成。
如果我删除那些 "children targets" 末尾的符号 (&
) 然后它们变成连续的,但这不是预期的行为。它们的行为应该类似于 "thread pool" 或 "process pool"。我事先不知道哪些目标会最后完成,所以我无法从瓶颈目标中删除与号 (&
)。
这些目标表示对远程 REST API 的 HTTP 调用,可能需要不同的时间才能完成。在 foo-parallel
.
中打印最终消息之前,我想等待这些 "parallel REST calls" 看看它们是否成功
这些 "parallel targets" 正在返回 stdout/stderr 所以我希望父目标可以等待它们并在出现错误时失败。
我该怎么做?
foo-task1:
@bash -c 'sleep 1 && echo "task1" &'
foo-task2:
@bash -c 'sleep 1 && echo "task2" &'
foo-task3:
@bash -c 'sleep 2 && echo "task3" &'
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
命令make
版本:
$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
编辑:
这个目标定义略有不同(我更改了 sleep
次只是为了确保消息按延迟顺序而不是代码中的顺序打印):
foo-parallel:
@bash -c 'sleep 5 && echo "task1" & \
sleep 1 && echo "task2" & \
sleep 2 && echo "task3" & \
wait; \
echo "done here!"'
打印:
$ make foo-parallel
task2
task3
task1
done here!
但我需要将所有这些 task1
、task2
和 task3
的逻辑放在同一个目标中。我想将这些任务分成不同的目标。
我想你想使用 -j
选项:
foo-task1:
@sleep 1
@echo "task1"
foo-task2:
@sleep 1
@echo "task2"
foo-task3:
@sleep 2
@echo "task3"
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
和 运行 make -j3 foo-parallel
- make
将 运行 与正确的依赖并行。查看更多 Parallel Execution 部分:
GNU make knows how to execute several recipes at once. Normally, make
will execute only one recipe at a time, waiting for it to finish
before executing the next. However, the ‘-j’ or ‘--jobs’ option tells
make to execute many recipes simultaneously.
如果不使用 make 的 -j
选项,您将无法做到这一点。默认情况下,make 构建一个目标,等待它完成,然后构建下一个目标。只有-j
才会同时支持多个目标运行ning。
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
foo-task1:
@sleep 1 && echo "task1"
foo-task2:
@sleep 1 && echo "task2"
foo-task3:
@sleep 2 && echo "task3"
然后 运行:make -j
或者如果您想限制并行构建的数量,请使用 make -j2
或任意数量。
如果你真的想避免输入 -j
你可以使用递归 make:
foo-parallel:
@$(MAKE) -j foo-task1 foo-task2 foo-task3
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
foo-task1:
@sleep 1 && echo "task1"
foo-task2:
@sleep 1 && echo "task2"
foo-task3:
@sleep 2 && echo "task3"
然而,如果有人调用 make -j
,这可能会导致奇怪的警告。一般来说,我认为最好由调用 make
的人来决定他们想要多少并行性,对于他们的特定系统。
我正在尝试让 "parent target" 等待 "parallel children targets" 完成,然后再在 "parent target" 的 "body" 中执行某些操作。
在下面的示例中,消息 @echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
应该仅在 在 所有目标 foo-task1
、foo-task2
和 [=18= 之后打印] 已完成。
如果我删除那些 "children targets" 末尾的符号 (&
) 然后它们变成连续的,但这不是预期的行为。它们的行为应该类似于 "thread pool" 或 "process pool"。我事先不知道哪些目标会最后完成,所以我无法从瓶颈目标中删除与号 (&
)。
这些目标表示对远程 REST API 的 HTTP 调用,可能需要不同的时间才能完成。在 foo-parallel
.
这些 "parallel targets" 正在返回 stdout/stderr 所以我希望父目标可以等待它们并在出现错误时失败。
我该怎么做?
foo-task1:
@bash -c 'sleep 1 && echo "task1" &'
foo-task2:
@bash -c 'sleep 1 && echo "task2" &'
foo-task3:
@bash -c 'sleep 2 && echo "task3" &'
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
命令make
版本:
$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
编辑:
这个目标定义略有不同(我更改了 sleep
次只是为了确保消息按延迟顺序而不是代码中的顺序打印):
foo-parallel:
@bash -c 'sleep 5 && echo "task1" & \
sleep 1 && echo "task2" & \
sleep 2 && echo "task3" & \
wait; \
echo "done here!"'
打印:
$ make foo-parallel
task2
task3
task1
done here!
但我需要将所有这些 task1
、task2
和 task3
的逻辑放在同一个目标中。我想将这些任务分成不同的目标。
我想你想使用 -j
选项:
foo-task1:
@sleep 1
@echo "task1"
foo-task2:
@sleep 1
@echo "task2"
foo-task3:
@sleep 2
@echo "task3"
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
和 运行 make -j3 foo-parallel
- make
将 运行 与正确的依赖并行。查看更多 Parallel Execution 部分:
GNU make knows how to execute several recipes at once. Normally, make will execute only one recipe at a time, waiting for it to finish before executing the next. However, the ‘-j’ or ‘--jobs’ option tells make to execute many recipes simultaneously.
如果不使用 make 的 -j
选项,您将无法做到这一点。默认情况下,make 构建一个目标,等待它完成,然后构建下一个目标。只有-j
才会同时支持多个目标运行ning。
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
foo-task1:
@sleep 1 && echo "task1"
foo-task2:
@sleep 1 && echo "task2"
foo-task3:
@sleep 2 && echo "task3"
然后 运行:make -j
或者如果您想限制并行构建的数量,请使用 make -j2
或任意数量。
如果你真的想避免输入 -j
你可以使用递归 make:
foo-parallel:
@$(MAKE) -j foo-task1 foo-task2 foo-task3
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
foo-task1:
@sleep 1 && echo "task1"
foo-task2:
@sleep 1 && echo "task2"
foo-task3:
@sleep 2 && echo "task3"
然而,如果有人调用 make -j
,这可能会导致奇怪的警告。一般来说,我认为最好由调用 make
的人来决定他们想要多少并行性,对于他们的特定系统。