* Raphael Hertzog <hert...@debian.org> [120316 09:36]:
> Suggestion of a better sentence:
> Reworded:

incorporated
> IMO this is not the proper way to extract it automatically. If you want
> this feature, you should add a unique (and fixed) start/end marker.
>
> Maybe something like this ?
>
> --- BEGIN DPKG-BUILDFLAGS STATUS ---
> […]
> --- END DPKG-BUILDFLAGS STATUS ---

Things requiring context like that are no fun to parse at all. You
cannot grep them, a line parser needs additional context.

> If you really want to keep the "dpkg-builflags: " prefix, then you should
> use one of the functions exported by Dpkg::ErrorHandling. But I don't
> think it's required.

That seems to always want to output some extra (at least a colon) and
most even seem to have localized messages, so do not look very
suiteable.

> You can easily do that... instead of hardcoding it here, create
> a new vendor hook for this purpose. Either the vendor hook
> allows to extend your @envvars or it prints directly supplementary
> information to include...

done.

> And indeed I was puzzled by seeing DEB_BUILD_HARDENING but realized thanks
> to your comment that it was only relevant for Ubuntu...

Actually I seem to have read that part to fast. It seems to be a output
and not a input variable...

> > +   # note that DEB_*_MAINT_* currently is not reflected
> > +   # by $origin...
>
> This was on purpose. It's a choice of the maintainer and thus of the
> vendor. And since it happens at the end, it would hide any
> user/system-wide customization... and I don't want this.

Added a patch on top of it to show more information here.

I've split the first one into preparations to the infrastructure and
the --status introduction. If you prefer them merged let me know...

        Bernhard R. Link
>From d21eed0dcf768d1f6509eb799ee6929a7f1147fe Mon Sep 17 00:00:00 2001
From: "Bernhard R. Link" <brl...@debian.org>
Date: Fri, 16 Mar 2012 09:56:52 +0100
Subject: [PATCH 1/4] Dpkg::BuildFlags: add get_feature_areas()

Add a way a caller can enumerate all possible values for get_features().

Signed-off-by: Bernhard R. Link <brl...@debian.org>
---
 scripts/Dpkg/BuildFlags.pm |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/scripts/Dpkg/BuildFlags.pm b/scripts/Dpkg/BuildFlags.pm
index 3800470..31a54d9 100644
--- a/scripts/Dpkg/BuildFlags.pm
+++ b/scripts/Dpkg/BuildFlags.pm
@@ -320,6 +320,18 @@ sub get {
     return $self->{'flags'}{$key};
 }
 
+=item $bf->get_feature_areas()
+
+Return the feature areas
+(i.e. the area values has_features will return true for).
+
+=cut
+
+sub get_feature_areas {
+    my ($self) = @_;
+    return keys $self->{'features'};
+}
+
 =item $bf->get_features($area)
 
 Return, for the given area, a hash with keys as feature names, and values
@@ -392,7 +404,8 @@ based on the package maintainer directives.
 
 =head Version 1.02
 
-New methods: $bf->get_features(), $bf->has_features(), $bf->set_feature().
+New methods: $bf->get_features(), $bf->has_features(), $bf->set_feature(),
+  $bf->get_feature_areas().
 
 =head1 AUTHOR
 
-- 
1.7.9.1

>From f9b17acfd98f0c539f0f70d204397963ab09e9dc Mon Sep 17 00:00:00 2001
From: "Bernhard R. Link" <brl...@debian.org>
Date: Fri, 16 Mar 2012 10:23:38 +0100
Subject: [PATCH 2/4] Dpkg::BuildFlags: record environment variables looked at

Record environment variables looked at by Dpkg::BuildFlags and
the vendor hooks and make them available via the new
get_used_environment().

Signed-off-by: Bernhard R. Link <brl...@debian.org>
---
 scripts/Dpkg/BuildFlags.pm    |   39 ++++++++++++++++++++++++++++++++++++++-
 scripts/Dpkg/Vendor/Debian.pm |    1 +
 scripts/Dpkg/Vendor/Ubuntu.pm |    1 +
 3 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/scripts/Dpkg/BuildFlags.pm b/scripts/Dpkg/BuildFlags.pm
index 31a54d9..4a84c57 100644
--- a/scripts/Dpkg/BuildFlags.pm
+++ b/scripts/Dpkg/BuildFlags.pm
@@ -69,7 +69,9 @@ sub load_vendor_defaults {
     $self->{'options'} = {};
     $self->{'source'} = {};
     $self->{'features'} = {};
+    $self->{'used_envs'} = {};
     my $build_opts = Dpkg::BuildOptions->new();
+    $self->environment_used("DEB_BUILD_OPTIONS");
     my $default_flags = $build_opts->has("noopt") ? "-g -O0" : "-g -O2";
     $self->{flags} = {
 	CPPFLAGS => '',
@@ -87,6 +89,8 @@ sub load_vendor_defaults {
     };
     # The Debian vendor hook will add hardening build flags
     run_vendor_hook("update-buildflags", $self);
+    # run_vendor_hook looked at DEB_VENDOR
+    $self->environment_used("DEB_VENDOR");
 }
 
 =item $bf->load_system_config()
@@ -126,18 +130,22 @@ sub load_environment_config {
     my ($self) = @_;
     foreach my $flag (keys %{$self->{flags}}) {
 	my $envvar = "DEB_" . $flag . "_SET";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->set($flag, $ENV{$envvar}, "env");
 	}
 	$envvar = "DEB_" . $flag . "_STRIP";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->strip($flag, $ENV{$envvar}, "env");
 	}
 	$envvar = "DEB_" . $flag . "_APPEND";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->append($flag, $ENV{$envvar}, "env");
 	}
 	$envvar = "DEB_" . $flag . "_PREPEND";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->prepend($flag, $ENV{$envvar}, "env");
 	}
@@ -155,18 +163,22 @@ sub load_maintainer_config {
     my ($self) = @_;
     foreach my $flag (keys %{$self->{flags}}) {
 	my $envvar = "DEB_" . $flag . "_MAINT_SET";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->set($flag, $ENV{$envvar}, undef);
 	}
 	$envvar = "DEB_" . $flag . "_MAINT_STRIP";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->strip($flag, $ENV{$envvar}, undef);
 	}
 	$envvar = "DEB_" . $flag . "_MAINT_APPEND";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->append($flag, $ENV{$envvar}, undef);
 	}
 	$envvar = "DEB_" . $flag . "_MAINT_PREPEND";
+	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
 	    $self->prepend($flag, $ENV{$envvar}, undef);
 	}
@@ -390,6 +402,31 @@ sub list {
     return sort keys %{$self->{'flags'}};
 }
 
+=item $bf->environment_used($envvar)
+
+Records that the given environment variable had influenced
+or could have influenced (if it had existed or had a different
+value) the calculated flags.
+
+=cut
+
+sub environment_used {
+    my ($self, $envvar) = @_;
+    $self->{'used_envs'}->{$envvar} = 1;
+}
+
+=item my @list = $bf->get_used_environment()
+
+Returns a list of all environment variables that had a
+possible influence.
+
+=cut
+
+sub get_used_environment {
+    my ($self) = @_;
+    return keys $self->{'used_envs'};
+}
+
 =back
 
 =head1 CHANGES
@@ -405,7 +442,7 @@ based on the package maintainer directives.
 =head Version 1.02
 
 New methods: $bf->get_features(), $bf->has_features(), $bf->set_feature(),
-  $bf->get_feature_areas().
+  $bf->get_feature_areas(), $bf->environment_used(), $bf->get_used_environment().
 
 =head1 AUTHOR
 
diff --git a/scripts/Dpkg/Vendor/Debian.pm b/scripts/Dpkg/Vendor/Debian.pm
index b4ce4cf..0a1ab8e 100644
--- a/scripts/Dpkg/Vendor/Debian.pm
+++ b/scripts/Dpkg/Vendor/Debian.pm
@@ -100,6 +100,7 @@ sub add_hardening_flags {
 
     # Adjust features based on Maintainer's desires.
     my $opts = Dpkg::BuildOptions->new(envvar => "DEB_BUILD_MAINT_OPTIONS");
+    $flags->environment_used("DEB_BUILD_MAINT_OPTIONS");
     foreach my $feature (split(",", $opts->get("hardening") // "")) {
 	$feature = lc($feature);
 	if ($feature =~ s/^([+-])//) {
diff --git a/scripts/Dpkg/Vendor/Ubuntu.pm b/scripts/Dpkg/Vendor/Ubuntu.pm
index 7e60fcf..8cf4569 100644
--- a/scripts/Dpkg/Vendor/Ubuntu.pm
+++ b/scripts/Dpkg/Vendor/Ubuntu.pm
@@ -108,6 +108,7 @@ sub run_hook {
 	$self->SUPER::run_hook($hook, $flags);
 
 	# Allow control of hardening-wrapper via dpkg-buildpackage DEB_BUILD_OPTIONS
+	$flags->used_environment("DEB_BUILD_OPTIONS");
 	my $build_opts = Dpkg::BuildOptions->new();
 	my $hardening;
 	if ($build_opts->has("hardening")) {
-- 
1.7.9.1

>From b90483512ca7181d8b72287ea669b281640d7314 Mon Sep 17 00:00:00 2001
From: "Bernhard R. Link" <brl...@debian.org>
Date: Thu, 15 Mar 2012 11:25:39 +0100
Subject: [PATCH 3/4] dpkg-buildflags: add --status action to describe what is
 happening

It's hard to see from a build log file what values should have been
used and why. The new --status action added by this tries to output
all meaningful information in way useful for human consumption
and for automatic log parsers.

Signed-off-by: Bernhard R. Link <brl...@debian.org>
---
 man/dpkg-buildflags.1      |   10 +++++++++
 scripts/dpkg-buildflags.pl |   47 +++++++++++++++++++++++++++++++++++++------
 2 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/man/dpkg-buildflags.1 b/man/dpkg-buildflags.1
index 4244b82..234d1cf 100644
--- a/man/dpkg-buildflags.1
+++ b/man/dpkg-buildflags.1
@@ -72,6 +72,16 @@ Print the list of flags supported by the current vendor
 (one per line). See the \fBSUPPORTED FLAGS\fP section for more
 information about them.
 .TP
+.BI \-\-status
+Display any information that can be useful to explain the behaviour
+of dpkg-buildflags:
+relevant environment variables, current vendor, state of all feature flags.
+Also print the resulting compiler flags with their origin.
+
+This is intended to be run from \fBdebian/rules\fP, so that the
+build log keeps a clear trace of the build flags used. This can
+be useful to diagnose problems related to them.
+.TP
 .BI \-\-export= format
 Print to standard output shell (if \fIformat\fP is \fBsh\fP) or make
 (if \fIformat\fP is \fBmake\fP) commands that can be used to export
diff --git a/scripts/dpkg-buildflags.pl b/scripts/dpkg-buildflags.pl
index d0f9fa8..66069a5 100755
--- a/scripts/dpkg-buildflags.pl
+++ b/scripts/dpkg-buildflags.pl
@@ -24,6 +24,7 @@ use Dpkg;
 use Dpkg::Gettext;
 use Dpkg::ErrorHandling;
 use Dpkg::BuildFlags;
+use Dpkg::Vendor qw(get_current_vendor);
 
 textdomain("dpkg-dev");
 
@@ -52,6 +53,9 @@ Actions:
                      compilation flags in a shell script, in make,
                      or on a ./configure command line.
   --dump             output all compilation flags with their values
+  --status           print a synopsis with all parameters affecting
+                     the behaviour of dpkg-buildflags and the resulting
+                     flags and their origin.
   --help             show this help message.
   --version          show the version.
 "), $progname;
@@ -72,14 +76,10 @@ while (@ARGV) {
             if defined($action);
         my $type = $1 || "sh";
         $action = "export-$type";
-    } elsif (m/^--dump$/) {
-        usageerr(_g("two commands specified: --%s and --%s"), "dump", $action)
-            if defined($action);
-        $action = "dump";
-    } elsif (m/^--list$/) {
-        usageerr(_g("two commands specified: --%s and --%s"), "list", $action)
+    } elsif (m/^--(list|status|dump)$/) {
+        usageerr(_g("two commands specified: --%s and --%s"), $1, $action)
             if defined($action);
-        $action = "list";
+        $action = $1;
     } elsif (m/^-(h|-help)$/) {
         usage();
         exit 0;
@@ -147,6 +147,39 @@ if ($action eq "get") {
 	print "$flag=$value\n";
     }
     exit(0);
+} elsif ($action eq "status") {
+    # prefix everything with "dpkg-buildflags: " to allow easy extraction
+    # from a buildd log.
+    # First print all environment variables that might have changed the
+    # results (only existing ones, might make sense to add a option to
+    # also show which could have set to modify it).
+    my @envvars = $build_flags->get_used_environment();
+    for my $envvar (@envvars) {
+	if (exists $ENV{$envvar}) {
+	    printf "dpkg-buildflags: environment variable %s=%s\n",
+				$envvar, $ENV{$envvar};
+	}
+    }
+    my $vendor = Dpkg::Vendor::get_current_vendor();
+    $vendor = "undefined" unless defined($vendor);
+    print "dpkg-buildflags: vendor is $vendor\n";
+    # Then the resulting features:
+    foreach my $area (sort $build_flags->get_feature_areas()) {
+	print "dpkg-buildflags: $area features:";
+	my %features = $build_flags->get_features($area);
+	foreach my $feature (sort keys %features) {
+	    printf " %s=%s", $feature, $features{$feature} ? "yes" : "no";
+	}
+	print "\n";
+    }
+    # Then the resulting values (with their origin):
+    foreach my $flag ($build_flags->list()) {
+	my $value = $build_flags->get($flag);
+	my $origin = $build_flags->get_origin($flag);
+	# Note that DEB_*_MAINT_* does not effect $origin.
+	print "dpkg-buildflags: $flag [$origin]: $value\n";
+    }
+    exit(0);
 }
 
 exit(1);
-- 
1.7.9.1

>From 6a600d3f9d2b438ca59d0e81f69b91249bd197b1 Mon Sep 17 00:00:00 2001
From: "Bernhard R. Link" <brl...@debian.org>
Date: Fri, 16 Mar 2012 11:05:17 +0100
Subject: [PATCH 4/4] dpkg-buildflags: make --status output which flags are
 modified by maintainer

As flags modified by DEB_*_MAINT_* are not reflected by its origin, add
a new flag to describe flags modified that way.

Signed-off-by: Bernhard R. Link <brl...@debian.org>
---
 scripts/Dpkg/BuildFlags.pm |   61 ++++++++++++++++++++++++++++++++-----------
 scripts/dpkg-buildflags.pl |    4 +-
 2 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/scripts/Dpkg/BuildFlags.pm b/scripts/Dpkg/BuildFlags.pm
index 4a84c57..af8d93b 100644
--- a/scripts/Dpkg/BuildFlags.pm
+++ b/scripts/Dpkg/BuildFlags.pm
@@ -87,6 +87,13 @@ sub load_vendor_defaults {
 	FFLAGS   => 'vendor',
 	LDFLAGS  => 'vendor',
     };
+    $self->{maintainer} = {
+	CPPFLAGS => 0,
+	CFLAGS   => 0,
+	CXXFLAGS => 0,
+	FFLAGS   => 0,
+	LDFLAGS  => 0,
+    };
     # The Debian vendor hook will add hardening build flags
     run_vendor_hook("update-buildflags", $self);
     # run_vendor_hook looked at DEB_VENDOR
@@ -165,22 +172,22 @@ sub load_maintainer_config {
 	my $envvar = "DEB_" . $flag . "_MAINT_SET";
 	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
-	    $self->set($flag, $ENV{$envvar}, undef);
+	    $self->set($flag, $ENV{$envvar}, undef, 1);
 	}
 	$envvar = "DEB_" . $flag . "_MAINT_STRIP";
 	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
-	    $self->strip($flag, $ENV{$envvar}, undef);
+	    $self->strip($flag, $ENV{$envvar}, undef, 1);
 	}
 	$envvar = "DEB_" . $flag . "_MAINT_APPEND";
 	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
-	    $self->append($flag, $ENV{$envvar}, undef);
+	    $self->append($flag, $ENV{$envvar}, undef, 1);
 	}
 	$envvar = "DEB_" . $flag . "_MAINT_PREPEND";
 	$self->environment_used($envvar);
 	if (exists $ENV{$envvar}) {
-	    $self->prepend($flag, $ENV{$envvar}, undef);
+	    $self->prepend($flag, $ENV{$envvar}, undef, 1);
 	}
     }
 }
@@ -202,17 +209,19 @@ sub load_config {
     $self->load_maintainer_config();
 }
 
-=item $bf->set($flag, $value, $source)
+=item $bf->set($flag, $value, $source, $maint)
 
 Update the build flag $flag with value $value and record its origin as
-$source (if defined).
+$source (if defined). Record it as maintainer modified if $maint is
+defined and true.
 
 =cut
 
 sub set {
-    my ($self, $flag, $value, $src) = @_;
+    my ($self, $flag, $value, $src, $maint) = @_;
     $self->{flags}->{$flag} = $value;
     $self->{origin}->{$flag} = $src if defined $src;
+    $self->{maintainer}->{$flag} = $maint if $maint;
 }
 
 =item $bf->set_feature($area, $feature, $enabled)
@@ -228,15 +237,16 @@ sub set_feature {
     $self->{'features'}{$area}{$feature} = $enabled;
 }
 
-=item $bf->strip($flag, $value, $source)
+=item $bf->strip($flag, $value, $source, $maint)
 
 Update the build flag $flag by stripping the flags listed in $value and
-record its origin as $source (if defined).
+record its origin as $source (if defined). Record it as maintainer modified
+if $maint is defined and true.
 
 =cut
 
 sub strip {
-    my ($self, $flag, $value, $src) = @_;
+    my ($self, $flag, $value, $src, $maint) = @_;
     foreach my $tostrip (split(/\s+/, $value)) {
 	next unless length $tostrip;
 	$self->{flags}->{$flag} =~ s/(^|\s+)\Q$tostrip\E(\s+|$)/ /g;
@@ -244,40 +254,45 @@ sub strip {
     $self->{flags}->{$flag} =~ s/^\s+//g;
     $self->{flags}->{$flag} =~ s/\s+$//g;
     $self->{origin}->{$flag} = $src if defined $src;
+    $self->{maintainer}->{$flag} = $maint if $maint;
 }
 
-=item $bf->append($flag, $value, $source)
+=item $bf->append($flag, $value, $source, $maint)
 
 Append the options listed in $value to the current value of the flag $flag.
-Record its origin as $source (if defined).
+Record its origin as $source (if defined). Record it as maintainer modified
+if $maint is defined and true.
 
 =cut
 
 sub append {
-    my ($self, $flag, $value, $src) = @_;
+    my ($self, $flag, $value, $src, $maint) = @_;
     if (length($self->{flags}->{$flag})) {
         $self->{flags}->{$flag} .= " $value";
     } else {
         $self->{flags}->{$flag} = $value;
     }
     $self->{origin}->{$flag} = $src if defined $src;
+    $self->{maintainer}->{$flag} = $maint if $maint;
 }
 
-=item $bf->prepend($flag, $value, $source)
+=item $bf->prepend($flag, $value, $source, $maint)
 
 Prepend the options listed in $value to the current value of the flag $flag.
-Record its origin as $source (if defined).
+Record its origin as $source (if defined). Record it as maintainer modified
+if $maint is defined and true.
 
 =cut
 
 sub prepend {
-    my ($self, $flag, $value, $src) = @_;
+    my ($self, $flag, $value, $src, $maint) = @_;
     if (length($self->{flags}->{$flag})) {
         $self->{flags}->{$flag} = "$value " . $self->{flags}->{$flag};
     } else {
         $self->{flags}->{$flag} = $value;
     }
     $self->{origin}->{$flag} = $src if defined $src;
+    $self->{maintainer}->{$flag} = $maint if $maint;
 }
 
 
@@ -368,6 +383,17 @@ sub get_origin {
     return $self->{'origin'}{$key};
 }
 
+=item $bf->is_maintainer_modified($flag)
+
+Return true if the flag is modified by the maintainer.
+
+=cut
+
+sub is_maintainer_modified {
+    my ($self, $key) = @_;
+    return $self->{'maintainer'}{$key};
+}
+
 =item $bf->has_features($area)
 
 Returns true if the given area of features is known, and false otherwise.
@@ -444,6 +470,9 @@ based on the package maintainer directives.
 New methods: $bf->get_features(), $bf->has_features(), $bf->set_feature(),
   $bf->get_feature_areas(), $bf->environment_used(), $bf->get_used_environment().
 
+New method $bf->is_maintainer_modified() and new optional parameter to
+$bf->set(), $bf->append(), $bf->prepend(), $bf->strip().
+
 =head1 AUTHOR
 
 Raphaël Hertzog <hert...@debian.org>
diff --git a/scripts/dpkg-buildflags.pl b/scripts/dpkg-buildflags.pl
index 66069a5..af685ca 100755
--- a/scripts/dpkg-buildflags.pl
+++ b/scripts/dpkg-buildflags.pl
@@ -176,8 +176,8 @@ if ($action eq "get") {
     foreach my $flag ($build_flags->list()) {
 	my $value = $build_flags->get($flag);
 	my $origin = $build_flags->get_origin($flag);
-	# Note that DEB_*_MAINT_* does not effect $origin.
-	print "dpkg-buildflags: $flag [$origin]: $value\n";
+	my $maintainer = $build_flags->is_maintainer_modified($flag) ? "+maintainer" : "";
+	print "dpkg-buildflags: $flag [$origin$maintainer]: $value\n";
     }
     exit(0);
 }
-- 
1.7.9.1

Reply via email to