Message ID | 9bcf023216b3cf79d242d9501d13128d6b27aeec.1499541369.git.mschiffer@universe-factory.net |
---|---|
State | Not Applicable |
Delegated to: | Matthias Schiffer |
Headers | show |
On 07/08/2017 09:18 PM, Matthias Schiffer wrote: > Instead of adding virtual packages to the normal package list, keep a > separate list for provides, make each package provide itself, and resolve > all dependencies through this list. This allows to use PROVIDES to replace > existing packages. > > A side effect of the changes in the makefile dependency logic is that > build dependencies are now always interpreted as source package names, > instead of putting build and runtime dependencies into the same list. > > Fixes FS#837. > > Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> > --- > > v2: Fixed an issue that caused syntax errors in .config-package.in for > dependencies on on-existing packages (the new version will generate an I meant to write *non-existing*. > unsatisfiable dependency, which is probably the best way we can handle > this) > > > scripts/feeds | 3 -- > scripts/metadata.pm | 17 +++---- > scripts/package-metadata.pl | 121 +++++++++++++++++++++----------------------- > 3 files changed, 67 insertions(+), 74 deletions(-) > > diff --git a/scripts/feeds b/scripts/feeds > index 55c294ad0a..a38eb45458 100755 > --- a/scripts/feeds > +++ b/scripts/feeds > @@ -252,7 +252,6 @@ sub search_feed { > my $substr; > my $pkgmatch = 1; > > - next if $pkg->{vdepends}; > foreach my $substr (@substr) { > my $match; > foreach my $key (qw(name title description src)) { > @@ -306,7 +305,6 @@ sub list_feed { > get_feed($feed); > foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { > my $pkg = $feed_package->{$name}; > - next if $pkg->{vdepends}; > if($pkg->{name}) { > printf "\%-32s\t\%s\n", $pkg->{name}, $pkg->{title}; > } > @@ -588,7 +586,6 @@ sub install { > get_feed($f->[1]); > foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { > my $p = $feed_package->{$name}; > - next if $p->{vdepends}; > if( $p->{name} ) { > install_package($feed, $p->{name}, exists($opts{f})) == 0 or $ret = 1; > get_feed($f->[1]); > diff --git a/scripts/metadata.pm b/scripts/metadata.pm > index d446892e2b..8f5af40f14 100644 > --- a/scripts/metadata.pm > +++ b/scripts/metadata.pm > @@ -2,9 +2,10 @@ package metadata; > use base 'Exporter'; > use strict; > use warnings; > -our @EXPORT = qw(%package %srcpackage %category %subdir %preconfig %features %overrides clear_packages parse_package_metadata parse_target_metadata get_multiline @ignore %usernames %groupnames); > +our @EXPORT = qw(%package %vpackage %srcpackage %category %subdir %preconfig %features %overrides clear_packages parse_package_metadata parse_target_metadata get_multiline @ignore %usernames %groupnames); > > our %package; > +our %vpackage; > our %preconfig; > our %srcpackage; > our %category; > @@ -181,6 +182,7 @@ sub clear_packages() { > %subdir = (); > %preconfig = (); > %package = (); > + %vpackage = (); > %srcpackage = (); > %category = (); > %features = (); > @@ -238,6 +240,9 @@ sub parse_package_metadata($) { > $pkg->{override} = $override; > $package{$1} = $pkg; > push @{$srcpackage{$src}}, $pkg; > + > + $vpackage{$1} or $vpackage{$1} = []; > + unshift @{$vpackage{$1}}, $1; > }; > /^Feature:\s*(.+?)\s*$/ and do { > undef $pkg; > @@ -269,14 +274,8 @@ sub parse_package_metadata($) { > /^Provides: \s*(.+)\s*$/ and do { > my @vpkg = split /\s+/, $1; > foreach my $vpkg (@vpkg) { > - $package{$vpkg} or $package{$vpkg} = { > - name => $vpkg, > - vdepends => [], > - src => $src, > - subdir => $subdir, > - makefile => $makefile > - }; > - push @{$package{$vpkg}->{vdepends}}, $pkg->{name}; > + $vpackage{$vpkg} or $vpackage{$vpkg} = []; > + push @{$vpackage{$vpkg}}, $pkg->{name}; > } > }; > /^Menu-Depends: \s*(.+)\s*$/ and $pkg->{mdepends} = [ split /\s+/, $1 ]; > diff --git a/scripts/package-metadata.pl b/scripts/package-metadata.pl > index d4100c1726..902f7807bd 100755 > --- a/scripts/package-metadata.pl > +++ b/scripts/package-metadata.pl > @@ -101,14 +101,16 @@ my %dep_check; > sub __find_package_dep($$) { > my $pkg = shift; > my $name = shift; > - my $deps = ($pkg->{vdepends} or $pkg->{depends}); > + my $deps = $pkg->{depends}; > > return 0 unless defined $deps; > - foreach my $dep (@{$deps}) { > - next if $dep_check{$dep}; > - $dep_check{$dep} = 1; > - return 1 if $dep eq $name; > - return 1 if ($package{$dep} and (__find_package_dep($package{$dep},$name) == 1)); > + foreach my $vpkg (@{$deps}) { > + foreach my $dep (@{$vpackage{$vpkg}}) { > + next if $dep_check{$dep}; > + $dep_check{$dep} = 1; > + return 1 if $dep eq $name; > + return 1 if ($package{$dep} and (__find_package_dep($package{$dep},$name) == 1)); > + } > } > return 0; > } > @@ -156,7 +158,6 @@ sub mconf_depends { > my $m = "depends on"; > my $flags = ""; > $depend =~ s/^([@\+]+)// and $flags = $1; > - my $vdep; > my $condition = $parent_condition; > > next if $condition eq $depend; > @@ -173,9 +174,9 @@ sub mconf_depends { > } > $depend = $2; > } > - next if $package{$depend} and $package{$depend}->{buildonly}; > if ($flags =~ /\+/) { > - if ($vdep = $package{$depend}->{vdepends}) { > + my $vdep = $vpackage{$depend}; > + if ($vdep and @$vdep > 0) { > my @vdeps; > $depend = undef; > > @@ -209,7 +210,8 @@ sub mconf_depends { > > $flags =~ /@/ or $depend = "PACKAGE_$depend"; > } else { > - if ($vdep = $package{$depend}->{vdepends}) { > + my $vdep = $vpackage{$depend}; > + if ($vdep and @$vdep > 0) { > $depend = join("||", map { "PACKAGE_".$_ } @$vdep); > } else { > $flags =~ /@/ or $depend = "PACKAGE_$depend"; > @@ -413,7 +415,6 @@ sub get_conditional_dep($$) { > > sub gen_package_mk() { > my %conf; > - my %dep; > my %done; > my $line; > > @@ -423,8 +424,6 @@ sub gen_package_mk() { > my $pkg = $package{$name}; > my @srcdeps; > > - next if defined $pkg->{vdepends}; > - > $config = "\$(CONFIG_PACKAGE_$name)"; > if ($config) { > $pkg->{buildonly} and $config = ""; > @@ -445,16 +444,7 @@ sub gen_package_mk() { > print "buildtypes-$pkg->{subdir}$pkg->{src} = ".join(' ', @{$pkg->{buildtypes}})."\n"; > } > > - foreach my $spkg (@{$srcpackage{$pkg->{src}}}) { > - foreach my $dep (@{$spkg->{depends}}, @{$spkg->{builddepends}}) { > - $dep =~ /@/ or do { > - $dep =~ s/\+//g; > - push @srcdeps, $dep; > - }; > - } > - } > foreach my $type (@{$pkg->{buildtypes}}) { > - my @extra_deps; > my %deplines; > > next unless $pkg->{"builddepends/$type"}; > @@ -492,63 +482,70 @@ sub gen_package_mk() { > } > } > > - my $hasdeps = 0; > my %deplines; > - foreach my $deps (@srcdeps) { > - my $idx; > - my $condition; > - my $prefix = ""; > - my $suffix = ""; > - > - if ($deps =~ /^(.+):(.+)/) { > - $condition = $1; > - $deps = $2; > - } > - if ($deps =~ /^(.+)(\/.+)/) { > - $deps = $1; > - $suffix = $2; > - } > + foreach my $spkg (@{$srcpackage{$pkg->{src}}}) { > + foreach my $bdep (@{$spkg->{builddepends}}) { > + my $condition; > + my $suffix = ""; > > - my $pkg_dep = $package{$deps}; > - my @deps; > + if ($bdep =~ /^(.+):(.+)/) { > + $condition = $1; > + $bdep = $2; > + } > + if ($bdep =~ /^(.+)(\/.+)/) { > + $bdep = $1; > + $suffix = $2; > + } > > - if ($pkg_dep->{vdepends}) { > - @deps = @{$pkg_dep->{vdepends}}; > - } else { > - @deps = ($deps); > + next unless $subdir{$bdep}; > + my $idx = $subdir{$bdep}.$bdep.$suffix; > + > + my $depline = get_conditional_dep($condition, "\$(curdir)/$idx/compile"); > + if ($depline) { > + $deplines{$depline}++; > + } > } > > - foreach my $dep (@deps) { > - $pkg_dep = $package{$deps}; > - if (defined $pkg_dep->{src}) { > - ($pkg->{src} ne $pkg_dep->{src}.$suffix) and $idx = $pkg_dep->{subdir}.$pkg_dep->{src}; > - } elsif (defined($srcpackage{$dep})) { > - $idx = $subdir{$dep}.$dep; > + foreach my $dep (@{$spkg->{depends}}) { > + my $condition; > + my $suffix = ""; > + > + next if $dep =~ /@/; > + $dep =~ s/\+//g; > + > + if ($dep =~ /^(.+):(.+)/) { > + $condition = $1; > + $dep = $2; > } > - undef $idx if $idx eq 'base-files'; > - if ($idx) { > - $idx .= $suffix; > + if ($dep =~ /^(.+)(\/.+)/) { > + $dep = $1; > + $suffix = $2; > + } > + > + next unless $vpackage{$dep}; > + > + my @vdeps = @{$vpackage{$dep}}; > + foreach my $vdep (@vdeps) { > + my $pkg_dep = $package{$vdep}; > > - my $depline; > + next unless $pkg_dep; > next if $pkg->{src} eq $pkg_dep->{src}.$suffix; > - next if $dep{$condition.":".$pkg->{src}."->".$idx}; > - next if $dep{$pkg->{src}."->($dep)".$idx} and $pkg_dep->{vdepends}; > - my $depstr; > > - if ($pkg_dep->{vdepends}) { > - $depstr = "\$(if \$(CONFIG_PACKAGE_$dep),\$(curdir)/$idx/compile)"; > - $dep{$pkg->{src}."->($dep)".$idx} = 1; > + my $idx = $pkg_dep->{subdir}.$pkg_dep->{src}.$suffix; > + my $depstr; > + if (@vdeps > 1) { > + $depstr = "\$(if \$(CONFIG_PACKAGE_$vdep),\$(curdir)/$idx/compile)"; > } else { > $depstr = "\$(curdir)/$idx/compile"; > - $dep{$pkg->{src}."->".$idx} = 1; > } > - $depline = get_conditional_dep($condition, $depstr); > + my $depline = get_conditional_dep($condition, $depstr); > if ($depline) { > $deplines{$depline}++; > } > } > } > } > + > my $depline = join(" ", sort keys %deplines); > if ($depline) { > $line .= "\$(curdir)/".$pkg->{subdir}."$pkg->{src}/compile += $depline\n"; > @@ -573,7 +570,7 @@ ifndef DUMP_TARGET_DB > ( \\ > $cmds \\ > ) > \$@ > - > + > ifneq (\$(IMAGEOPT)\$(CONFIG_IMAGEOPT),) > package/preconfig: \$(TARGET_DIR)/etc/uci-defaults/$preconfig > endif >
On 07/08/2017 09:18 PM, Matthias Schiffer wrote: > Instead of adding virtual packages to the normal package list, keep a > separate list for provides, make each package provide itself, and resolve > all dependencies through this list. This allows to use PROVIDES to replace > existing packages. > > A side effect of the changes in the makefile dependency logic is that > build dependencies are now always interpreted as source package names, > instead of putting build and runtime dependencies into the same list. > > Fixes FS#837. > > Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> The patch has been tested in Gluon for a while now and it seems to work correctly. It may break some feed packages that are incorrectly specifying binary instead of source package names in PKG_BUILD_DEPENDS; these packages will need to be fixed when we notice them. If nobody vetoes, I'd like to push it to master soon. The patch is also in my staging tree for everybody to test. Matthias
diff --git a/scripts/feeds b/scripts/feeds index 55c294ad0a..a38eb45458 100755 --- a/scripts/feeds +++ b/scripts/feeds @@ -252,7 +252,6 @@ sub search_feed { my $substr; my $pkgmatch = 1; - next if $pkg->{vdepends}; foreach my $substr (@substr) { my $match; foreach my $key (qw(name title description src)) { @@ -306,7 +305,6 @@ sub list_feed { get_feed($feed); foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { my $pkg = $feed_package->{$name}; - next if $pkg->{vdepends}; if($pkg->{name}) { printf "\%-32s\t\%s\n", $pkg->{name}, $pkg->{title}; } @@ -588,7 +586,6 @@ sub install { get_feed($f->[1]); foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { my $p = $feed_package->{$name}; - next if $p->{vdepends}; if( $p->{name} ) { install_package($feed, $p->{name}, exists($opts{f})) == 0 or $ret = 1; get_feed($f->[1]); diff --git a/scripts/metadata.pm b/scripts/metadata.pm index d446892e2b..8f5af40f14 100644 --- a/scripts/metadata.pm +++ b/scripts/metadata.pm @@ -2,9 +2,10 @@ package metadata; use base 'Exporter'; use strict; use warnings; -our @EXPORT = qw(%package %srcpackage %category %subdir %preconfig %features %overrides clear_packages parse_package_metadata parse_target_metadata get_multiline @ignore %usernames %groupnames); +our @EXPORT = qw(%package %vpackage %srcpackage %category %subdir %preconfig %features %overrides clear_packages parse_package_metadata parse_target_metadata get_multiline @ignore %usernames %groupnames); our %package; +our %vpackage; our %preconfig; our %srcpackage; our %category; @@ -181,6 +182,7 @@ sub clear_packages() { %subdir = (); %preconfig = (); %package = (); + %vpackage = (); %srcpackage = (); %category = (); %features = (); @@ -238,6 +240,9 @@ sub parse_package_metadata($) { $pkg->{override} = $override; $package{$1} = $pkg; push @{$srcpackage{$src}}, $pkg; + + $vpackage{$1} or $vpackage{$1} = []; + unshift @{$vpackage{$1}}, $1; }; /^Feature:\s*(.+?)\s*$/ and do { undef $pkg; @@ -269,14 +274,8 @@ sub parse_package_metadata($) { /^Provides: \s*(.+)\s*$/ and do { my @vpkg = split /\s+/, $1; foreach my $vpkg (@vpkg) { - $package{$vpkg} or $package{$vpkg} = { - name => $vpkg, - vdepends => [], - src => $src, - subdir => $subdir, - makefile => $makefile - }; - push @{$package{$vpkg}->{vdepends}}, $pkg->{name}; + $vpackage{$vpkg} or $vpackage{$vpkg} = []; + push @{$vpackage{$vpkg}}, $pkg->{name}; } }; /^Menu-Depends: \s*(.+)\s*$/ and $pkg->{mdepends} = [ split /\s+/, $1 ]; diff --git a/scripts/package-metadata.pl b/scripts/package-metadata.pl index d4100c1726..902f7807bd 100755 --- a/scripts/package-metadata.pl +++ b/scripts/package-metadata.pl @@ -101,14 +101,16 @@ my %dep_check; sub __find_package_dep($$) { my $pkg = shift; my $name = shift; - my $deps = ($pkg->{vdepends} or $pkg->{depends}); + my $deps = $pkg->{depends}; return 0 unless defined $deps; - foreach my $dep (@{$deps}) { - next if $dep_check{$dep}; - $dep_check{$dep} = 1; - return 1 if $dep eq $name; - return 1 if ($package{$dep} and (__find_package_dep($package{$dep},$name) == 1)); + foreach my $vpkg (@{$deps}) { + foreach my $dep (@{$vpackage{$vpkg}}) { + next if $dep_check{$dep}; + $dep_check{$dep} = 1; + return 1 if $dep eq $name; + return 1 if ($package{$dep} and (__find_package_dep($package{$dep},$name) == 1)); + } } return 0; } @@ -156,7 +158,6 @@ sub mconf_depends { my $m = "depends on"; my $flags = ""; $depend =~ s/^([@\+]+)// and $flags = $1; - my $vdep; my $condition = $parent_condition; next if $condition eq $depend; @@ -173,9 +174,9 @@ sub mconf_depends { } $depend = $2; } - next if $package{$depend} and $package{$depend}->{buildonly}; if ($flags =~ /\+/) { - if ($vdep = $package{$depend}->{vdepends}) { + my $vdep = $vpackage{$depend}; + if ($vdep and @$vdep > 0) { my @vdeps; $depend = undef; @@ -209,7 +210,8 @@ sub mconf_depends { $flags =~ /@/ or $depend = "PACKAGE_$depend"; } else { - if ($vdep = $package{$depend}->{vdepends}) { + my $vdep = $vpackage{$depend}; + if ($vdep and @$vdep > 0) { $depend = join("||", map { "PACKAGE_".$_ } @$vdep); } else { $flags =~ /@/ or $depend = "PACKAGE_$depend"; @@ -413,7 +415,6 @@ sub get_conditional_dep($$) { sub gen_package_mk() { my %conf; - my %dep; my %done; my $line; @@ -423,8 +424,6 @@ sub gen_package_mk() { my $pkg = $package{$name}; my @srcdeps; - next if defined $pkg->{vdepends}; - $config = "\$(CONFIG_PACKAGE_$name)"; if ($config) { $pkg->{buildonly} and $config = ""; @@ -445,16 +444,7 @@ sub gen_package_mk() { print "buildtypes-$pkg->{subdir}$pkg->{src} = ".join(' ', @{$pkg->{buildtypes}})."\n"; } - foreach my $spkg (@{$srcpackage{$pkg->{src}}}) { - foreach my $dep (@{$spkg->{depends}}, @{$spkg->{builddepends}}) { - $dep =~ /@/ or do { - $dep =~ s/\+//g; - push @srcdeps, $dep; - }; - } - } foreach my $type (@{$pkg->{buildtypes}}) { - my @extra_deps; my %deplines; next unless $pkg->{"builddepends/$type"}; @@ -492,63 +482,70 @@ sub gen_package_mk() { } } - my $hasdeps = 0; my %deplines; - foreach my $deps (@srcdeps) { - my $idx; - my $condition; - my $prefix = ""; - my $suffix = ""; - - if ($deps =~ /^(.+):(.+)/) { - $condition = $1; - $deps = $2; - } - if ($deps =~ /^(.+)(\/.+)/) { - $deps = $1; - $suffix = $2; - } + foreach my $spkg (@{$srcpackage{$pkg->{src}}}) { + foreach my $bdep (@{$spkg->{builddepends}}) { + my $condition; + my $suffix = ""; - my $pkg_dep = $package{$deps}; - my @deps; + if ($bdep =~ /^(.+):(.+)/) { + $condition = $1; + $bdep = $2; + } + if ($bdep =~ /^(.+)(\/.+)/) { + $bdep = $1; + $suffix = $2; + } - if ($pkg_dep->{vdepends}) { - @deps = @{$pkg_dep->{vdepends}}; - } else { - @deps = ($deps); + next unless $subdir{$bdep}; + my $idx = $subdir{$bdep}.$bdep.$suffix; + + my $depline = get_conditional_dep($condition, "\$(curdir)/$idx/compile"); + if ($depline) { + $deplines{$depline}++; + } } - foreach my $dep (@deps) { - $pkg_dep = $package{$deps}; - if (defined $pkg_dep->{src}) { - ($pkg->{src} ne $pkg_dep->{src}.$suffix) and $idx = $pkg_dep->{subdir}.$pkg_dep->{src}; - } elsif (defined($srcpackage{$dep})) { - $idx = $subdir{$dep}.$dep; + foreach my $dep (@{$spkg->{depends}}) { + my $condition; + my $suffix = ""; + + next if $dep =~ /@/; + $dep =~ s/\+//g; + + if ($dep =~ /^(.+):(.+)/) { + $condition = $1; + $dep = $2; } - undef $idx if $idx eq 'base-files'; - if ($idx) { - $idx .= $suffix; + if ($dep =~ /^(.+)(\/.+)/) { + $dep = $1; + $suffix = $2; + } + + next unless $vpackage{$dep}; + + my @vdeps = @{$vpackage{$dep}}; + foreach my $vdep (@vdeps) { + my $pkg_dep = $package{$vdep}; - my $depline; + next unless $pkg_dep; next if $pkg->{src} eq $pkg_dep->{src}.$suffix; - next if $dep{$condition.":".$pkg->{src}."->".$idx}; - next if $dep{$pkg->{src}."->($dep)".$idx} and $pkg_dep->{vdepends}; - my $depstr; - if ($pkg_dep->{vdepends}) { - $depstr = "\$(if \$(CONFIG_PACKAGE_$dep),\$(curdir)/$idx/compile)"; - $dep{$pkg->{src}."->($dep)".$idx} = 1; + my $idx = $pkg_dep->{subdir}.$pkg_dep->{src}.$suffix; + my $depstr; + if (@vdeps > 1) { + $depstr = "\$(if \$(CONFIG_PACKAGE_$vdep),\$(curdir)/$idx/compile)"; } else { $depstr = "\$(curdir)/$idx/compile"; - $dep{$pkg->{src}."->".$idx} = 1; } - $depline = get_conditional_dep($condition, $depstr); + my $depline = get_conditional_dep($condition, $depstr); if ($depline) { $deplines{$depline}++; } } } } + my $depline = join(" ", sort keys %deplines); if ($depline) { $line .= "\$(curdir)/".$pkg->{subdir}."$pkg->{src}/compile += $depline\n"; @@ -573,7 +570,7 @@ ifndef DUMP_TARGET_DB ( \\ $cmds \\ ) > \$@ - + ifneq (\$(IMAGEOPT)\$(CONFIG_IMAGEOPT),) package/preconfig: \$(TARGET_DIR)/etc/uci-defaults/$preconfig endif
Instead of adding virtual packages to the normal package list, keep a separate list for provides, make each package provide itself, and resolve all dependencies through this list. This allows to use PROVIDES to replace existing packages. A side effect of the changes in the makefile dependency logic is that build dependencies are now always interpreted as source package names, instead of putting build and runtime dependencies into the same list. Fixes FS#837. Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> --- v2: Fixed an issue that caused syntax errors in .config-package.in for dependencies on on-existing packages (the new version will generate an unsatisfiable dependency, which is probably the best way we can handle this) scripts/feeds | 3 -- scripts/metadata.pm | 17 +++---- scripts/package-metadata.pl | 121 +++++++++++++++++++++----------------------- 3 files changed, 67 insertions(+), 74 deletions(-)