你能确定makefile目标的优先级吗?

你能确定makefile目标的优先级吗?,makefile,gnu-make,Makefile,Gnu Make,我有一个非常大和复杂的制造系统,需要几个小时才能完成。我正在研究潜在的优化,我有一个问题,就是是否有可能对某些目标进行优先排序 下面是一个简单的Makefile示例,演示了这个概念: Test%: Prog% #run some post build verification on Prog{n} # -- takes 30min or less on failure... Prog1: A B # do some linking Prog2: B C

我有一个非常大和复杂的制造系统,需要几个小时才能完成。我正在研究潜在的优化,我有一个问题,就是是否有可能对某些目标进行优先排序

下面是一个简单的Makefile示例,演示了这个概念:

Test%: Prog%
    #run some post build verification on Prog{n}
    #  -- takes 30min or less on failure...

Prog1:  A B
    # do some linking

Prog2:  B C
    # do some linking

A B C:
    # take 10 minutes each
然后我就跑

make -j2 Prog1 Test2
然后最快的构建方法是:
B
C
,然后是
Prog2
A
,然后是
Test2
Prog2
。当然,make通常会首先构建
A
B
,这会将我的最终输出延迟10分钟

如果我预先知道
Test2
将成为瓶颈,那么在gnu make中是否有可能优先考虑该目标及其所有依赖关系

为了补充这个问题,假设我正在构建
Test1
Test2
<代码>测试20。那么在这种情况下,我希望其中一个目标——比如说
Test1
,尽快完成,就好像它失败了一样,我希望尽快知道,这样我就可以终止构建,让其他人使用构建机器

我考虑过单独使用make,如下所示:

make Test2 && make Prog1
但是,当测试正在生成时,
Prog1
将不会生成,从而导致生成服务器上的周期浪费。如果我试图以优先顺序并行构建它们:

`make Test2; nice -n -10 make Prog1`
这可能导致在构建
B
时出现争用情况


我还没有找到任何好的解决办法,但我想如果我错过了什么,我会继续问下去。(另外,我不确定这是否应该启用SO或SuperUser——我选择这里是因为它在技术上是关于“编程”的,但请随意更正我,我可以移动它)。

GNU make没有提供任何语法来为目标添加权重。也就是说,当make能够启动下一个作业,并且独立(!)目标
A
B
被解锁(它们的所有依赖项都已满足)并需要重新生成时,则取决于它们在内部make数据库中的顺序,首先选择哪个目标执行

但是您可以使用其他依赖项来实现您的目标。以您的问题为例:

TESTS:=Test1 Test2
$(测试):测试%:进度%
方案1:A B
项目2:B和C
ifdef_优先级_测试2
#确保Prog2->Test2优先级的其他依赖项
A:B:C
恩迪夫
A B C程序1程序2测试1测试2全部:
@回音$@
.虚假:A B C Prog1 Prog2$(测试)全部
测试运行:

$make--trace-j10程序1测试2
生成文件:13:目标“A”不存在
呼应
生成文件:13:目标“B”不存在
回声B
生成文件:13:目标“C”不存在
回声C
A.
B
C
生成文件:13:更新目标“Prog1”的原因:A B
回波程序1
Makefile:13:更新目标“Prog2”的原因:B C
回波程序2
程序1
程序2
Makefile:13:更新目标“Test2”的原因:Prog2
回声测试2
测试2
$make--trace-j10_优先级_TEST2=1 Prog1 TEST2
生成文件:13:目标“B”不存在
回声B
生成文件:13:目标“C”不存在
回声C
B
C
生成文件:13:更新目标“A”的原因:B C
呼应
Makefile:13:更新目标“Prog2”的原因:B C
回波程序2
A.
生成文件:13:更新目标“Prog1”的原因:A B
回波程序1
程序2
Makefile:13:更新目标“Test2”的原因:Prog2
回声测试2
程序1
测试2
这可能需要大量手工制作才能得到你想要的结果。您甚至可能需要编写不同的附加依赖项集,以覆盖不同的
make
调用场景

您可以研究转储GNU make数据库(
make——无内置规则——打印数据库)
),解析它以提取所有目标及其依赖项,并可视化结果图。下面是一个如何在of中生成有向图的示例:

#/usr/bin/perl
使用警告;
严格使用;
开始{
打印“有向图生成\n”;
打印“{\n”;
}
我的$default_目标='???';
我的目标;
而(){
如果(我的($target,$dependencies)=/^([\w_-]+):\s+(.*)/){
#打印“节点${target}\n”;
打印“$\->${target}\n”
对于(拆分(“”,$dependencies));
}elsif(我的($goals)=/^MAKECMDGOALS:=\s+(.+)/){
@目标=分割(“”,$goals);
}elsif(我的($goal)=/^\。默认目标:=\s+(.+)/){
$default_goal=$goal;
}
}
结束{
@目标=($default\u目标)
除非(@目标);
#打印“根$\n”
#对于(@目标);
打印“}\n”;
}
出口0;
对于上述示例,将导致:

$make-n--无内置规则--打印数据库Prog1 Test2>&1| perl dummy.pl
有向图构建
{
A->Prog1
B->Prog1
Prog1->Test1
B->Prog2
C->Prog2
Prog2->Test2
}

我是否正确理解您的问题,即您运行的是串行生成?否则,我无法解释您描述的构建步骤序列。如果是这种情况,那么您可以选择使用依赖顺序,即
T:ab
将触发
A
然后
B
,而
T:ba
将触发
B
然后
A
目标
T
。您需要手工构建您的依赖项,以便在您为
make
设定的目标中,优先级较高的依赖项始终处于第一位。
-j2
意味着它是一个具有两个线程的并行构建。在现实生活中,我在一台8核机器上运行,目标大约为100000个。我没有发现任何迹象表明,例如,对于并行构建,
A
的依赖项必须在
B
的依赖项之前构建。(事实上,在我的测试中,它是在构建最终目标之前构建所有依赖项)我的语句是针对串行构建的。在并行构建中,
make
实例在分叉作业子进程以获取下一个可用作业后立即返回主循环。在递归构建系统中,这意味着如果父
make
实例或子
make
实例是随机的