From: Matthias Schiffer Date: Sat, 8 Jul 2017 01:35:35 +0200 Subject: scripts: metadata: always resolve dependencies through provides list 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 diff --git a/scripts/feeds b/scripts/feeds index 55c294ad0a4ec2f0419d12deddeda7324c349e04..a38eb454585f5dd27b707db23184b7df07ab2658 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 8334f26d3179a0eb83aa1aa976778ff5828faf45..e7bdbab4568ddd7e10c10b2ca6a718380c7d6308 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); +our @EXPORT = qw(%package %vpackage %srcpackage %category %subdir %preconfig %features %overrides clear_packages parse_package_metadata parse_target_metadata get_multiline @ignore); our %package; +our %vpackage; our %preconfig; our %srcpackage; our %category; @@ -124,6 +125,7 @@ sub clear_packages() { %subdir = (); %preconfig = (); %package = (); + %vpackage = (); %srcpackage = (); %category = (); %features = (); @@ -179,6 +181,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; @@ -210,14 +215,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 2da32c770ef3333bfcc18922ede556f9734510c7..998d37dd415d89e7eccad2ddf73f855f6a9b017c 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