| File: | Dpkg/Vendor/Ubuntu.pm |
| Coverage: | 66.7% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 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 | |||||||
| 35 | package 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 | |||||||
| 48 | sub 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. | ||||||
| 104 | sub 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 | |||||||
| 117 | sub 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 | |||||||
| 132 | sub 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 | |||||||
| 202 | sub 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 | |||||||
| 226 | 1; | ||||||