diff options
-rw-r--r-- | debian/changelog | 8 | ||||
-rw-r--r-- | dpkg-deb/build.c | 1 | ||||
-rw-r--r-- | man/deb-src-control.5 | 14 | ||||
-rw-r--r-- | man/dpkg-buildpackage.1 | 14 | ||||
-rw-r--r-- | man/dpkg-checkbuilddeps.1 | 15 | ||||
-rw-r--r-- | scripts/Dpkg/BuildProfiles.pm | 82 | ||||
-rw-r--r-- | scripts/Dpkg/Control/FieldsCore.pm | 11 | ||||
-rw-r--r-- | scripts/Dpkg/Deps.pm | 98 | ||||
-rw-r--r-- | scripts/Makefile.am | 1 | ||||
-rwxr-xr-x | scripts/dpkg-buildpackage.pl | 7 | ||||
-rwxr-xr-x | scripts/dpkg-checkbuilddeps.pl | 18 | ||||
-rwxr-xr-x | scripts/dpkg-genchanges.pl | 3 | ||||
-rwxr-xr-x | scripts/dpkg-gencontrol.pl | 11 | ||||
-rwxr-xr-x | scripts/dpkg-shlibdeps.pl | 2 | ||||
-rw-r--r-- | scripts/t/400_Dpkg_Deps.t | 22 |
15 files changed, 289 insertions, 18 deletions
diff --git a/debian/changelog b/debian/changelog index aba5303ba..d64383cb3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -109,6 +109,14 @@ dpkg (1.17.2) UNRELEASED; urgency=low the array in a subsequent package processing. Closes: #726112 * Do not accept empty field names in dpkg. * Do not accept an initial hyphen in field names. + * Add experimental build profiles support: + - Add support for <!profile.name> build-time restrictions in dependencies. + - Add support for DEB_BUILD_PROFILES environment variable. + - Add new option -P to dpkg-buildpackage and dpkg-checbuilddeps. + - Add new Built-For-Profiles output field in .deb and .changes files. + Based on a patch by Patrick "P. J." McDermott <pjm@nac.net>, + Wookey <wookey@debian.org> and Johannes Schauer <j.schauer@email.de>. + Closes: #661538 [ Updated programs translations ] * German (Sven Joachim). diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c index 8e84a9d55..b071fd358 100644 --- a/dpkg-deb/build.c +++ b/dpkg-deb/build.c @@ -339,6 +339,7 @@ check_conffiles(const char *dir) } static const char *arbitrary_fields[] = { + "Built-For-Profiles", "Built-Using", "Package-Type", "Subarchitecture", diff --git a/man/deb-src-control.5 b/man/deb-src-control.5 index d924985df..9b6d2ddc2 100644 --- a/man/deb-src-control.5 +++ b/man/deb-src-control.5 @@ -17,7 +17,7 @@ .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. . -.TH deb\-src\-control 5 "2013-04-02" "Debian Project" "Debian" +.TH deb\-src\-control 5 "2013-09-17" "Debian Project" "Debian" .SH NAME deb\-src\-control \- Debian source packages' master control file format . @@ -172,8 +172,9 @@ fields is a list of groups of alternative packages. Each group is a list of packages separated by vertical bar (or "pipe") symbols, "|". The groups are separated by commas. Commas are to be read as "AND", and pipes as "OR", with pipes binding more tightly. Each package name is -optionally followed by a version number specification in parentheses and an -architecture specification in square brackets. +optionally followed by a version number specification in parentheses, an +architecture specification in square brackets, and a profile specification +in angle brackets. The syntax of the .BR Build\-Conflicts , @@ -183,7 +184,8 @@ and fields is a list of comma-separated package names, where the comma is read as an "AND". Specifying alternative packages using a "pipe" is not supported. Each package name is optionally followed by a version number specification in -parentheses and an architecture specification in square brackets. +parentheses, an architecture specification in square brackets, and a profile +specification in angle brackets. A version number may start with a ">>", in which case any later version will match, and may specify or omit the Debian packaging revision (separated @@ -195,6 +197,10 @@ A architecture specification consists of one or more architecture names, separated by whitespace. Exclamation marks may be prepended to each of the names, meaning "NOT". +A profile specification consists of one or more profile names, prefixed +with the "\fBprofile.\fP" namespace, separated by whitespace. Exclamation +marks may be prepended to each of the names, meaning "NOT". + Note that dependencies on packages in the .B build\-essential set can be omitted and that declaring build conflicts against them is diff --git a/man/dpkg-buildpackage.1 b/man/dpkg-buildpackage.1 index bd54c1051..c31c5cd7e 100644 --- a/man/dpkg-buildpackage.1 +++ b/man/dpkg-buildpackage.1 @@ -19,7 +19,7 @@ .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. . -.TH dpkg\-buildpackage 1 "2013-08-31" "Debian Project" "dpkg utilities" +.TH dpkg\-buildpackage 1 "2013-09-17" "Debian Project" "dpkg utilities" .SH NAME dpkg\-buildpackage \- build binary or source packages from sources . @@ -131,6 +131,13 @@ Specify the GNU system type we build for. It can be used in place of \-a or as a complement to override the default GNU system type of the target Debian architecture. .TP +.BR \-P \fIprofile\fP[ , ...] +Specify the profile(s) we build, as a comma-separated list, without the +"\fBprofile.\fP" namespace prefix. The default behavior is to build for +no specific profile. Also adds them (as a space separated list) to the +\fBDEB_BUILD_PROFILES\fP environment variable which allows, for example, +\fBdebian/rules\fP files to use this information for conditional builds. +.TP .BI \-j jobs Number of jobs allowed to be run simultaneously, equivalent to the .BR make (1) @@ -247,6 +254,11 @@ Show the version and exit. .B DEB_SIGN_KEYID If set, it will be used to sign the \fB.changes\fP and \fB.dsc\fP files. Overridden by the \fB\-k\fP option. +.TP +.B DEB_BUILD_PROFILES +If set, it will be used as the active build profile(s) for the package +being built. It is a space separated list of profile names, without the +"\fBprofile.\fP" namespace prefix. Overridden by the \fB\-P\fP option. .SS Reliance on exported environment flags Even if \fBdpkg\-buildpackage\fP exports some variables, \fBdebian/rules\fP diff --git a/man/dpkg-checkbuilddeps.1 b/man/dpkg-checkbuilddeps.1 index 41862d697..6b41acce5 100644 --- a/man/dpkg-checkbuilddeps.1 +++ b/man/dpkg-checkbuilddeps.1 @@ -17,7 +17,7 @@ .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. . -.TH dpkg\-checkbuilddeps 1 "2012-05-22" "Debian Project" "dpkg utilities" +.TH dpkg\-checkbuilddeps 1 "2013-09-17" "Debian Project" "dpkg utilities" .SH NAME dpkg\-checkbuilddeps \- check build dependencies and conflicts . @@ -61,8 +61,21 @@ Check build dependencies/conflicts assuming that the package described in the control file is to be built for the given host architecture instead of the architecture of the current system. .TP +.BR "\-P " \fIprofile\fP[ , ...] +Check build dependencies/conflicts assuming that the package described +in the control file is to be built for the given build profile(s). The +argument is a comma-separated list of profile names, without the +"\fBprofile.\fP" namespace prefix. +.TP .BR \-? ", " \-\-help Show the usage message and exit. .TP .BR \-\-version Show the version and exit. +. +.SH ENVIRONMENT +.TP +.B DEB_BUILD_PROFILES +If set, it will be used as the active build profile(s) for the package +being built. It is a space separated list of profile names, without the +"\fBprofile.\fP" namespace prefix. Overridden by the \fB\-P\fP option. diff --git a/scripts/Dpkg/BuildProfiles.pm b/scripts/Dpkg/BuildProfiles.pm new file mode 100644 index 000000000..491cef16d --- /dev/null +++ b/scripts/Dpkg/BuildProfiles.pm @@ -0,0 +1,82 @@ +# Copyright © 2013 Guillem Jover <guillem@debian.org> +# +# 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 2 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/>. + +package Dpkg::BuildProfiles; + +use strict; +use warnings; + +our $VERSION = '0.01'; +our @EXPORT_OK = qw(get_build_profiles set_build_profiles); + +use Exporter qw(import); + +use Dpkg::BuildEnv; + +my $cache_profiles; +my @build_profiles; + +=encoding utf8 + +=head1 NAME + +Dpkg::BuildProfiles - handle build profiles + +=head1 DESCRIPTION + +The Dpkg::BuildProfiles module provides functions to handle the build +profiles. + +=head1 FUNCTIONS + +=over 4 + +=item my @profiles = get_build_profiles() + +Get an array with the currently active build profiles, taken from +the environment variable B<DEB_BUILD_PROFILES>. + +=cut + +sub get_build_profiles { + return @build_profiles if $cache_profiles; + + if (Dpkg::BuildEnv::has('DEB_BUILD_PROFILES')) { + @build_profiles = split / /, Dpkg::BuildEnv::get('DEB_BUILD_PROFILES'); + } + $cache_profiles = 1; + + return @build_profiles; +} + +=item set_build_profiles(@profiles) + +Set C<@profiles> as the current active build profiles, by setting +the environment variable B<DEB_BUILD_PROFILES>. + +=cut + +sub set_build_profiles { + my (@profiles) = @_; + + @build_profiles = @profiles; + Dpkg::BuildEnv::set('DEB_BUILD_PROFILES', join ' ', @profiles); +} + +=back + +=cut + +1; diff --git a/scripts/Dpkg/Control/FieldsCore.pm b/scripts/Dpkg/Control/FieldsCore.pm index e0124fcd8..a8d63e0ef 100644 --- a/scripts/Dpkg/Control/FieldsCore.pm +++ b/scripts/Dpkg/Control/FieldsCore.pm @@ -111,6 +111,10 @@ our %FIELDS = ( dependency => 'normal', dep_order => 3, }, + 'Built-For-Profiles' => { + allowed => ALL_PKG | CTRL_FILE_CHANGES, + separator => FIELD_SEP_SPACE, + }, 'Built-Using' => { allowed => ALL_PKG, separator => FIELD_SEP_COMMA, @@ -337,7 +341,8 @@ my @sum_fields = map { $_ eq 'md5' ? 'MD5sum' : &field_capitalize($_) } our %FIELD_ORDER = ( CTRL_PKG_DEB() => [ qw(Package Package-Type Source Version Built-Using Kernel-Version - Architecture Subarchitecture Installer-Menu-Item Essential Origin Bugs + Built-For-Profiles Architecture Subarchitecture + Installer-Menu-Item Essential Origin Bugs Maintainer Installed-Size), &field_list_pkg_dep(), qw(Section Priority Multi-Arch Homepage Description Tag Task) ], @@ -349,8 +354,8 @@ our %FIELD_ORDER = ( @checksum_fields, qw(Files) ], CTRL_FILE_CHANGES() => [ - qw(Format Date Source Binary Binary-Only Architecture Version - Distribution Urgency Maintainer Changed-By Description + qw(Format Date Source Binary Binary-Only Built-For-Profiles Architecture + Version Distribution Urgency Maintainer Changed-By Description Closes Changes), @checksum_fields, qw(Files) ], diff --git a/scripts/Dpkg/Deps.pm b/scripts/Dpkg/Deps.pm index 356ea8301..7fefd109b 100644 --- a/scripts/Dpkg/Deps.pm +++ b/scripts/Dpkg/Deps.pm @@ -53,6 +53,7 @@ our $VERSION = '1.02'; use Dpkg::Version; use Dpkg::Arch qw(get_host_arch get_build_arch); +use Dpkg::BuildProfiles qw(get_build_profiles); use Dpkg::ErrorHandling; use Dpkg::Gettext; @@ -195,6 +196,30 @@ architecture. This implicitely strips off the architecture restriction list so that the resulting dependencies are directly applicable to the current architecture. +=item use_profiles (defaults to 1) + +Take into account the profile restriction part of the dependencies. Set +to 0 to completely ignore that information. + +=item build_profiles (defaults to no profile) + +Define the active build profiles. By default no profile is defined. + +=item reduce_profiles (defaults to 0) + +If set to 1, ignore dependencies that do not concern the current build +profile. This implicitly strips off the profile restriction list so +that the resulting dependencies are directly applicable to the current +profiles. + +=item reduce_restrictions (defaults to 0) + +If set to 1, ignore dependencies that do not concern the current set of +restrictions. This implicitly strips off any restriction list so that the +resulting dependencies are directly applicable to the current restriction. +This currently implies C<reduce_arch> and C<reduce_profiles>, and overrides +them if set. + =item union (defaults to 0) If set to 1, returns a Dpkg::Deps::Union instead of a Dpkg::Deps::AND. Use @@ -216,9 +241,19 @@ sub deps_parse { $options{reduce_arch} = 0 if not exists $options{reduce_arch}; $options{host_arch} = get_host_arch() if not exists $options{host_arch}; $options{build_arch} = get_build_arch() if not exists $options{build_arch}; + $options{use_profiles} = 1 if not exists $options{use_profiles}; + $options{reduce_profiles} = 0 if not exists $options{reduce_profiles}; + $options{build_profiles} = [ get_build_profiles() ] + if not exists $options{build_profiles}; + $options{reduce_restrictions} = 0 if not exists $options{reduce_restrictions}; $options{union} = 0 if not exists $options{union}; $options{build_dep} = 0 if not exists $options{build_dep}; + if ($options{reduce_restrictions}) { + $options{reduce_arch} = 1; + $options{reduce_profiles} = 1; + } + # Strip trailing/leading spaces $dep_line =~ s/^\s+//; $dep_line =~ s/\s+$//; @@ -242,6 +277,11 @@ sub deps_parse { $dep_simple->reduce_arch($options{host_arch}); next if not $dep_simple->arch_is_concerned($options{host_arch}); } + $dep_simple->{restrictions} = undef if not $options{use_profiles}; + if ($options{reduce_profiles}) { + $dep_simple->reduce_profiles($options{build_profiles}); + next if not $dep_simple->profile_is_concerned($options{build_profiles}); + } push @or_list, $dep_simple; } next if not @or_list; @@ -470,6 +510,7 @@ use Dpkg::Arch qw(debarch_is); use Dpkg::Version; use Dpkg::ErrorHandling; use Dpkg::Gettext; +use Dpkg::Util qw(:list); use parent qw(Dpkg::Interface::Storable); @@ -493,6 +534,7 @@ sub reset { $self->{version} = undef; $self->{arches} = undef; $self->{archqual} = undef; + $self->{restrictions} = undef; } sub parse { @@ -522,6 +564,11 @@ sub parse_string { \s* (.*?) # don't parse architectures now \s* \] # closing bracket )? # end of optional architecture + (?: # start of optional restriction + \s* < # open bracket for restriction + \s* (.*?) # don't parse restrictions now + \s* > # closing bracket + )? # end of optional restriction \s*$ # trailing spaces at end }x; if (defined($2)) { @@ -536,6 +583,9 @@ sub parse_string { if (defined($5)) { $self->{arches} = [ split(/\s+/, $5) ]; } + if (defined($6)) { + $self->{restrictions} = [ map { lc } split /\s+/, $6 ]; + } } sub output { @@ -550,6 +600,9 @@ sub output { if (defined($self->{arches})) { $res .= ' [' . join(' ', @{$self->{arches}}) . ']'; } + if (defined($self->{restrictions})) { + $res .= ' <' . join(' ', @{$self->{restrictions}}) . '>'; + } if (defined($fh)) { print { $fh } $res; } @@ -764,6 +817,51 @@ sub has_arch_restriction { } } +sub profile_is_concerned { + my ($self, $build_profiles) = @_; + + return 0 if not defined $self->{package}; # Empty dep + return 1 if not defined $self->{restrictions}; # Dep without restrictions + + my $seen_profile = 0; + foreach my $restriction (@{$self->{restrictions}}) { + # Determine if this restriction is negated, and within the "profile" + # namespace, otherwise it does not concern this check. + next if $restriction !~ m/^(!)?profile\.(.*)/; + + my $negated = defined $1 && $1 eq '!'; + my $profile = $2; + + # Determine if the restriction matches any of the specified profiles. + my $found = any { $_ eq $profile } @{$build_profiles}; + + if ($negated) { + if ($found) { + $seen_profile = 0; + last; + } else { + # "!profile.this" includes by default all other profiles + # unless they also appear in a "!profile.other". + $seen_profile = 1; + } + } elsif ($found) { + $seen_profile = 1; + last; + } + } + return $seen_profile; +} + +sub reduce_profiles { + my ($self, $build_profiles) = @_; + + if (not $self->profile_is_concerned($build_profiles)) { + $self->reset(); + } else { + $self->{restrictions} = undef; + } +} + sub get_evaluation { my ($self, $facts) = @_; return if not defined $self->{package}; diff --git a/scripts/Makefile.am b/scripts/Makefile.am index f83adfff3..aeba5b621 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -58,6 +58,7 @@ nobase_dist_perllib_DATA = \ Dpkg/BuildEnv.pm \ Dpkg/BuildFlags.pm \ Dpkg/BuildOptions.pm \ + Dpkg/BuildProfiles.pm \ Dpkg/Changelog.pm \ Dpkg/Changelog/Debian.pm \ Dpkg/Changelog/Entry.pm \ diff --git a/scripts/dpkg-buildpackage.pl b/scripts/dpkg-buildpackage.pl index 127107284..38df61e70 100755 --- a/scripts/dpkg-buildpackage.pl +++ b/scripts/dpkg-buildpackage.pl @@ -31,6 +31,7 @@ use Dpkg (); use Dpkg::Gettext; use Dpkg::ErrorHandling; use Dpkg::BuildOptions; +use Dpkg::BuildProfiles qw(set_build_profiles); use Dpkg::Compression; use Dpkg::Version; use Dpkg::Changelog::Parse; @@ -62,6 +63,7 @@ sub usage { -tc clean source tree when finished. -D (default) check build dependencies and conflicts. -d do not check build dependencies and conflicts. + -P<profiles> assume given build profiles as active (comma-separated list). -R<rules> rules file to execute (default is debian/rules). -T<target> call debian/rules <target> with the proper environment. --as-root ensure -T calls the target with root rights. @@ -123,6 +125,7 @@ my $signchanges = 1; my $buildtarget = 'build'; my $binarytarget = 'binary'; my $targetarch = my $targetgnusystem = ''; +my @build_profiles = (); my $call_target = ''; my $call_target_as_root = 0; my (@checkbuilddep_opts, @changes_opts, @source_opts); @@ -187,6 +190,8 @@ while (@ARGV) { $usepause = 1; } elsif (/^-a(.*)$/) { $targetarch = $1; + } elsif (/^-P(.*)$/) { + @build_profiles = split /,/, $1; } elsif (/^-s[iad]$/) { push @changes_opts, $_; } elsif (/^-(?:s[insAkurKUR]|[zZ].*|i.*|I.*)$/) { @@ -283,6 +288,8 @@ if (defined $parallel) { $build_opts->export(); } +set_build_profiles(@build_profiles) if @build_profiles; + my $cwd = cwd(); my $dir = basename($cwd); diff --git a/scripts/dpkg-checkbuilddeps.pl b/scripts/dpkg-checkbuilddeps.pl index 72485e8e4..cf5ef2735 100755 --- a/scripts/dpkg-checkbuilddeps.pl +++ b/scripts/dpkg-checkbuilddeps.pl @@ -28,6 +28,7 @@ use Dpkg (); use Dpkg::Gettext; use Dpkg::ErrorHandling; use Dpkg::Arch qw(get_host_arch); +use Dpkg::BuildProfiles qw(get_build_profiles set_build_profiles); use Dpkg::Deps; use Dpkg::Control::Info; @@ -51,6 +52,7 @@ sub usage { -c build-conf use given string for build conflicts instead of retrieving them from control file -a arch assume given host architecture + -P profiles assume given build profiles (comma-separated list) --admindir=<directory> change the administrative directory. -?, --help show this help message. @@ -63,6 +65,7 @@ sub usage { my $ignore_bd_arch = 0; my $ignore_bd_indep = 0; my ($bd_value, $bc_value); +my $bp_value; my $host_arch = get_host_arch(); my $admindir = $Dpkg::ADMINDIR; my @options_spec = ( @@ -73,6 +76,7 @@ my @options_spec = ( 'd=s' => \$bd_value, 'c=s' => \$bc_value, 'a=s' => \$host_arch, + 'P=s' => \$bp_value, 'admindir=s' => \$admindir, ); @@ -81,6 +85,10 @@ my @options_spec = ( GetOptions(@options_spec); } +# Update currently active build profiles. +set_build_profiles(split(/,/, $bp_value)) if ($bp_value); +my @build_profiles = get_build_profiles(); + my $controlfile = shift || 'debian/control'; my $control = Dpkg::Control::Info->new($controlfile); @@ -103,13 +111,15 @@ my (@unmet, @conflicts); if ($bd_value) { push @unmet, build_depends('Build-Depends/Build-Depends-Arch/Build-Depends-Indep', - deps_parse($bd_value, build_dep => 1, host_arch => $host_arch, - reduce_arch => 1), $facts); + deps_parse($bd_value, reduce_restrictions => 1, build_dep => 1, + build_profiles => \@build_profiles, + host_arch => $host_arch), $facts); } if ($bc_value) { push @conflicts, build_conflicts('Build-Conflicts/Build-Conflicts-Arch/Build-Conflicts-Indep', - deps_parse($bc_value, build_dep => 1, host_arch => $host_arch, - reduce_arch => 1, union => 1), $facts); + deps_parse($bc_value, reduce_restrictions => 1, build_dep => 1, + build_profiles => \@build_profiles, union => 1, + host_arch => $host_arch), $facts); } if (@unmet) { diff --git a/scripts/dpkg-genchanges.pl b/scripts/dpkg-genchanges.pl index 808218b4a..1d6b00fcf 100755 --- a/scripts/dpkg-genchanges.pl +++ b/scripts/dpkg-genchanges.pl @@ -30,6 +30,7 @@ use Dpkg::Util qw(:list); use Dpkg::File; use Dpkg::Checksums; use Dpkg::ErrorHandling; +use Dpkg::BuildProfiles qw(get_build_profiles); use Dpkg::Arch qw(get_host_arch debarch_eq debarch_is); use Dpkg::Compression; use Dpkg::Control::Info; @@ -470,6 +471,8 @@ unshift(@archvalues,'source') unless is_binaryonly; unless $include & ARCH_INDEP; $fields->{'Architecture'} = join(' ',@archvalues); +$fields->{'Built-For-Profiles'} = join ' ', get_build_profiles(); + $fields->{'Description'} = "\n" . join("\n", sort @descriptions); $fields->{'Files'} = ''; diff --git a/scripts/dpkg-gencontrol.pl b/scripts/dpkg-gencontrol.pl index 5d08a39a7..00477089c 100755 --- a/scripts/dpkg-gencontrol.pl +++ b/scripts/dpkg-gencontrol.pl @@ -30,6 +30,7 @@ use Dpkg::Util qw(:list); use Dpkg::File; use Dpkg::Arch qw(get_host_arch debarch_eq debarch_is); use Dpkg::Package; +use Dpkg::BuildProfiles qw(get_build_profiles); use Dpkg::Deps; use Dpkg::Control; use Dpkg::Control::Info; @@ -253,7 +254,7 @@ $facts->add_installed_package($fields->{'Package'}, $fields->{'Version'}, $fields->{'Architecture'}, $fields->{'Multi-Arch'}); if (exists $pkg->{'Provides'}) { my $provides = deps_parse($substvars->substvars($pkg->{'Provides'}, no_warn => 1), - reduce_arch => 1, union => 1); + reduce_restrictions => 1, union => 1); if (defined $provides) { foreach my $subdep ($provides->get_deps()) { if ($subdep->isa('Dpkg::Deps::Simple')) { @@ -275,7 +276,8 @@ foreach my $field (field_list_pkg_dep()) { msg_prefix => sprintf(_g('%s field of package %s: '), $field, $pkg->{Package})); if (field_get_dep_type($field) eq 'normal') { $dep = deps_parse($field_value, use_arch => 1, - reduce_arch => $reduce_arch); + reduce_arch => $reduce_arch, + reduce_profiles => 1); error(_g('error occurred while parsing %s field: %s'), $field, $field_value) unless defined $dep; $dep->simplify_deps($facts, @seen_deps); @@ -283,7 +285,8 @@ foreach my $field (field_list_pkg_dep()) { push @seen_deps, $dep; } else { $dep = deps_parse($field_value, use_arch => 1, - reduce_arch => $reduce_arch, union => 1); + reduce_arch => $reduce_arch, + reduce_profiles => 1, union => 1); error(_g('error occurred while parsing %s field: %s'), $field, $field_value) unless defined $dep; $dep->simplify_deps($facts); @@ -297,6 +300,8 @@ foreach my $field (field_list_pkg_dep()) { } } +$fields->{'Built-For-Profiles'} = join ' ', get_build_profiles(); + for my $f (qw(Package Version)) { error(_g('missing information for output field %s'), $f) unless defined $fields->{$f}; diff --git a/scripts/dpkg-shlibdeps.pl b/scripts/dpkg-shlibdeps.pl index 7129dc2b5..25f5d1e98 100755 --- a/scripts/dpkg-shlibdeps.pl +++ b/scripts/dpkg-shlibdeps.pl @@ -147,7 +147,7 @@ usageerr(_g('need at least one executable')) unless scalar keys %exec; my $control = Dpkg::Control::Info->new(); my $fields = $control->get_source(); my $bd_value = deps_concat($fields->{'Build-Depends'}, $fields->{'Build-Depends-Arch'}); -my $build_deps = deps_parse($bd_value, build_dep => 1, reduce_arch => 1); +my $build_deps = deps_parse($bd_value, build_dep => 1, reduce_restrictions => 1); error(_g('error occurred while parsing %s'), 'Build-Depends/Build-Depends-Arch') unless defined $build_deps; diff --git a/scripts/t/400_Dpkg_Deps.t b/scripts/t/400_Dpkg_Deps.t index b37a1c607..e4ea16971 100644 --- a/scripts/t/400_Dpkg_Deps.t +++ b/scripts/t/400_Dpkg_Deps.t @@ -16,7 +16,7 @@ use strict; use warnings; -use Test::More tests => 20; +use Test::More tests => 25; use Dpkg::Arch qw(get_host_arch); use_ok('Dpkg::Deps'); @@ -58,6 +58,26 @@ is($dep_i386->output(), 'libc6 (>= 2.5)', 'Arch reduce 1/3'); is($dep_alpha->output(), 'libc6.1', 'Arch reduce 2/3'); is($dep_hurd->output(), 'libc0.1', 'Arch reduce 3/3'); +my $field_profile = 'dep1 <!profile.stage1 !profile.notest>, ' . +'dep2 <profile.stage1 !profile.notest>, ' . +'dep3 <profile.notest !profile.stage1>, ' . +'dep4 <profile.stage1 profile.notest>, ' . +'dep5 <profile.stage1>, dep6 <!profile.stage1>'; +my $dep_noprof = deps_parse($field_profile, reduce_profiles => 1, build_profiles => []); +my $dep_stage1 = deps_parse($field_profile, reduce_profiles => 1, build_profiles => ['stage1']); +my $dep_notest = deps_parse($field_profile, reduce_profiles => 1, build_profiles => ['notest']); +my $dep_stage1notest = deps_parse($field_profile, reduce_profiles => 1, build_profiles => ['stage1', 'notest']); +is($dep_noprof->output(), 'dep1, dep2, dep3, dep6', 'Profile reduce 1/4'); +is($dep_stage1->output(), 'dep2, dep4, dep5', 'Profile reduce 2/4'); +is($dep_notest->output(), 'dep3, dep4, dep6', 'Profile reduce 3/4'); +is($dep_stage1notest->output(), 'dep2, dep3, dep4, dep5', 'Profile reduce 4/4'); + +my $field_restrict = 'dep1 <!profile.bootstrap !other.restrict>, ' . +'dep2 <profile.bootstrap other.restrict>, ' . +'dep3 <!other.restrict>, ' . +'dep4 <other.restrict>'; +my $dep_restrict = deps_parse($field_restrict, reduce_restrictions => 1, build_profiles => []); +is($dep_restrict->output(), 'dep1', 'Unknown restrictions reduce'); my $facts = Dpkg::Deps::KnownFacts->new(); $facts->add_installed_package('mypackage', '1.3.4-1', get_host_arch(), 'no'); |