On 2012-07-11 23:51, Guillem Jover wrote:
> On Tue, 2012-07-10 at 02:17:22 +0100, Wookey wrote:
>> +++ Guillem Jover [2012-05-12 04:46 +0200]:
>>> I've not checked the details of the current proposed patch, as I think
>>> the correct overall design should be agreed on first.
>>>
>>> I think I might have mentioned this before but I pondered about this
>>> in more general terms some time ago in:
>>>
>>>   <http://www.hadrons.org/~guillem/debian/docs/embedded.proposal>
>>>
>>> From those, adding something like profiles support is IMO the nicer and
>>> more generic solution, although it implies some infrastructure changes.
>>
>> OK. I've looked at this again (finally) and I'm inclined to agree that
>> it seems a lot nicer than adding lots of Build-Depends-StageN fields.
> 
> Thanks.
> 
>> As there are quite a lot of suggestions in the above doc, this is the
>> one I think Guillem is referring to and that seems good to me:
> 
> Sorry for not being more clear on this, I guess I thought it was more
> obvious from the previous context and it being the first option listed,
> I was referring to:
> 
>  * Introducing build profiles (the specific characters '<>' could be
>    changed, this is just an example):
> 
>    Build-Depends: huge (>= 1.0) [i386 arm] <!embedded !bootstrap>, tiny
> 
>    + Generic, it can solve other problems like bootstrapping.
>    + Does not duplicate information.
>    + Does not overload existing syntax.
>    + Does not have the problem of mixed positive and negative arches.
>    - This could only be deployed in Debian on etch+1 and started to be used
>      on etch+2, that does not mean it cannot be used elsewhere beforehand
>      given different release cycles.

Out of curiosity, I implemented the above.  As I was able to borrow some
of the architecture specifications parsing logic and interfaces, profile
spec parsing was pretty simple to add.

The attached alternative patch makes dpkg-checkbuilddeps and Dpkg::Deps
parse and reduce build profiles (e.g. "<!embedded !stage1>") and makes
dpkg-gencontrol add a new "Build-Profile" field (like the previously
proposed "Build-Stage" field) to packages built with a profile.

Added to dpkg-buildpackage and dpkg-checkbuilddeps is a "-P<profile>"
option.  dpkg-buildpackage sets a "DEB_BUILD_PROFILE" environment
variable (unless it is already set) which is used by dpkg-checkbuilddeps
and dpkg-gencontrol.  (The new variable again follows the interface for
setting a host arch.)

The changes have been tested by building a package using
dpkg-buildpackage (with a "-P" option) and by directly running
debian/rules (with "DEB_BUILD_PROFILE" set).

The patch does not verify that the profile chosen by the user is
actually specified in the package's control file.  I'm not sure if (or
where) that should be done, but it would be fairly easy to do by listing
the "profiles" keys of all build dependencies.  Is similar checking done
for the host arch?

To be clear, this patch (an implementation of Guillem's "build profiles"
proposal) is a possible alternative to the previously considered
options.  We're not yet sure if all of the bootstrap dependency
information can be easily expressed in this build profiles syntax; I'll
be working to help determine this in the coming days and weeks.

So although I'm not proposing this for immediate inclusion, we'd
appreciate feedback on the design and implementation.

-- 
P. J. McDermott                                        (_/@\_)    ,--.
http://www.pehjota.net/                           o    < o o >   / oo \
http://www.pehjota.net/contact.html                 o   \ `-/    | <> |.
                                                o o o    "~v    /_\--/_/
diff -Nru dpkg-1.16.7/debian/changelog dpkg-1.16.7+nmu1/debian/changelog
--- dpkg-1.16.7/debian/changelog        2012-07-02 15:23:31.000000000 -0400
+++ dpkg-1.16.7+nmu1/debian/changelog   2012-07-14 20:50:56.000000000 -0400
@@ -1,3 +1,10 @@
+dpkg (1.16.7+nmu1) UNRELEASED; urgency=low
+
+  * Non-maintainer upload.
+  * Add support for build profiles.
+
+ -- P. J. McDermott <p...@nac.net>  Sat, 14 Jul 2012 07:05:11 -0400
+
 dpkg (1.16.7) unstable; urgency=low
 
   [ Guillem Jover ]
diff -Nru dpkg-1.16.7/dpkg-deb/build.c dpkg-1.16.7+nmu1/dpkg-deb/build.c
--- dpkg-1.16.7/dpkg-deb/build.c        2012-06-30 03:21:47.000000000 -0400
+++ dpkg-1.16.7+nmu1/dpkg-deb/build.c   2012-07-14 22:29:56.000000000 -0400
@@ -296,6 +296,7 @@
   "Installer-Menu-Item",
   "Homepage",
   "Tag",
+  "Build-Profile",
   NULL
 };
 
diff -Nru dpkg-1.16.7/man/deb-src-control.5 
dpkg-1.16.7+nmu1/man/deb-src-control.5
--- dpkg-1.16.7/man/deb-src-control.5   2012-06-30 03:21:47.000000000 -0400
+++ dpkg-1.16.7+nmu1/man/deb-src-control.5      2012-07-14 12:53:03.000000000 
-0400
@@ -177,8 +177,9 @@
 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 ,
@@ -188,7 +189,8 @@
 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
diff -Nru dpkg-1.16.7/man/dpkg-buildpackage.1 
dpkg-1.16.7+nmu1/man/dpkg-buildpackage.1
--- dpkg-1.16.7/man/dpkg-buildpackage.1 2012-06-30 03:21:47.000000000 -0400
+++ dpkg-1.16.7+nmu1/man/dpkg-buildpackage.1    2012-07-14 20:31:45.000000000 
-0400
@@ -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 "2012-05-04" "Debian Project" "dpkg utilities"
+.TH dpkg\-buildpackage 1 "2012-07-14" "Debian Project" "dpkg utilities"
 .SH NAME
 dpkg\-buildpackage \- build binary or source packages from sources
 .
@@ -135,6 +135,10 @@
 of \-a or as a complement to override the default GNU system type
 of the target Debian architecture.
 .TP
+.BI \-P profile
+Specify the profile we build. The default behavior is to build for no
+specific profile.
+.TP
 .BI \-j jobs
 Number of jobs allowed to be run simultaneously, equivalent to the
 .BR make (1)
diff -Nru dpkg-1.16.7/man/dpkg-checkbuilddeps.1 
dpkg-1.16.7+nmu1/man/dpkg-checkbuilddeps.1
--- dpkg-1.16.7/man/dpkg-checkbuilddeps.1       2012-06-30 03:21:47.000000000 
-0400
+++ dpkg-1.16.7+nmu1/man/dpkg-checkbuilddeps.1  2012-07-14 20:31:32.000000000 
-0400
@@ -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 "2012-07-14" "Debian Project" "dpkg utilities"
 .SH NAME
 dpkg\-checkbuilddeps \- check build dependencies and conflicts
 .
@@ -61,6 +61,10 @@
 the control file is to be built for the given host architecture instead of
 the architecture of the current system.
 .TP
+.BI "\-P " profile
+Check build dependencies/conflicts assuming that the package described in
+the control file is to be built for the given build profile.
+.TP
 .BR \-? ", " \-\-help
 Show the usage message and exit.
 .TP
diff -Nru dpkg-1.16.7/scripts/Dpkg/Control/Fields.pm 
dpkg-1.16.7+nmu1/scripts/Dpkg/Control/Fields.pm
--- dpkg-1.16.7/scripts/Dpkg/Control/Fields.pm  2012-06-30 03:21:47.000000000 
-0400
+++ dpkg-1.16.7+nmu1/scripts/Dpkg/Control/Fields.pm     2012-07-14 
22:31:04.000000000 -0400
@@ -91,6 +91,9 @@
         dependency => 'normal',
         dep_order => 3,
     },
+    'Build-Profile' => {
+        allowed => ALL_PKG,
+    },
     'Built-Using' => {
         allowed => ALL_PKG,
         dependency => 'union',
diff -Nru dpkg-1.16.7/scripts/Dpkg/Deps.pm dpkg-1.16.7+nmu1/scripts/Dpkg/Deps.pm
--- dpkg-1.16.7/scripts/Dpkg/Deps.pm    2012-06-30 03:21:47.000000000 -0400
+++ dpkg-1.16.7+nmu1/scripts/Dpkg/Deps.pm       2012-07-14 07:44:46.000000000 
-0400
@@ -286,6 +286,8 @@
     $options{use_arch} = 1 if not exists $options{use_arch};
     $options{reduce_arch} = 0 if not exists $options{reduce_arch};
     $options{host_arch} = get_host_arch() if not exists $options{host_arch};
+    $options{reduce_profile} = 0 if not exists $options{reduce_profile};
+    $options{build_profile} = '' if not exists $options{build_profile};
     $options{union} = 0 if not exists $options{union};
     $options{build_dep} = 0 if not exists $options{build_dep};
 
@@ -299,6 +301,8 @@
         foreach my $dep_or (split(/\s*\|\s*/m, $dep_and)) {
            my $dep_simple = Dpkg::Deps::Simple->new($dep_or, host_arch =>
                                                     $options{host_arch},
+                                                    build_profile =>
+                                                    $options{build_profile},
                                                     build_dep =>
                                                     $options{build_dep});
            if (not defined $dep_simple->{package}) {
@@ -310,6 +314,10 @@
                $dep_simple->reduce_arch($options{host_arch});
                next if not $dep_simple->arch_is_concerned($options{host_arch});
            }
+            if ($options{reduce_profile}) {
+               $dep_simple->reduce_profile($options{build_profile});
+               next if not 
$dep_simple->profile_is_concerned($options{build_profile});
+           }
            push @or_list, $dep_simple;
         }
        next if not @or_list;
@@ -558,6 +566,7 @@
     $self->{'relation'} = undef;
     $self->{'version'} = undef;
     $self->{'arches'} = undef;
+    $self->{'profiles'} = undef;
     $self->{'archqual'} = undef;
 }
 
@@ -588,6 +597,11 @@
                 \s* (.*?)                   # don't parse architectures now
                 \s* \]                      # closing bracket
               )?                            # end of optional architecture
+              (?:                           # start of optional profile
+                \s* <                       # open bracket for profile
+                \s* (.*?)                   # don't parse profiles now
+                \s* >                       # closing bracket
+              )?                            # end of optional profile
              \s*$                          # trailing spaces at end
             /x;
     if (defined($2)) {
@@ -602,6 +616,9 @@
     if (defined($5)) {
        $self->{arches} = [ split(/\s+/, $5) ];
     }
+    if (defined($6)) {
+       $self->{profiles} = [ split(/\s+/, $6) ];
+    }
 }
 
 sub output {
@@ -616,6 +633,9 @@
     if (defined($self->{'arches'})) {
        $res .= " [" . join(" ", @{$self->{arches}}) . "]";
     }
+    if (defined($self->{'profiles'})) {
+       $res .= " <" . join(" ", @{$self->{profiles}}) . ">";
+    }
     if (defined($fh)) {
        print $fh $res;
     }
@@ -745,6 +765,45 @@
     }
 }
 
+sub profile_is_concerned {
+    my ($self, $build_profile) = @_;
+
+    return 0 if not defined $self->{package};  # Empty dep
+    return 1 if not defined $self->{profiles}; # Dep without profile spec
+
+    my $seen_profile = 0;
+    foreach my $profile (@{$self->{profiles}}) {
+       $profile=lc($profile);
+
+       if ($profile =~ /^!/) {
+           my $not_profile = $profile;
+           $not_profile =~ s/^!//;
+
+           if ($build_profile eq $not_profile) {
+               $seen_profile = 0;
+               last;
+           } else {
+               # !profile includes by default all other profiles
+               # unless they also appear in a !otherprofile
+               $seen_profile = 1;
+           }
+       } elsif ($build_profile eq $profile) {
+           $seen_profile = 1;
+           last;
+       }
+    }
+    return $seen_profile;
+}
+
+sub reduce_profile {
+    my ($self, $build_profile) = @_;
+    if (not $self->profile_is_concerned($build_profile)) {
+       $self->reset();
+    } else {
+       $self->{profiles} = undef;
+    }
+}
+
 sub get_evaluation {
     my ($self, $facts) = @_;
     return undef if not defined $self->{package};
diff -Nru dpkg-1.16.7/scripts/dpkg-buildpackage.pl 
dpkg-1.16.7+nmu1/scripts/dpkg-buildpackage.pl
--- dpkg-1.16.7/scripts/dpkg-buildpackage.pl    2012-07-02 14:48:55.000000000 
-0400
+++ dpkg-1.16.7+nmu1/scripts/dpkg-buildpackage.pl       2012-07-16 
20:10:23.000000000 -0400
@@ -83,6 +83,9 @@
   -a<arch>       Debian architecture we build for.
   -t<system>     set GNU system type.")
     . "\n\n" . _g(
+"Options passed to dpkg-checkbuilddeps:
+  -P<profile>    set profile we build.")
+    . "\n\n" . _g(
 "Options passed to dpkg-genchanges:
   -si (default)  source includes orig if new upstream.
   -sa            uploaded source always includes orig.
@@ -124,6 +127,7 @@
 my $buildtarget = 'build';
 my $binarytarget = 'binary';
 my $targetarch = my $targetgnusystem = '';
+my $buildprofile = '';
 my $call_target = '';
 my $call_target_as_root = 0;
 my (@checkbuilddep_opts, @changes_opts, @source_opts);
@@ -186,6 +190,8 @@
        $usepause = 1;
     } elsif (/^-a(.*)$/) {
        $targetarch = $1;
+    } elsif (/^-P(.*)$/) {
+       $buildprofile = $1;
     } elsif (/^-s[iad]$/) {
        push @changes_opts, $_;
     } elsif (/^-(?:s[insAkurKUR]|[zZ].*|i.*|I.*)$/) {
@@ -326,6 +332,10 @@
     $arch = mustsetvar($ENV{'DEB_HOST_ARCH'}, _g('host architecture'));
 }
 
+unless (defined $ENV{'DEB_BUILD_PROFILE'}) {
+    $ENV{'DEB_BUILD_PROFILE'} = $buildprofile;
+}
+
 # Preparation of environment stops here
 
 (my $sversion = $version) =~ s/^\d+://;
diff -Nru dpkg-1.16.7/scripts/dpkg-checkbuilddeps.pl 
dpkg-1.16.7+nmu1/scripts/dpkg-checkbuilddeps.pl
--- dpkg-1.16.7/scripts/dpkg-checkbuilddeps.pl  2012-06-30 03:21:47.000000000 
-0400
+++ dpkg-1.16.7+nmu1/scripts/dpkg-checkbuilddeps.pl     2012-07-14 
22:24:45.000000000 -0400
@@ -30,6 +30,7 @@
 use Dpkg::Arch qw(get_host_arch);
 use Dpkg::Deps;
 use Dpkg::Control::Info;
+use Dpkg::BuildEnv;
 
 textdomain("dpkg-dev");
 
@@ -51,6 +52,7 @@
   -c build-conf  use given string for build conflicts instead of
                  retrieving them from control file
   -a arch        assume given host architecture
+  -P profile     assume given build profile
   --admindir=<directory>
                  change the administrative directory.
   -?, --help     show this help message.
@@ -64,6 +66,7 @@
 my $ignore_bd_indep = 0;
 my ($bd_value, $bc_value);
 my $host_arch = get_host_arch();
+my $build_profile = Dpkg::BuildEnv::get('DEB_BUILD_PROFILE');
 if (!GetOptions('A' => \$ignore_bd_arch,
                 'B' => \$ignore_bd_indep,
                 'help|?' => sub { usage(); exit(0); },
@@ -71,6 +74,7 @@
                 'd=s' => \$bd_value,
                 'c=s' => \$bc_value,
                 'a=s' => \$host_arch,
+                'P=s' => \$build_profile,
                 'admindir=s' => \$admindir)) {
        usage();
        exit(2);
@@ -113,12 +117,14 @@
 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);
+                          reduce_arch => 1, build_profile => $build_profile,
+                          reduce_profile => 1), $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);
+                          reduce_arch => 1, build_profile => $build_profile,
+                          reduce_profile => 1, union => 1), $facts);
 }
 
 if (@unmet) {
diff -Nru dpkg-1.16.7/scripts/dpkg-gencontrol.pl 
dpkg-1.16.7+nmu1/scripts/dpkg-gencontrol.pl
--- dpkg-1.16.7/scripts/dpkg-gencontrol.pl      2012-07-02 15:02:20.000000000 
-0400
+++ dpkg-1.16.7+nmu1/scripts/dpkg-gencontrol.pl 2012-07-16 20:05:45.000000000 
-0400
@@ -37,6 +37,7 @@
 use Dpkg::Substvars;
 use Dpkg::Vars;
 use Dpkg::Changelog::Parse;
+use Dpkg::BuildEnv;
 
 textdomain("dpkg-dev");
 
@@ -291,6 +292,9 @@
     }
 }
 
+my $buildprofile = Dpkg::BuildEnv::get('DEB_BUILD_PROFILE');
+$fields->{'Build-Profile'} = $buildprofile unless !$buildprofile;
+
 for my $f (qw(Package Version)) {
     defined($fields->{$f}) || error(_g("missing information for output field 
%s"), $f);
 }

Reply via email to