tags 291939 patch retitle 291939 [ARCH] Add support for Architecture aliases/wildcards thanks
Hi Scott, I've finally had the time to finish this patch. I've polished the initial version I showed you at Debconf, moved the read_{cpu,os}table functions to controllib.pl, thus eliminating the need to expand the arches externally through dpkg-architecture. Those aliases will only affect the debian/control file, so will not change the debian source (.dsc, .changes) or binary format (.deb). Once the new dpkg source format is introduced the source format could use the new aliases instead. The new aliases are: <kernel>-any linux-<cpu> any-<cpu> any-any all-all I've not added "all-any" and "any-all" because they do not make sense right now, but maybe would be nice to have, just for consistency. I've added two new commands to dpkg-architecture so other programs can use the same logic w/o having to reimplement it, also that will allow adding aliases there and everyone will benefit automagically. Those are -e<debian-arch> for equality (eq) and -i<arch-alias> for identity (is). The only problem is that when you set the current arch with -a it spews a warning, so it's a bit annoying (maybe that could be removed?). So you can ask things like: - "current arch" eq i386? dpkg-architecture -ei386 && echo yes - alpha eq linux-alpha? dpkg-architecture -aalpha -elinux-alpha 2>/dev/null && echo yes - "current arch" is any-sparc? dpkg-architecture -iany-sparc && echo yes - alpha is linux-any? dpkg-architecture -aalpha -ilinux-any 2>/dev/null && echo yes - kfreebsd-i386 is any-i386? dpkg-architecture -akfreebsd-i386 -iany-i386 2>/dev/null && echo yes Once this patch is accepted, bug #112325 can be closed as well as it can be handled with the new wildcards. Patch attached, apply, rename "scripts/controllib.pl" to "scripts/controllib.pl.in" and autoreconf. I've included as well two hackish source packages to test the new stuff, the test-source is for dpkg-checkbuilddeps and dpkg-source and test-binary for the remaning stuff, just debuild and check. regards, guillem
diff -aur dpkg-1.13.10.orig/scripts/controllib.pl dpkg-1.13.10/scripts/controllib.pl --- dpkg-1.13.10.orig/scripts/controllib.pl 2005-06-06 07:07:12.000000000 +0300 +++ dpkg-1.13.10/scripts/controllib.pl 2005-07-23 23:52:17.000000000 +0300 @@ -12,6 +12,8 @@ # "S key" where S is the source and key is the packagename # %substvar - map with substitution variables +$pkgdatadir="."; + $parsechangelog= 'dpkg-parsechangelog'; grep($capit{lc $_}=$_, qw(Pre-Depends Standards-Version Installed-Size @@ -80,6 +82,114 @@ $substvar{'Arch'}= $arch; } +sub read_cputable { + open CPUTABLE, "$pkgdatadir/cputable" + or &syserr("unable to open cputable"); + while (<CPUTABLE>) { + if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) { + $cputable{$1} = $2; + $cputable_re{$1} = $3; + push @cpu, $1; + } + } + close CPUTABLE; +} + +sub read_ostable { + open OSTABLE, "$pkgdatadir/ostable" + or &syserr("unable to open ostable"); + while (<OSTABLE>) { + if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) { + $ostable{$1} = $2; + $ostable_re{$1} = $3; + push @os, $1; + } + } + close OSTABLE; +} + +sub debian_arch_fix +{ + local ($os, $cpu) = @_; + + if ($os eq "linux") { + return $cpu; + } else { + return "$os-$cpu"; + } +} + +sub debian_arch_split { + local ($_) = @_; + + if (/^([^-]*)-(.*)/) { + return ($1, $2); + } elsif (/any/ || /all/) { + return ($_, $_); + } else { + return ("linux", $_); + } +} + +sub debian_arch_eq { + my ($a, $b) = @_; + my ($a_os, $a_cpu) = debian_arch_split($a); + my ($b_os, $b_cpu) = debian_arch_split($b); + + return ("$a_os-$a_cpu" eq "$b_os-$b_cpu"); +} + +sub debian_arch_is { + my ($real, $alias) = @_; + my ($real_os, $real_cpu) = debian_arch_split($real); + my ($alias_os, $alias_cpu) = debian_arch_split($alias); + + if ("$real_os-$real_cpu" eq "$alias_os-$alias_cpu") { + return 1; + } elsif ("$alias_os-$alias_cpu" eq "any-any") { + return 1; + } elsif ("$alias_os-$alias_cpu" eq "any-$real_cpu") { + return 1; + } elsif ("$alias_os-$alias_cpu" eq "$real_os-any") { + return 1; + } + + return 0; +} + +&read_cputable; +&read_ostable; + +sub debian_arch_expand +{ + local ($_) = @_; + + /^(!)?(.*)/; + + local $not = $1; + local $arch = $2; + local ($os, $cpu) = debian_arch_split($arch); + local @list; + + if ("$os-$cpu" eq 'any-any') { + @list = 'any'; + } elsif ($os eq 'all' or $cpu eq 'all') { + @list = 'all'; + } elsif ($cpu eq 'any') { + foreach my $_cpu (@cpu) { + push @list, $not.debian_arch_fix($os, $_cpu); + } + } elsif ($os eq 'any') { + foreach my $_os (@os) { + push @list, $not.debian_arch_fix($_os, $cpu); + } + } else { + push @list, $not.debian_arch_fix($os, $cpu); + } + + return @list; +} + sub substvars { my ($v) = @_; my ($lhs,$vn,$rhs,$count); @@ -188,17 +298,21 @@ my $seen_arch=''; foreach my $arch (@arches) { $arch=lc($arch); - if ($arch eq $host_arch) { + if (debian_arch_is($host_arch, $arch)) { $seen_arch=1; next; - } elsif ($arch eq "!$host_arch") { - next ALTERNATE; - } elsif ($arch =~ /!/) { - # This is equivilant to - # having seen the current arch, - # unless the current arch - # is also listed.. - $seen_arch=1; + } elsif ($arch =~ /^!/) { + ($not_arch = $arch) =~ s/^!//; + + if (debian_arch_is($host_arch, $not_arch)) { + next ALTERNATE; + } else { + # This is equivilant to + # having seen the current arch, + # unless the current arch + # is also listed.. + $seen_arch=1; + } } } if (! $seen_arch) { diff -aur dpkg-1.13.10.orig/scripts/dpkg-architecture.pl dpkg-1.13.10/scripts/dpkg-architecture.pl --- dpkg-1.13.10.orig/scripts/dpkg-architecture.pl 2005-07-23 23:52:33.000000000 +0300 +++ dpkg-1.13.10/scripts/dpkg-architecture.pl 2005-07-24 00:33:02.000000000 +0300 @@ -26,8 +26,6 @@ push(@INC,$dpkglibdir); require 'controllib.pl'; -$pkgdatadir="."; - sub usageversion { print STDERR "Debian $0 $version. @@ -39,12 +37,14 @@ Usage: $0 [<option> ...] [<action>] Options: - -a<debian-arch> set Debian architecture - -t<gnu-system> set GNU system type + -a<debian-arch> set current Debian architecture + -t<gnu-system> set current GNU system type -L list valid architectures -f force flag (override variables set in environment) Actions: -l list variables (default) + -e<debian-arch> compare the current Debian architecture with the one given + -i<arch-alias> check if current Debian architecture is part of the arch-alias -q<variable> prints only the value of <variable>. -s print command to set environment variables -u print command to unset environment variables @@ -52,32 +52,6 @@ "; } -sub read_cputable { - open CPUTABLE, "$pkgdatadir/cputable" - or &syserr("unable to open cputable"); - while (<CPUTABLE>) { - if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) { - $cputable{$1} = $2; - $cputable_re{$1} = $3; - push @cpu, $1; - } - } - close CPUTABLE; -} - -sub read_ostable { - open OSTABLE, "$pkgdatadir/ostable" - or &syserr("unable to open ostable"); - while (<OSTABLE>) { - if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) { - $ostable{$1} = $2; - $ostable_re{$1} = $3; - push @os, $1; - } - } - close OSTABLE; -} - sub split_debian { local ($_) = @_; @@ -124,25 +98,14 @@ } return undef if !defined($cpu) || !defined($os); - if ($os eq "linux") { - return $cpu; - } else { - return "$os-$cpu"; - } + return debian_arch_fix($os, $cpu); } -&read_cputable; -&read_ostable; - # Check for -L if (grep { m/^-L$/ } @ARGV) { foreach $os (@os) { foreach $cpu (@cpu) { - if ($os eq "linux") { - print "$cpu\n" - } else { - print "$os-$cpu\n"; - } + print debian_arch_fix($os, $cpu)."\n"; } } exit unless $#ARGV; @@ -182,6 +145,8 @@ $req_host_arch = ''; $req_host_gnu_type = ''; $req_build_gnu_type = ''; +$req_eq_arch = ''; +$req_is_arch = ''; $action='l'; $force=0; @@ -191,6 +156,12 @@ $req_host_arch = "$'"; } elsif (m/^-t/) { $req_host_gnu_type = "$'"; + } elsif (m/^-e/) { + $req_eq_arch = "$'"; + $action = 'e'; + } elsif (m/^-i/) { + $req_is_arch = "$'"; + $action = 'i'; } elsif (m/^-[lsu]$/) { $action = $_; $action =~ s/^-//; @@ -282,6 +253,10 @@ print "export ".join(" ",@ordered)."\n"; } elsif ($action eq 'u') { print "unset ".join(" ",@ordered)."\n"; +} elsif ($action eq 'e') { + exit !debian_arch_eq($deb_host_arch, $req_eq_arch); +} elsif ($action eq 'i') { + exit !debian_arch_is($deb_host_arch, $req_is_arch); } elsif ($action eq 'c') { @ENV{keys %env} = values %env; exec @ARGV; diff -aur dpkg-1.13.10.orig/scripts/dpkg-genchanges.pl dpkg-1.13.10/scripts/dpkg-genchanges.pl --- dpkg-1.13.10.orig/scripts/dpkg-genchanges.pl 2005-06-06 07:07:12.000000000 +0300 +++ dpkg-1.13.10/scripts/dpkg-genchanges.pl 2005-07-12 20:57:52.000000000 +0300 @@ -168,8 +168,9 @@ } elsif (s/^C(\d+) //) { $i=$1; $p=$fi{"C$i Package"}; $a=$fi{"C$i Architecture"}; if (!defined($p2f{$p}) && not $sourceonly) { - if ($a eq 'any' || ($a eq 'all' && !$archspecific) || - grep($_ eq $substvar{'Arch'}, split(/\s+/, $a))) { + if ((debian_arch_eq('all', $a) && !$archspecific) || + debian_arch_is($arch, $a) || + grep(debian_arch_is($arch, $_), split(/\s+/, $a))) { &warn("package $p in control file but not in files list"); next; } @@ -191,9 +192,10 @@ $f{$_}= $v; } elsif (m/^Architecture$/) { if (not $sourceonly) { - if ($v eq 'any' || grep($_ eq $arch, split(/\s+/, $v))) { + if (debian_arch_is($arch, $v) || + grep(debian_arch_is($arch, $_), split(/\s+/, $v))) { $v= $arch; - } elsif ($v ne 'all') { + } elsif (!debian_arch_eq('all', $v)) { $v= ''; } } else { @@ -315,7 +317,7 @@ $f{'Files'}= ''; for $f (@sourcefiles,@fileslistfiles) { - next if ($archspecific && ($p2arch{$f2p{$f}} eq 'all')); + next if ($archspecific && debian_arch_eq('all', $p2arch{$f2p{$f}})); next if $filedone{$f}++; $uf= "$uploadfilesdir/$f"; open(STDIN,"< $uf") || &syserr("cannot open upload file $uf for reading"); diff -aur dpkg-1.13.10.orig/scripts/dpkg-gencontrol.pl dpkg-1.13.10/scripts/dpkg-gencontrol.pl --- dpkg-1.13.10.orig/scripts/dpkg-gencontrol.pl 2005-06-06 07:07:12.000000000 +0300 +++ dpkg-1.13.10/scripts/dpkg-gencontrol.pl 2005-07-12 20:57:52.000000000 +0300 @@ -133,13 +133,13 @@ } elsif (m/^Section$|^Priority$/) { $spvalue{$_}= $v; } elsif (m/^Architecture$/) { - if ($v eq 'all') { + if (debian_arch_eq('all', $v)) { $f{$_}= $v; - } elsif ($v eq 'any') { + } elsif (debian_arch_is($arch, $v)) { $f{$_}= $arch; } else { @archlist= split(/\s+/,$v); - grep($arch eq $_, @archlist) || + grep(debian_arch_is($arch, $_), @archlist) || &error("current build architecture $arch does not". " appear in package's list (@archlist)"); $f{$_}= $arch; @@ -243,7 +243,8 @@ while (<X>) { chomp; next if m/^([-+0-9a-z.]+)_[^_]+_([\w-]+)\.deb / - && ($1 eq $oppackage) && ($2 eq $arch || $2 eq 'all'); + && ($1 eq $oppackage) + && (debian_arch_eq($2, $arch) || debian_arch_eq($2, 'all')); print(Y "$_\n") || &syserr("copy old entry to new files list file"); } close(X) || &syserr("close old files list file"); diff -aur dpkg-1.13.10.orig/scripts/dpkg-source.pl dpkg-1.13.10/scripts/dpkg-source.pl --- dpkg-1.13.10.orig/scripts/dpkg-source.pl 2005-06-13 20:47:34.000000000 +0300 +++ dpkg-1.13.10/scripts/dpkg-source.pl 2005-07-12 21:25:03.000000000 +0300 @@ -161,9 +161,9 @@ $i=$1; $p=$fi{"C$i Package"}; push(@binarypackages,$p) unless $packageadded{$p}++; if (m/^Architecture$/) { - if ($v eq 'any') { + if (debian_arch_eq($v, 'any')) { @sourcearch= ('any'); - } elsif ($v eq 'all') { + } elsif (debian_arch_eq($v, 'all')) { if ([EMAIL PROTECTED] || $sourcearch[0] eq 'all') { @sourcearch= ('all'); } else { @@ -173,7 +173,10 @@ if (grep($sourcearch[0] eq $_, 'any','all')) { @sourcearch= ('any'); } else { - for $a (split(/\s+/,$v)) { + my @arches = map(split(/\s+/, debian_arch_expand($_)), + split(/\s+/, $v)); + chomp @arches; + for $a (@arches) { &error("architecture $a only allowed on its own". " (list for package $p is `$a')") if grep($a eq $_, 'any','all'); diff -aur dpkg-1.13.10.orig/scripts/Makefile.am dpkg-1.13.10/scripts/Makefile.am --- dpkg-1.13.10.orig/scripts/Makefile.am 2005-06-06 07:07:12.000000000 +0300 +++ dpkg-1.13.10/scripts/Makefile.am 2005-07-24 01:18:03.000000000 +0300 @@ -70,6 +70,11 @@ $(do_perl_subst) <$< >$@ chmod +x $@ +%.pl: %.pl.in Makefile + @test -d `dirname [EMAIL PROTECTED] || $(mkdir_p) `dirname [EMAIL PROTECTED] + $(do_perl_subst) <$< >$@ + chmod +x $@ + %: %.sh Makefile @test -d `dirname [EMAIL PROTECTED] || $(mkdir_p) `dirname [EMAIL PROTECTED] $(do_shell_subst) <$< >$@
dpkg-arch-alias-tests.tgz
Description: GNU Unix tar archive