File Coverage

File:Dpkg/Vendor/Ubuntu.pm
Coverage:66.7%

linestmtbrancondsubpodtimecode
1# Copyright © 2008 Ian Jackson <ijackson@chiark.greenend.org.uk>
2# Copyright © 2008 Canonical, Ltd.
3#   written by Colin Watson <cjwatson@ubuntu.com>
4# Copyright © 2008 James Westby <jw+debian@jameswestby.net>
5# Copyright © 2009 Raphaël Hertzog <hertzog@debian.org>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20=encoding utf8
21
22 - 33
=head1 NAME

Dpkg::Vendor::Ubuntu - Ubuntu vendor class

=head1 DESCRIPTION

This vendor class customizes the behavior of dpkg scripts for Ubuntu
specific behavior and policies.

B<Note>: This is a private module, its API can change at any time.

=cut
34
35package Dpkg::Vendor::Ubuntu 0.01;
36
37
9
9
9
21
5
152
use strict;
38
9
9
9
13
7
294
use warnings;
39
40
9
9
9
21
5
335
use List::Util qw(any);
41
42
9
9
9
22
9
424
use Dpkg::ErrorHandling;
43
9
9
9
22
8
270
use Dpkg::Gettext;
44
9
9
9
22
5
469
use Dpkg::Control::Types;
45
46
9
9
9
22
7
37
use parent qw(Dpkg::Vendor::Debian);
47
48sub run_hook {
49
768
1
871
    my ($self, $hook, @params) = @_;
50
51
768
1924
    if ($hook eq 'before-source-build') {
52
0
0
        my $src = shift @params;
53
0
0
        my $fields = $src->{fields};
54
55        # check that Maintainer/XSBC-Original-Maintainer comply to
56        # https://wiki.ubuntu.com/DebianMaintainerField
57
0
0
        if (defined($fields->{'Version'}) and defined($fields->{'Maintainer'}) and
58           $fields->{'Version'} =~ /ubuntu/) {
59
0
0
           if ($fields->{'Maintainer'} !~ /(?:ubuntu|canonical)/i) {
60
0
0
               if (length $ENV{DEBEMAIL} and $ENV{DEBEMAIL} =~ /\@(?:ubuntu|canonical)\.com/) {
61
0
0
                   error(g_('Version number suggests Ubuntu changes, but Maintainer: does not have Ubuntu address'));
62               } else {
63
0
0
                   warning(g_('Version number suggests Ubuntu changes, but Maintainer: does not have Ubuntu address'));
64               }
65           }
66
0
0
           unless ($fields->{'Original-Maintainer'}) {
67
0
0
               warning(g_('Version number suggests Ubuntu changes, but there is no XSBC-Original-Maintainer field'));
68           }
69        }
70    } elsif ($hook eq 'package-keyrings') {
71
0
0
        return ($self->SUPER::run_hook($hook),
72                '/usr/share/keyrings/ubuntu-archive-keyring.gpg');
73    } elsif ($hook eq 'archive-keyrings') {
74
0
0
        return ($self->SUPER::run_hook($hook),
75                '/usr/share/keyrings/ubuntu-archive-keyring.gpg');
76    } elsif ($hook eq 'archive-keyrings-historic') {
77
0
0
        return ($self->SUPER::run_hook($hook),
78                '/usr/share/keyrings/ubuntu-archive-removed-keys.gpg');
79    } elsif ($hook eq 'register-custom-fields') {
80
3
7
        my @field_ops = $self->SUPER::run_hook($hook);
81
3
22
        push @field_ops, [
82            'register', 'Launchpad-Bugs-Fixed',
83              CTRL_FILE_CHANGES | CTRL_CHANGELOG,
84        ], [
85            'insert_after', CTRL_FILE_CHANGES, 'Closes', 'Launchpad-Bugs-Fixed',
86        ], [
87            'insert_after', CTRL_CHANGELOG, 'Closes', 'Launchpad-Bugs-Fixed',
88        ];
89
3
7
        return @field_ops;
90    } elsif ($hook eq 'post-process-changelog-entry') {
91
750
652
        my $fields = shift @params;
92
93        # Add Launchpad-Bugs-Fixed field
94
750
714
        my $bugs = find_launchpad_closes($fields->{'Changes'} // '');
95
750
1388
        if (scalar(@$bugs)) {
96
21
44
            $fields->{'Launchpad-Bugs-Fixed'} = join(' ', @$bugs);
97        }
98    } else {
99
15
36
        return $self->SUPER::run_hook($hook, @params);
100    }
101}
102
103# Override Debian default features.
104sub init_build_features {
105
15
0
18
    my ($self, $use_feature, $builtin_feature) = @_;
106
107
15
43
    $self->SUPER::init_build_features($use_feature, $builtin_feature);
108
109
15
38
    require Dpkg::Arch;
110
15
28
    my $arch = Dpkg::Arch::get_host_arch();
111
112
15
39
62
38
    if (any { $_ eq $arch } qw(amd64 arm64 ppc64el s390x)) {
113
9
19
        $use_feature->{optimize}{lto} = 1;
114    }
115}
116
117sub set_build_features {
118
15
1
17
    my ($self, $flags) = @_;
119
120
15
32
    $self->SUPER::set_build_features($flags);
121
122
15
38
    require Dpkg::Arch;
123
15
38
    my $arch = Dpkg::Arch::get_host_arch();
124
125
15
29
    if ($arch eq 'ppc64el' && $flags->get_option_value('optimize-level') != 0) {
126
3
4
        $flags->set_option_value('optimize-level', 3);
127    }
128
129
15
15
    $flags->set_option_value('fortify-level', 3);
130}
131
132sub add_build_flags {
133
15
1
15
    my ($self, $flags) = @_;
134
135
15
23
    my @compile_flags = qw(
136        CFLAGS
137        CXXFLAGS
138        OBJCFLAGS
139        OBJCXXFLAGS
140        FFLAGS
141        FCFLAGS
142    );
143
144
15
35
    $self->SUPER::add_build_flags($flags);
145
146    # Per https://wiki.ubuntu.com/DistCompilerFlags
147
15
36
    $flags->prepend('LDFLAGS', '-Wl,-Bsymbolic-functions');
148
149    # In Ubuntu these flags are set by the compiler, so when disabling the
150    # features we need to pass appropriate flags to disable them.
151
15
25
    if (!$flags->use_feature('hardening', 'stackprotectorstrong') &&
152        !$flags->use_feature('hardening', 'stackprotector')) {
153
0
0
        my $flag = '-fno-stack-protector';
154
0
0
        $flags->append($_, $flag) foreach @compile_flags;
155    }
156
157
15
24
    if (!$flags->use_feature('hardening', 'stackclash')) {
158
9
8
        my $flag = '-fno-stack-clash-protection';
159
9
27
        $flags->append($_, $flag) foreach @compile_flags;
160    }
161
162
15
25
    if (!$flags->use_feature('hardening', 'fortify')) {
163
0
0
        $flags->append('CPPFLAGS', '-D_FORTIFY_SOURCE=0');
164    }
165
166
15
17
    if (!$flags->use_feature('hardening', 'format')) {
167
0
0
        my $flag = '-Wno-format -Wno-error=format-security';
168
0
0
        $flags->append('CFLAGS', $flag);
169
0
0
        $flags->append('CXXFLAGS', $flag);
170
0
0
        $flags->append('OBJCFLAGS', $flag);
171
0
0
        $flags->append('OBJCXXFLAGS', $flag);
172     }
173
174
15
24
     if (!$flags->use_feature('hardening', 'branch')) {
175
9
11
        my $cpu = $flags->get_option_value('hardening-branch-cpu');
176
9
9
        my $flag;
177
9
18
        if ($cpu eq 'arm64') {
178
0
0
            $flag = '-mbranch-protection=none';
179        } elsif ($cpu eq 'amd64') {
180
0
0
            $flag = '-fcf-protection=none';
181        }
182
9
13
        if (defined $flag) {
183
0
0
            $flags->append($_, $flag) foreach @compile_flags;
184        }
185    }
186
187
15
88
    return;
188}
189
190 - 200
=head1 PUBLIC FUNCTIONS

=over

=item $bugs = Dpkg::Vendor::Ubuntu::find_launchpad_closes($changes)

Takes one string as argument and finds "LP: #123456, #654321" statements,
which are references to bugs on Launchpad. Returns all closed bug
numbers in an array reference.

=cut
201
202sub find_launchpad_closes {
203
750
1
590
    my $changes = shift;
204
750
484
    my %closes;
205
206
750
2672
    while ($changes &&
207          ($changes =~ /lp:\s+\#\d+(?:,\s*\#\d+)*/pig)) {
208
27
208
        $closes{$_} = 1 foreach (${^MATCH} =~ /\#?\s?(\d+)/g);
209    }
210
211
750
43
862
68
    my @closes = sort { $a <=> $b } keys %closes;
212
213
750
829
    return \@closes;
214}
215
216=back
217
218 - 224
=head1 CHANGES

=head2 Version 0.xx

This is a semi-private module. Only documented functions are public.

=cut
225
2261;