summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Dpkg/BuildProfiles.pm82
-rw-r--r--scripts/Dpkg/Control/FieldsCore.pm11
-rw-r--r--scripts/Dpkg/Deps.pm98
-rw-r--r--scripts/Makefile.am1
-rwxr-xr-xscripts/dpkg-buildpackage.pl7
-rwxr-xr-xscripts/dpkg-checkbuilddeps.pl18
-rwxr-xr-xscripts/dpkg-genchanges.pl3
-rwxr-xr-xscripts/dpkg-gencontrol.pl11
-rwxr-xr-xscripts/dpkg-shlibdeps.pl2
-rw-r--r--scripts/t/400_Dpkg_Deps.t22
10 files changed, 243 insertions, 12 deletions
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');