使用GNU make,是否可以创建一组在使用“--jobs”选项时永远不会同时安排的目标?
为了使这更具体一点,请考虑格式为
的makefilep1: ...deps... # no parallelization conflicts (can run at the same time as p*, e*)
...rules...
p2: ...deps... # no parallelization conflicts (can run at the same time as p*, e*)
...rules...
p3: ...deps... # no parallelization conflicts (can run at the same time as p*, e*)
...rules...
e1: ...deps... # cannot run at same time as any other e*
...rules...
e2: ...deps... # cannot run at same time as any other e*
...rules...
e3: ...deps... # cannot run at same time as any other e*
...rules...
我需要做的主要事情是确保e1,e2和e3永远不会同时处理,因为它们在资源有限的嵌入式设备上做了一些工作。如果它们中的多个同时执行,它们会崩溃。 p1,p2和p3可以与任何东西并行执行,包括任何e *作业。
请注意,实际的makefile有几千个目标,其依赖关系树大约有10个级别,所以我希望有一种方法可以做到这一点:(a)不需要串行运行make和(b)保留在makefile中编码依赖树的好处。
答案 0 :(得分:6)
您可以使用“flock”在独占锁下运行“e”规则。有关详细信息,请参阅man flock(1)。例如,而不是
e2: deps
my_cmd foo bar
你可以拥有
e2: deps
flock .embedded-device-lock -c my_cmd foo bar
然后会发生所有“e”目标并行启动(可能),但实际命令将以串行方式执行。
答案 1 :(得分:2)
这不是一个完美的解决方案,但您可以使用仅限订单的先决条件对e *目标强制执行特定排序:
e1: ...deps...
...commands...
e2: ...deps... | e1
...commands...
e3: ...deps... | e2 e1
...commands...
管道符号“|”之后的先决条件如果e1或e2已经改变,它们不会强制e3更新,但它们确实要求e1和e2的所有命令在e3的命令开始之前完成运行。
这样做的缺点是它对这些互斥的先决条件强加了特定的顺序,而不是让make
选择订单,但实际上你可以手动找出合理的订单。