c1d0a96581
The dependencies are stored in gendep.macros file. The file be regenerated from an RPM build log by ./generatedependencies tool. The intended work flow is to build a new perl with RPM Perl dependency generator available locally. Then use this ./generatedependencies tool to convert the discovered dependencies into the gendep.macro file. Then it's possible to build the new perl even without the RPM Perl dependency generator available in the build root while the resulting binary packages will still posses all dependencies. The reason is standard perl-genererators is written in the Perl thus perl-generators must run-require perl. Therefore there is a build cycle. One could rewrite perl-generators.spec so that it did not need perl for building, but the run-time dependency would still be there. One could claim the one run-time dependency can be satisfied by older perl. And that's true and it has been done so until now. But that would not solve the problem when bootrapping perl to a new architecture or as an excercise the perl can be built without any prior perl available (required by paranoid users). With pregenerated dependencies, one can implement real bootstrap. (Ultimate solution would be reimplement RPM Perl generators in C.)
164 lines
4.4 KiB
Perl
Executable File
164 lines
4.4 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
use strict;
|
|
use warnings;
|
|
|
|
# Split "A B >= 1" dependencies string into ("A", "B >= 1") list.
|
|
sub appendsymbols {
|
|
my ($array, $line) = @_;
|
|
my $qualified;
|
|
my $dependency;
|
|
for my $token (split(/\s/, $line)) {
|
|
if ($token =~ /\A[<>]?=\z/) {
|
|
$qualified = 1;
|
|
$dependency .= ' ' . $token;
|
|
next;
|
|
}
|
|
if (!$qualified) {
|
|
if (defined $dependency) {
|
|
push @$array, $dependency;
|
|
}
|
|
$dependency = $token;
|
|
next;
|
|
}
|
|
if ($qualified) {
|
|
$qualified = 0;
|
|
$dependency .= ' ' . $token;
|
|
push @$array, $dependency;
|
|
$dependency = undef;
|
|
next;
|
|
}
|
|
}
|
|
if (defined $dependency) {
|
|
push @$array, $dependency;
|
|
}
|
|
}
|
|
|
|
# Return true if the argument is a Perl dependency. Otherwise return false.
|
|
sub is_perl_dependency {
|
|
my $dependency = shift;
|
|
return ($dependency =~ /\Aperl\(/);
|
|
}
|
|
|
|
my $file = shift @ARGV;
|
|
if (!defined $file) {
|
|
die "Missing an argument with an RPM build log!\n"
|
|
}
|
|
|
|
# Parse build log
|
|
open(my $log, '<', $file) or die "Could not open `$file': $!\n";
|
|
my ($package, %packages);
|
|
while (!eof($log)) {
|
|
defined($_ = <$log>) or die "Error while reading from `$file': $!\n";
|
|
chomp;
|
|
|
|
if (/\AProcessing files: ([\S]+)-[^-]+-[^-]+$/) {
|
|
$package = $1;
|
|
$packages{$package}{requires} = [];
|
|
$packages{$package}{provides} = [];
|
|
} elsif ($package && /\AProvides: (.*)\z/) {
|
|
appendsymbols($packages{$package}{provides}, $1);
|
|
} elsif ($package && /\ARequires: (.*)\z/) {
|
|
appendsymbols($packages{$package}{requires}, $1);
|
|
}
|
|
}
|
|
close($log);
|
|
|
|
# Save dependencies into file
|
|
my $filename = 'gendep.macros';
|
|
open (my $gendep, '>', $filename) or
|
|
die "Could not open `$filename' for writing: $!\n";
|
|
for my $package (sort keys %packages) {
|
|
# Macro name
|
|
my $macro = 'gendep_' . $package;
|
|
$macro =~ s/[+-]/_/g;
|
|
$gendep->print("%global $macro \\\n");
|
|
# Macro value
|
|
for my $dependency (@{$packages{$package}{requires}}) {
|
|
if (is_perl_dependency($dependency)) {
|
|
$gendep->print("Requires: $dependency \\\n");
|
|
}
|
|
}
|
|
for my $dependency (@{$packages{$package}{provides}}) {
|
|
if (is_perl_dependency($dependency)) {
|
|
$gendep->print("Provides: $dependency \\\n");
|
|
}
|
|
}
|
|
# Macro trailer
|
|
$gendep->print("%{nil}\n");
|
|
}
|
|
close($gendep) or die "Could not close `$filename': $!\n";
|
|
|
|
|
|
__END__
|
|
=encoding utf8
|
|
|
|
=head1 NAME
|
|
|
|
generatedependencies - Distil generated Perl dependencies from a build log
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
B<generatedependencies> I<BUILD_LOG>
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
It opens specified RPM build log I<BUILD_LOG>. It locates a protocol about
|
|
autogenerated dependencies. It stores the reported dependencies into F<./gendep.macros> file.
|
|
|
|
The output file will define macros C<gendep_I<BINARY_PACKAGE_NAME>>. A macro
|
|
for each binary package. The macro name will use underscores instead of
|
|
hyphens or other SPEC language special characters.
|
|
|
|
It will ignore non-Perl dependencies (not C<perl(*)>) as they do not come from
|
|
Perl dependency generator.
|
|
|
|
=head1 EXIT CODE
|
|
|
|
Returns zero, if no error occurred. Otherwise non-zero code is returned.
|
|
|
|
=head1 EXAMPLE
|
|
|
|
The invocation is:
|
|
|
|
$ generatedependencies .build-5.24.0-364.fc25.log
|
|
|
|
The output is:
|
|
|
|
$ grep -A5 perl_Devel_Peek gendep.macros
|
|
%global gendep_perl_Devel_Peek \
|
|
Requires: perl(Exporter) \
|
|
Requires: perl(XSLoader) \
|
|
Provides: perl(Devel::Peek) = 1.23 \
|
|
%nil{}
|
|
%global gendep_perl_Devel_SelfStubber \
|
|
|
|
|
|
The output can be used in a spec file like:
|
|
|
|
Name: perl
|
|
Source0: gendep.macros
|
|
%include %{SOURCE0}
|
|
%package Devel-Peek
|
|
%gendep_Devel_Peek
|
|
%package Devel-SelfStubber
|
|
%gendep_Devel_SelfStubber
|
|
|
|
=head1 COPYING
|
|
|
|
Copyright (C) 2016 Petr Písař <ppisar@redhat.com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
=cut
|