1 # Copyright © 2006-2015 Guillem Jover <guillem@debian.org>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
20 Dpkg::Arch - handle architectures
24 The Dpkg::Arch module provides functions to handle Debian architectures,
25 wildcards, and mapping from and to GNU triplets.
27 No symbols are exported by default. The :all tag can be used to import all
28 symbols. The :getters, :parsers, :mappers and :operators tags can be used
29 to import specific symbol subsets.
33 package Dpkg
::Arch
1.03;
37 use feature
qw(state);
58 debtuple_to_gnutriplet
60 gnutriplet_to_debtuple
61 gnutriplet_to_multiarch
64 all
=> [ @EXPORT_OK ],
82 debtuple_to_gnutriplet
84 gnutriplet_to_debtuple
85 gnutriplet_to_multiarch
97 use Exporter
qw(import);
98 use List
::Util
qw(any);
102 use Dpkg
::ErrorHandling
;
106 my (%cputable, %ostable);
107 my (%cputable_re, %ostable_re);
108 my (%cpubits, %cpuendian);
111 my %debtuple_to_debarch;
112 my %debarch_to_debtuple;
118 =item $arch = get_raw_build_arch()
120 Get the raw build Debian architecture, without taking into account variables
121 from the environment.
125 sub get_raw_build_arch
()
129 return $build_arch if defined $build_arch;
131 # Note: We *always* require an installed dpkg when inferring the
132 # build architecture. The bootstrapping case is handled by
133 # dpkg-architecture itself, by avoiding computing the DEB_BUILD_
134 # variables when they are not requested.
136 ## no critic (TestingAndDebugging::ProhibitNoWarnings)
137 no warnings
qw(exec);
138 $build_arch = qx(dpkg
--print-architecture
);
139 syserr
('dpkg --print-architecture failed') if $?
>> 8;
145 =item $arch = get_build_arch()
147 Get the build Debian architecture, using DEB_BUILD_ARCH from the environment
154 return Dpkg
::BuildEnv
::get
('DEB_BUILD_ARCH') || get_raw_build_arch
();
158 my %cc_host_gnu_type;
160 sub get_host_gnu_type
()
162 my $CC = $ENV{CC
} || 'gcc';
164 return $cc_host_gnu_type{$CC} if defined $cc_host_gnu_type{$CC};
166 ## no critic (TestingAndDebugging::ProhibitNoWarnings)
167 no warnings
qw(exec);
168 $cc_host_gnu_type{$CC} = qx($CC -dumpmachine
);
170 $cc_host_gnu_type{$CC} = '';
172 chomp $cc_host_gnu_type{$CC};
175 return $cc_host_gnu_type{$CC};
178 sub set_host_gnu_type
180 my ($host_gnu_type) = @_;
181 my $CC = $ENV{CC
} || 'gcc';
183 $cc_host_gnu_type{$CC} = $host_gnu_type;
187 =item $arch = get_raw_host_arch()
189 Get the raw host Debian architecture, without taking into account variables
190 from the environment.
194 sub get_raw_host_arch
()
198 return $host_arch if defined $host_arch;
200 my $host_gnu_type = get_host_gnu_type
();
202 if ($host_gnu_type eq '') {
203 warning
(g_
('cannot determine CC system type, falling back to ' .
204 'default (native compilation)'));
206 my (@host_archtuple) = gnutriplet_to_debtuple
($host_gnu_type);
207 $host_arch = debtuple_to_debarch
(@host_archtuple);
209 if (defined $host_arch) {
210 $host_gnu_type = debtuple_to_gnutriplet
(@host_archtuple);
212 warning
(g_
('unknown CC system type %s, falling back to ' .
213 'default (native compilation)'), $host_gnu_type);
216 set_host_gnu_type
($host_gnu_type);
219 if (!defined($host_arch)) {
220 # Switch to native compilation.
221 $host_arch = get_raw_build_arch
();
227 =item $arch = get_host_arch()
229 Get the host Debian architecture, using DEB_HOST_ARCH from the environment
236 return Dpkg
::BuildEnv
::get
('DEB_HOST_ARCH') || get_raw_host_arch
();
239 =item @arch_list = get_valid_arches()
241 Get an array with all currently known Debian architectures.
245 sub get_valid_arches
()
252 foreach my $os (@os) {
253 foreach my $cpu (@cpu) {
254 my $arch = debtuple_to_debarch
(split(/-/, $os, 3), $cpu);
255 push @arches, $arch if defined($arch);
265 my ($table, $loader) = @_;
267 return if $table_loaded{$table};
272 open my $table_fh, '<', "$Dpkg::DATADIR/$table"
273 or syserr
(g_
('cannot open %s'), $table);
274 while (<$table_fh>) {
279 $table_loaded{$table} = 1;
284 _load_table
('cputable', sub {
285 if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) {
287 $cputable_re{$1} = $3;
297 _load_table
('ostable', sub {
298 if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
300 $ostable_re{$1} = $3;
308 _load_table
('abitable', sub {
309 if (m/^(?!\#)(\S+)\s+(\S+)/) {
315 sub _load_tupletable
()
319 _load_table
('tupletable', sub {
320 if (m/^(?!\#)(\S+)\s+(\S+)/) {
324 if ($debtuple =~ /<cpu>/) {
325 foreach my $_cpu (@cpu) {
326 (my $dt = $debtuple) =~ s/<cpu>/$_cpu/;
327 (my $da = $debarch) =~ s/<cpu>/$_cpu/;
329 next if exists $debarch_to_debtuple{$da}
330 or exists $debtuple_to_debarch{$dt};
332 $debarch_to_debtuple{$da} = $dt;
333 $debtuple_to_debarch{$dt} = $da;
336 $debarch_to_debtuple{$2} = $1;
337 $debtuple_to_debarch{$1} = $2;
343 sub debtuple_to_gnutriplet
(@
)
345 my ($abi, $libc, $os, $cpu) = @_;
351 defined $abi && defined $libc && defined $os && defined $cpu &&
352 exists $cputable{$cpu} && exists $ostable{"$abi-$libc-$os"};
353 return join('-', $cputable{$cpu}, $ostable{"$abi-$libc-$os"});
356 sub gnutriplet_to_debtuple
($)
359 return unless defined($gnu);
360 my ($gnu_cpu, $gnu_os) = split(/-/, $gnu, 2);
361 return unless defined($gnu_cpu) && defined($gnu_os);
368 foreach my $_cpu (@cpu) {
369 if ($gnu_cpu =~ /^$cputable_re{$_cpu}$/) {
375 foreach my $_os (@os) {
376 if ($gnu_os =~ /^(.*-)?$ostable_re{$_os}$/) {
382 return if !defined($cpu) || !defined($os);
383 return (split(/-/, $os, 3), $cpu);
386 =item $multiarch = gnutriplet_to_multiarch($gnutriplet)
388 Map a GNU triplet into a Debian multiarch triplet.
392 sub gnutriplet_to_multiarch
($)
395 my ($cpu, $cdr) = split(/-/, $gnu, 2);
397 if ($cpu =~ /^i[4567]86$/) {
404 =item $multiarch = debarch_to_multiarch($arch)
406 Map a Debian architecture into a Debian multiarch triplet.
410 sub debarch_to_multiarch
($)
414 return gnutriplet_to_multiarch
(debarch_to_gnutriplet
($arch));
417 sub debtuple_to_debarch
(@
)
419 my ($abi, $libc, $os, $cpu) = @_;
423 if (!defined $abi || !defined $libc || !defined $os || !defined $cpu) {
425 } elsif (exists $debtuple_to_debarch{"$abi-$libc-$os-$cpu"}) {
426 return $debtuple_to_debarch{"$abi-$libc-$os-$cpu"};
432 sub debarch_to_debtuple
($)
436 return if not defined $arch;
440 if ($arch =~ /^linux-([^-]*)/) {
441 # XXX: Might disappear in the future, not sure yet.
445 my $tuple = $debarch_to_debtuple{$arch};
447 if (defined($tuple)) {
448 my @tuple = split /-/, $tuple, 4;
449 return @tuple if wantarray;
461 =item $gnutriplet = debarch_to_gnutriplet($arch)
463 Map a Debian architecture into a GNU triplet.
467 sub debarch_to_gnutriplet
($)
471 return debtuple_to_gnutriplet
(debarch_to_debtuple
($arch));
474 =item $arch = gnutriplet_to_debarch($gnutriplet)
476 Map a GNU triplet into a Debian architecture.
480 sub gnutriplet_to_debarch
($)
484 return debtuple_to_debarch
(gnutriplet_to_debtuple
($gnu));
487 sub debwildcard_to_debtuple
($)
490 my @tuple = split /-/, $arch, 4;
492 if (any
{ $_ eq 'any' } @tuple) {
493 if (scalar @tuple == 4) {
495 } elsif (scalar @tuple == 3) {
496 return ('any', @tuple);
497 } elsif (scalar @tuple == 2) {
498 return ('any', 'any', @tuple);
500 return ('any', 'any', 'any', 'any');
503 return debarch_to_debtuple
($arch);
507 sub debarch_to_abiattrs
($)
510 my ($abi, $libc, $os, $cpu) = debarch_to_debtuple
($arch);
515 return ($abibits{$abi} // $cpubits{$cpu}, $cpuendian{$cpu});
521 sub debarch_to_cpubits
($)
526 ((undef) x
3, $cpu) = debarch_to_debtuple
($arch);
529 return $cpubits{$cpu};
535 =item $bool = debarch_eq($arch_a, $arch_b)
537 Evaluate the equality of a Debian architecture, by comparing with another
538 Debian architecture. No wildcard matching is performed.
546 return 1 if ($a eq $b);
548 my @a = debarch_to_debtuple
($a);
549 my @b = debarch_to_debtuple
($b);
551 return 0 if scalar @a != 4 or scalar @b != 4;
553 return $a[0] eq $b[0] && $a[1] eq $b[1] && $a[2] eq $b[2] && $a[3] eq $b[3];
556 =item $bool = debarch_is($arch, $arch_wildcard)
558 Evaluate the identity of a Debian architecture, by matching with an
559 architecture wildcard.
565 my ($real, $alias) = @_;
567 return 1 if ($alias eq $real or $alias eq 'any');
569 my @real = debarch_to_debtuple
($real);
570 my @alias = debwildcard_to_debtuple
($alias);
572 return 0 if scalar @real != 4 or scalar @alias != 4;
574 if (($alias[0] eq $real[0] || $alias[0] eq 'any') &&
575 ($alias[1] eq $real[1] || $alias[1] eq 'any') &&
576 ($alias[2] eq $real[2] || $alias[2] eq 'any') &&
577 ($alias[3] eq $real[3] || $alias[3] eq 'any')) {
584 =item $bool = debarch_is_wildcard($arch)
586 Evaluate whether a Debian architecture is an architecture wildcard.
590 sub debarch_is_wildcard
($)
594 return 0 if $arch eq 'all';
596 my @tuple = debwildcard_to_debtuple
($arch);
598 return 0 if scalar @tuple != 4;
599 return 1 if any
{ $_ eq 'any' } @tuple;
603 =item $bool = debarch_is_illegal($arch, %options)
605 Validate an architecture name.
607 If the "positive" option is set to a true value, only positive architectures
608 will be accepted, otherwise negated architectures are allowed.
612 sub debarch_is_illegal
614 my ($arch, %opts) = @_;
615 my $arch_re = qr/[a-zA-Z0-9][a-zA-Z0-9-]*/;
617 if ($opts{positive
}) {
618 return $arch !~ m/^$arch_re$/;
620 return $arch !~ m/^!?$arch_re$/;
624 =item $bool = debarch_is_concerned($arch, @arches)
626 Evaluate whether a Debian architecture applies to the list of architecture
627 restrictions, as usually found in dependencies inside square brackets.
631 sub debarch_is_concerned
633 my ($host_arch, @arches) = @_;
636 foreach my $arch (@arches) {
640 my $not_arch = $arch;
643 if (debarch_is
($host_arch, $not_arch)) {
647 # !arch includes by default all other arches
648 # unless they also appear in a !otherarch
651 } elsif (debarch_is
($host_arch, $arch)) {
659 =item @array = debarch_list_parse($arch_list, %options)
661 Parse an architecture list.
663 If the "positive" option is set to a true value, only positive architectures
664 will be accepted, otherwise negated architectures are allowed.
668 sub debarch_list_parse
670 my ($arch_list, %opts) = @_;
671 my @arch_list = split ' ', $arch_list;
673 foreach my $arch (@arch_list) {
674 if (debarch_is_illegal
($arch, %opts)) {
675 error
(g_
("'%s' is not a legal architecture in list '%s'"),
689 =head2 Version 1.03 (dpkg 1.19.1)
691 New argument: Accept a "positive" option in debarch_is_illegal() and
692 debarch_list_parse().
694 =head2 Version 1.02 (dpkg 1.18.19)
696 New import tags: ":all", ":getters", ":parsers", ":mappers", ":operators".
698 =head2 Version 1.01 (dpkg 1.18.5)
700 New functions: debarch_is_illegal(), debarch_list_parse().
702 =head2 Version 1.00 (dpkg 1.18.2)
704 Mark the module as public.
708 L<dpkg-architecture(1)>.