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/>.
22 Dpkg::Arch - handle architectures
26 The Dpkg::Arch module provides functions to handle Debian architectures,
27 wildcards, and mapping from and to GNU triplets.
29 No symbols are exported by default. The :all tag can be used to import all
30 symbols. The :getters, :parsers, :mappers and :operators tags can be used
31 to import specific symbol subsets.
37 use feature qw(state);
39 our $VERSION = '1.02';
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 POSIX qw(:errno_h);
102 use Dpkg::ErrorHandling;
103 use Dpkg::Util qw(:list);
104 use Dpkg::Build::Env;
107 my (%cputable, %ostable);
108 my (%cputable_re, %ostable_re);
109 my (%cpubits, %cpuendian);
112 my %debtuple_to_debarch;
113 my %debarch_to_debtuple;
119 =item $arch = get_raw_build_arch()
121 Get the raw build Debian architecture, without taking into account variables
122 from the environment.
126 sub get_raw_build_arch()
130 return $build_arch if defined $build_arch;
132 # Note: We *always* require an installed dpkg when inferring the
133 # build architecture. The bootstrapping case is handled by
134 # dpkg-architecture itself, by avoiding computing the DEB_BUILD_
135 # variables when they are not requested.
137 $build_arch = qx(dpkg --print-architecture);
138 syserr('dpkg --print-architecture failed') if $? >> 8;
144 =item $arch = get_build_arch()
146 Get the build Debian architecture, using DEB_BUILD_ARCH from the environment
153 return Dpkg::Build::Env::get('DEB_BUILD_ARCH') || get_raw_build_arch();
157 my %cc_host_gnu_type;
159 sub get_host_gnu_type()
161 my $CC = $ENV{CC} || 'gcc';
163 return $cc_host_gnu_type{$CC} if defined $cc_host_gnu_type{$CC};
165 $cc_host_gnu_type{$CC} = qx($CC -dumpmachine);
167 $cc_host_gnu_type{$CC} = '';
169 chomp $cc_host_gnu_type{$CC};
172 return $cc_host_gnu_type{$CC};
175 sub set_host_gnu_type
177 my ($host_gnu_type) = @_;
178 my $CC = $ENV{CC} || 'gcc';
180 $cc_host_gnu_type{$CC} = $host_gnu_type;
184 =item $arch = get_raw_host_arch()
186 Get the raw host Debian architecture, without taking into account variables
187 from the environment.
191 sub get_raw_host_arch()
195 return $host_arch if defined $host_arch;
197 my $host_gnu_type = get_host_gnu_type();
199 if ($host_gnu_type eq '') {
200 warning(g_('cannot determine CC system type, falling back to ' .
201 'default (native compilation)'));
203 my (@host_archtuple) = gnutriplet_to_debtuple($host_gnu_type);
204 $host_arch = debtuple_to_debarch(@host_archtuple);
206 if (defined $host_arch) {
207 $host_gnu_type = debtuple_to_gnutriplet(@host_archtuple);
209 warning(g_('unknown CC system type %s, falling back to ' .
210 'default (native compilation)'), $host_gnu_type);
213 set_host_gnu_type($host_gnu_type);
216 if (!defined($host_arch)) {
217 # Switch to native compilation.
218 $host_arch = get_raw_build_arch();
224 =item $arch = get_host_arch()
226 Get the host Debian architecture, using DEB_HOST_ARCH from the environment
233 return Dpkg::Build::Env::get('DEB_HOST_ARCH') || get_raw_host_arch();
236 =item @arch_list = get_valid_arches()
238 Get an array with all currently known Debian architectures.
242 sub get_valid_arches()
249 foreach my $os (@os) {
250 foreach my $cpu (@cpu) {
251 my $arch = debtuple_to_debarch(split(/-/, $os, 3), $cpu);
252 push @arches, $arch if defined($arch);
262 my ($table, $loader) = @_;
264 return if $table_loaded{$table};
269 open my $table_fh, '<', "$Dpkg::DATADIR/$table"
270 or syserr(g_('cannot open %s'), $table);
271 while (<$table_fh>) {
276 $table_loaded{$table} = 1;
281 _load_table('cputable', sub {
282 if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) {
284 $cputable_re{$1} = $3;
294 _load_table('ostable', sub {
295 if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
297 $ostable_re{$1} = $3;
305 _load_table('abitable', sub {
306 if (m/^(?!\#)(\S+)\s+(\S+)/) {
312 sub _load_tupletable()
316 _load_table('tupletable', sub {
317 if (m/^(?!\#)(\S+)\s+(\S+)/) {
321 if ($debtuple =~ /<cpu>/) {
322 foreach my $_cpu (@cpu) {
323 (my $dt = $debtuple) =~ s/<cpu>/$_cpu/;
324 (my $da = $debarch) =~ s/<cpu>/$_cpu/;
326 next if exists $debarch_to_debtuple{$da}
327 or exists $debtuple_to_debarch{$dt};
329 $debarch_to_debtuple{$da} = $dt;
330 $debtuple_to_debarch{$dt} = $da;
333 $debarch_to_debtuple{$2} = $1;
334 $debtuple_to_debarch{$1} = $2;
340 sub debtuple_to_gnutriplet(@)
342 my ($abi, $libc, $os, $cpu) = @_;
348 defined $abi && defined $libc && defined $os && defined $cpu &&
349 exists $cputable{$cpu} && exists $ostable{"$abi-$libc-$os"};
350 return join('-', $cputable{$cpu}, $ostable{"$abi-$libc-$os"});
353 sub gnutriplet_to_debtuple($)
356 return unless defined($gnu);
357 my ($gnu_cpu, $gnu_os) = split(/-/, $gnu, 2);
358 return unless defined($gnu_cpu) && defined($gnu_os);
365 foreach my $_cpu (@cpu) {
366 if ($gnu_cpu =~ /^$cputable_re{$_cpu}$/) {
372 foreach my $_os (@os) {
373 if ($gnu_os =~ /^(.*-)?$ostable_re{$_os}$/) {
379 return if !defined($cpu) || !defined($os);
380 return (split(/-/, $os, 3), $cpu);
383 =item $multiarch = gnutriplet_to_multiarch($gnutriplet)
385 Map a GNU triplet into a Debian multiarch triplet.
389 sub gnutriplet_to_multiarch($)
392 my ($cpu, $cdr) = split(/-/, $gnu, 2);
394 if ($cpu =~ /^i[4567]86$/) {
401 =item $multiarch = debarch_to_multiarch($arch)
403 Map a Debian architecture into a Debian multiarch triplet.
407 sub debarch_to_multiarch($)
411 return gnutriplet_to_multiarch(debarch_to_gnutriplet($arch));
414 sub debtuple_to_debarch(@)
416 my ($abi, $libc, $os, $cpu) = @_;
420 if (!defined $abi || !defined $libc || !defined $os || !defined $cpu) {
422 } elsif (exists $debtuple_to_debarch{"$abi-$libc-$os-$cpu"}) {
423 return $debtuple_to_debarch{"$abi-$libc-$os-$cpu"};
429 sub debarch_to_debtuple($)
433 return if not defined $arch;
437 if ($arch =~ /^linux-([^-]*)/) {
438 # XXX: Might disappear in the future, not sure yet.
442 my $tuple = $debarch_to_debtuple{$arch};
444 if (defined($tuple)) {
445 my @tuple = split /-/, $tuple, 4;
446 return @tuple if wantarray;
458 =item $gnutriplet = debarch_to_gnutriplet($arch)
460 Map a Debian architecture into a GNU triplet.
464 sub debarch_to_gnutriplet($)
468 return debtuple_to_gnutriplet(debarch_to_debtuple($arch));
471 =item $arch = gnutriplet_to_debarch($gnutriplet)
473 Map a GNU triplet into a Debian architecture.
477 sub gnutriplet_to_debarch($)
481 return debtuple_to_debarch(gnutriplet_to_debtuple($gnu));
484 sub debwildcard_to_debtuple($)
487 my @tuple = split /-/, $arch, 4;
489 if (any { $_ eq 'any' } @tuple) {
490 if (scalar @tuple == 4) {
492 } elsif (scalar @tuple == 3) {
493 return ('any', @tuple);
494 } elsif (scalar @tuple == 2) {
495 return ('any', 'any', @tuple);
497 return ('any', 'any', 'any', 'any');
500 return debarch_to_debtuple($arch);
504 sub debarch_to_cpuattrs($)
507 my ($abi, $libc, $os, $cpu) = debarch_to_debtuple($arch);
512 return ($abibits{$abi} // $cpubits{$cpu}, $cpuendian{$cpu});
518 =item $bool = debarch_eq($arch_a, $arch_b)
520 Evaluate the equality of a Debian architecture, by comparing with another
521 Debian architecture. No wildcard matching is performed.
529 return 1 if ($a eq $b);
531 my @a = debarch_to_debtuple($a);
532 my @b = debarch_to_debtuple($b);
534 return 0 if scalar @a != 4 or scalar @b != 4;
536 return $a[0] eq $b[0] && $a[1] eq $b[1] && $a[2] eq $b[2] && $a[3] eq $b[3];
539 =item $bool = debarch_is($arch, $arch_wildcard)
541 Evaluate the identity of a Debian architecture, by matching with an
542 architecture wildcard.
548 my ($real, $alias) = @_;
550 return 1 if ($alias eq $real or $alias eq 'any');
552 my @real = debarch_to_debtuple($real);
553 my @alias = debwildcard_to_debtuple($alias);
555 return 0 if scalar @real != 4 or scalar @alias != 4;
557 if (($alias[0] eq $real[0] || $alias[0] eq 'any') &&
558 ($alias[1] eq $real[1] || $alias[1] eq 'any') &&
559 ($alias[2] eq $real[2] || $alias[2] eq 'any') &&
560 ($alias[3] eq $real[3] || $alias[3] eq 'any')) {
567 =item $bool = debarch_is_wildcard($arch)
569 Evaluate whether a Debian architecture is an architecture wildcard.
573 sub debarch_is_wildcard($)
577 return 0 if $arch eq 'all';
579 my @tuple = debwildcard_to_debtuple($arch);
581 return 0 if scalar @tuple != 4;
582 return 1 if any { $_ eq 'any' } @tuple;
586 =item $bool = debarch_is_illegal($arch)
588 Validate an architecture name.
592 sub debarch_is_illegal
596 return $arch !~ m/^!?[a-zA-Z0-9][a-zA-Z0-9-]*$/;
599 =item $bool = debarch_is_concerned($arch, @arches)
601 Evaluate whether a Debian architecture applies to the list of architecture
602 restrictions, as usually found in dependencies inside square brackets.
606 sub debarch_is_concerned
608 my ($host_arch, @arches) = @_;
611 foreach my $arch (@arches) {
615 my $not_arch = $arch;
618 if (debarch_is($host_arch, $not_arch)) {
622 # !arch includes by default all other arches
623 # unless they also appear in a !otherarch
626 } elsif (debarch_is($host_arch, $arch)) {
634 =item @array = debarch_list_parse($arch_list, %options)
636 Parse an architecture list.
640 sub debarch_list_parse
642 my $arch_list = shift;
643 my @arch_list = split /\s+/, $arch_list;
645 foreach my $arch (@arch_list) {
646 if (debarch_is_illegal($arch)) {
647 error(g_("'%s' is not a legal architecture in list '%s'"),
663 =head2 Version 1.02 (dpkg 1.18.19)
665 New import tags: ":all", ":getters", ":parsers", ":mappers", ":operators".
667 =head2 Version 1.01 (dpkg 1.18.5)
669 New functions: debarch_is_illegal(), debarch_list_parse().
671 =head2 Version 1.00 (dpkg 1.18.2)
673 Mark the module as public.
677 dpkg-architecture(1).