Browse Source

scripts: metadata: always resolve dependencies through provides list

Allow to use PROVIDES to replace existing packages.
Matthias Schiffer 6 years ago
parent
commit
9b7ef2c65e

+ 296 - 0
patches/lede/0033-scripts-metadata-always-resolve-dependencies-through-provides-list.patch

@@ -0,0 +1,296 @@
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+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 <mschiffer@universe-factory.net>
+
+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..bd795bfe58d86c0e48205042192751fadf8a209b 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;
+ }
+@@ -173,9 +175,8 @@ sub mconf_depends {
+ 			}
+ 			$depend = $2;
+ 		}
+-		next if $package{$depend} and $package{$depend}->{buildonly};
+ 		if ($flags =~ /\+/) {
+-			if ($vdep = $package{$depend}->{vdepends}) {
++			if ($vdep = $vpackage{$depend}) {
+ 				my @vdeps;
+ 				$depend = undef;
+ 
+@@ -209,7 +210,7 @@ sub mconf_depends {
+ 
+ 			$flags =~ /@/ or $depend = "PACKAGE_$depend";
+ 		} else {
+-			if ($vdep = $package{$depend}->{vdepends}) {
++			if ($vdep = $vpackage{$depend}) {
+ 				$depend = join("||", map { "PACKAGE_".$_ } @$vdep);
+ 			} else {
+ 				$flags =~ /@/ or $depend = "PACKAGE_$depend";
+@@ -413,7 +414,6 @@ sub get_conditional_dep($$) {
+ 
+ sub gen_package_mk() {
+ 	my %conf;
+-	my %dep;
+ 	my %done;
+ 	my $line;
+ 
+@@ -423,8 +423,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 +443,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 +481,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 +569,7 @@ ifndef DUMP_TARGET_DB
+ 	( \\
+ $cmds \\
+ 	) > \$@
+-	
++
+ ifneq (\$(IMAGEOPT)\$(CONFIG_IMAGEOPT),)
+   package/preconfig: \$(TARGET_DIR)/etc/uci-defaults/$preconfig
+ endif