5

使用 GNU make,是否可以在使用“--jobs”选项时创建一组永远不会同时安排的目标?

背景:

为了使这更具体一点,请考虑以下形式的生成文件

p1: ...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)保留的好处在生成文件中编码依赖树。

4

2 回答 2

6

您的一种选择是使用“flock”在排他锁下运行“e”规则。有关详细信息,请参见 manflock(1)。例如,而不是

e2: deps
    my_cmd foo bar

你可以有

e2: deps
    flock .embedded-device-lock -c my_cmd foo bar

然后发生的事情是所有“e”目标都由 make 并行启动(可能),但实际命令将串行执行。

于 2009-02-23T17:38:55.337 回答
3

这不是一个完美的解决方案,但您可以使用仅订购的先决条件对 e* 目标施加特定的顺序:

e1: ...deps...
    ...commands...
e2: ...deps... | e1
    ...commands...
e3: ...deps... | e2 e1
    ...commands...

管道符号“|”之后的先决条件 仅订购:如果 e1 或 e2 已更改,它们不会强制更新 e3,但它们确实要求 e1 和 e2 的所有命令在启动 e3 的命令之前完成运行。

这样做的缺点是它为这些互斥的先决条件强加了特定make的顺序,而不是让选择顺序,但实际上您可能可以手动找出合理的顺序。

于 2009-02-23T17:48:38.340 回答