Skip to content

Commit 0af073d

Browse files
committed
pbuild: support generated build requires
1 parent 3036e27 commit 0af073d

4 files changed

Lines changed: 88 additions & 27 deletions

File tree

PBuild/Checker.pm

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,4 +889,35 @@ sub build {
889889
return ('building', $job);
890890
}
891891

892+
#
893+
# Store the generated buildreq list into the package data
894+
#
895+
sub set_genbuildreqs {
896+
my ($ctx, $p, $file) = @_;
897+
my $pkg = $p->{'pkg'};
898+
my $genbuildreqs = ($ctx->{'genbuildreqs'} ||= {});
899+
my $filecontent = $file ? PBuild::Util::readstr($file, 1) : undef;
900+
if (defined $filecontent) {
901+
my $verifymd5 = $p->{'verifymd5'} || $p->{'srcmd5'};
902+
$genbuildreqs->{$pkg} = $p->{'genbuildreqs'} = [ Digest::MD5::md5_hex($filecontent), [ split("\n", $filecontent) ], $verifymd5 ]
903+
} else {
904+
delete $p->{'genbuildreqs'};
905+
delete $genbuildreqs->{$pkg};
906+
}
907+
}
908+
909+
#
910+
# Wait for a building job to finish, return undef if no job is building
911+
#
912+
sub waitjob {
913+
my ($ctx, $builders) = @_;
914+
my @building = map {$_->{'job'}} grep {$_->{'job'}} @$builders;
915+
return undef unless @building;
916+
my $job = PBuild::Job::waitjob($ctx->{'opts'}, @building);
917+
for (@$builders) {
918+
delete $_->{'job'} if $_->{'job'} && $_->{'job'} == $job;
919+
}
920+
return $job;
921+
}
922+
892923
1;

PBuild/Expand.pm

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,7 @@ sub expand_deps {
126126
$p->{'dep_expanded'} = \@deps;
127127
return;
128128
}
129-
if ($p->{'genbuildreqs'}) {
130-
push @deps, @{$p->{'genbuildreqs'}};
131-
}
129+
push @deps, @{$p->{'genbuildreqs'}->[1]} if $p->{'genbuildreqs'};
132130
my @edeps;
133131
if ($cross) {
134132
my @native;

PBuild/Job.pm

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ sub updatelines {
8080
}
8181

8282
#
83-
# Wait for one or more build jobs to finish
83+
# Wait for a build job to finish
8484
#
8585
sub waitjob {
8686
my ($opts, @jobs) = @_;
87+
die("waitjob called with no jobs\n") unless @jobs;
8788
local $| = 1;
8889
my $oldmsg;
8990
while (1) {
@@ -442,9 +443,6 @@ sub finishjob {
442443
print $ll if $ll;
443444
die("fatal build error, see $buildroot/.build.log for more information\n");
444445
}
445-
if ($ret == 3) {
446-
$ret = 1; # map badhost to build failure
447-
}
448446

449447
rename_build_result($vm, $buildroot) if $ret == 0 || $ret == 9;
450448

@@ -454,8 +452,25 @@ sub finishjob {
454452
$ret = 1;
455453
}
456454

457-
if ($ret == 9) {
458-
die("XXX: dynamic buildreqs not implemented yet");
455+
if ($ret != 3 && -e "$buildroot/.build.packages/OTHER/_generated_buildreqs") {
456+
my $genbuildreqs;
457+
if (-s "$buildroot/.build.packages/OTHER/_generated_buildreqs" > 100000) {
458+
PBuild::Util::appendstr("$buildroot/.build.log", "\n_generated_buildreqs size error\n");
459+
$ret = 1;
460+
} else {
461+
$genbuildreqs = PBuild::Util::readstr("$buildroot/.build.packages/OTHER/_generated_buildreqs");
462+
if ($genbuildreqs =~ /[^\n\040-\176]/s) {
463+
PBuild::Util::appendstr("$buildroot/.build.log", "\n_generated_buildreqs contains invalid characters\n");
464+
$genbuildreqs = undef;
465+
$ret = 1;
466+
}
467+
}
468+
if (defined($genbuildreqs) && Digest::MD5::md5_hex($genbuildreqs) ne (($p->{'genbuildreqs'} || [])->[0] || '')) {
469+
return ('genbuildreqs', {'_generated_buildreqs' => "$buildroot/.build.packages/OTHER/_generated_buildreqs"});
470+
}
471+
}
472+
if ($ret == 3) {
473+
$ret = 1; # map badhost to build failure
459474
}
460475
if ($ret) {
461476
my $result = { '_log' => "$buildroot/.build.log" };

pbuild

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,17 @@ if (-s "$builddir/.pbuild/_lastcheck") {
472472
}
473473
}
474474

475+
# load genbuildreqs cache
476+
my %genbuildreqs;
477+
if (-s "$builddir/.pbuild/_genbuildreqs") {
478+
my $oldgenbuildreqs = PBuild::Util::retrieve("$builddir/.pbuild/_genbuildreqs", 1) || {};
479+
for my $pkg (grep {$oldgenbuildreqs->{$_}} @pkgs) {
480+
my $old = $oldgenbuildreqs->{$pkg};
481+
my $p = $pkgsrc{$pkg};
482+
$genbuildreqs{$pkg} = $p->{'genbuildreqs'} = $old if @$old == 3 && $old->[2] eq ($p->{'verifymd5'} || $p->{'srcmd5'});
483+
}
484+
}
485+
475486
# tweak package list if we're just looking at one package
476487
if ($opts->{'single'}) {
477488
my $pkg = $opts->{'single'};
@@ -510,6 +521,7 @@ while (1) {
510521
# create and setup checker
511522
if (!$ctx) {
512523
$ctx = PBuild::Checker::create($bconf, $myarch, $buildtype, \%pkgsrc, $builddir, $opts, $repomgr, $assetmgr);
524+
$ctx->{'genbuildreqs'} = \%genbuildreqs;
513525
$ctx->{'hostarch'} = $hostarch;
514526
$ctx->{'bconf_host'} = $bconf_host if $cross;
515527
print "preparing package pool\n" unless $runs;
@@ -538,14 +550,18 @@ while (1) {
538550
if ($opts->{'extra-packs'}) {
539551
my $pkg = $opts->{'single'};
540552
die unless $pkg;
541-
my $code = $result->{$pkg}->{'code'};
542-
my $details = '';
553+
my ($code, $details) = ($result->{$pkg}->{'code'}, $result->{$pkg}->{'details'});
543554
if ($code eq 'building') {
544-
my @building = map {$_->{'job'}} grep {$_->{'job'}} @builders;
545-
my $job = PBuild::Job::waitjob($opts, @building);
546-
($code) = PBuild::Job::finishjob($job);
547-
} else {
548-
$details = ": $result->{$pkg}->{'details'}" if $result->{$pkg}->{'details'};
555+
my $job = $ctx->waitjob(\@builders);
556+
my $buildresult;
557+
($code, $buildresult) = PBuild::Job::finishjob($job);
558+
$details = undef;
559+
if ($code eq 'genbuildreqs') {
560+
print "$pkg: $code$details\n";
561+
$ctx->set_genbuildreqs($job->{'pdata'}, $buildresult->{'_generated_buildreqs'});
562+
undef $ctx;
563+
next;
564+
}
549565
}
550566
print "$pkg: $code$details\n";
551567
exit PBuild::Result::has_failed_code($opts, $code);
@@ -557,10 +573,9 @@ while (1) {
557573
my $oldresult = PBuild::Util::retrieve("$builddir/.pbuild/_result", 1) || {};
558574
$oldresult->{$pkg} = $result->{$pkg};
559575
$result = $oldresult;
560-
my $code = $result->{$pkg}->{'code'};
576+
my ($code, $details) = ($result->{$pkg}->{'code'}, $result->{$pkg}->{'details'});
561577
if ($code ne 'failed' && $code ne 'succeeded' && $code ne 'building') {
562-
$code .= ": $result->{$pkg}->{'details'}" if $result->{$pkg}->{'details'};
563-
print "$pkg: $code\n";
578+
print "$pkg: $code".($details ? " ($details)" : '')."\n";
564579
}
565580
}
566581

@@ -569,15 +584,10 @@ while (1) {
569584
PBuild::Util::store("$builddir/.pbuild/._result.$$", "$builddir/.pbuild/_result", $result);
570585
PBuild::Util::store("$builddir/.pbuild/._lastcheck.$$", "$builddir/.pbuild/_lastcheck", \%lastcheck);
571586

572-
# get list of building jobs
573-
my @building = map {$_->{'job'}} grep {$_->{'job'}} @builders;
574-
last unless @building;
575-
576587
# wait for one job to finish
577-
my $job = PBuild::Job::waitjob($opts, @building);
578-
for (@builders) {
579-
delete $_->{'job'} if $_->{'job'} && $_->{'job'} == $job;
580-
}
588+
my $job = $ctx->waitjob(\@builders);
589+
last unless $job;
590+
581591
# process finished job
582592
my ($code, $buildresult) = PBuild::Job::finishjob($job);
583593
my $p = $job->{'pdata'};
@@ -596,6 +606,13 @@ while (1) {
596606
my $jobhist = PBuild::BuildResult::makejobhist($p, $code, $job->{'readytime'}, $job->{'starttime'}, $job->{'endtime'}, $job->{'reason'}, $job->{'hostarch'});
597607
PBuild::BuildResult::addjobhist($builddir, $jobhist);
598608

609+
if ($code eq 'genbuildreqs') {
610+
$ctx->set_genbuildreqs($p, $buildresult->{'_generated_buildreqs'});
611+
# write genbuildreqs cache
612+
PBuild::Util::store("$builddir/.pbuild/._genbuildreqs.$$", "$builddir/.pbuild/_genbuildreqs", \%genbuildreqs);
613+
undef $ctx; # we need a new checker as we have to expand again
614+
next;
615+
}
599616
# integrate build artifacts and extra files
600617
my $bininfo = PBuild::BuildResult::integrate_job($builddir, $job, $code, $buildresult);
601618

0 commit comments

Comments
 (0)