uname -m is unreliable as the host architecture might not match the target architecture. This can happen when cross compiling or (more common) if you are running a 32 bit userspace on a 64 bit kernel. The latter makes sparse fail to build on some machines of the Debian build farm as for example some armhf builder run on arm64 kernels. This patch is only lightly tested and also misses details for mips* and so marked as RFC. Signed-off-by: Uwe Kleine-König <uwe@xxxxxxxxxxxxxxxxx> --- cgcc | 87 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/cgcc b/cgcc index 629124b9412e..176c14c35adb 100755 --- a/cgcc +++ b/cgcc @@ -339,28 +339,71 @@ sub add_specs { chomp $os; return &add_specs (lc $os); } elsif ($spec eq 'host_arch_specs') { - my $arch = `uname -m`; - chomp $arch; - if ($arch =~ /^(i.?86|athlon)$/i) { - return &add_specs ('i386'); - } elsif ($arch =~ /^(sun4u)$/i) { - return &add_specs ('sparc'); - } elsif ($arch =~ /^(x86_64)$/i) { - return &add_specs ('x86_64'); - } elsif ($arch =~ /^(ppc)$/i) { - return &add_specs ('ppc'); - } elsif ($arch =~ /^(ppc64)$/i) { - return &add_specs ('ppc64') . ' -mbig-endian -D_CALL_ELF=1'; - } elsif ($arch =~ /^(ppc64le)$/i) { - return &add_specs ('ppc64') . ' -mlittle-endian -D_CALL_ELF=2'; - } elsif ($arch =~ /^(s390x)$/i) { - return &add_specs ('s390x'); - } elsif ($arch =~ /^(sparc64)$/i) { - return &add_specs ('sparc64'); - } elsif ($arch =~ /^arm(?:v[78]l)?$/i) { - return &add_specs ('arm'); - } elsif ($arch =~ /^(aarch64)$/i) { - return &add_specs ('aarch64'); + chomp(my $gccmachine = `$cc -dumpmachine`); + + if ($gccmachine eq 'aarch64-linux-gnu') { + return (' -m64' . &float_types (1, 1, 36, [24, 8], [53, 11], [113, 15])); + + } elsif ($gccmachine eq 'arm-linux-gnueabi') { + return (' -m32' . &float_types (1, 1, 36, [24, 8], [53,11], [53, 11])); + + } elsif ($gccmachine eq 'arm-linux-gnueabihf') { + return (' -m32 -D__ARM_PCS_VFP=1' . &float_types (1, 1, 36, [24,8], [53,11], [53, 11])); + + } elsif ($gccmachine eq 'i686-linux-gnu') { + return &float_types (1, 1, 21, [24, 8], [53, 11], [64, 15]); + + } elsif ($gccmachine eq 'mips-linux-gnu') { + # ??? + + } elsif ($gccmachine eq 'mipsel-linux-gnu') { + # ??? + + } elsif ($gccmachine eq 'mips64el-linux-gnuabi64') { + # ??? + + } elsif ($gccmachine eq 'powerpc64le-linux-gnu') { + return (' -D_STRING_ARCH_unaligned=1 -m64 -mlittle-endian -D_CALL_ELF=2' . &float_types (1, 1, 21, [24,8], [53,11], [113,15])); + + } elsif ($gccmachine eq 's390x') { + + return (' -D_BIG_ENDIAN' . + &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . + &float_types (1, 1, 36, [24,8], [53,11], [113,15]) . + &define_size_t ("long unsigned int") . + ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4')); + + } elsif ($gccmachine eq 'x86_64-linux-gnu') { + return &float_types (1, 1, 33, [24, 8], [53, 11], [113, 15]); + + } else { + # fall back to uname -m to determine the specifics. Note this is + # unstable as we might run an i386 compiler on an amd64 box or even + # a hppa compiler on s390x. + + my $arch = `uname -m`; + chomp $arch; + if ($arch =~ /^(i.?86|athlon)$/i) { + return &add_specs ('i386'); + } elsif ($arch =~ /^(sun4u)$/i) { + return &add_specs ('sparc'); + } elsif ($arch =~ /^(x86_64)$/i) { + return &add_specs ('x86_64'); + } elsif ($arch =~ /^(ppc)$/i) { + return &add_specs ('ppc'); + } elsif ($arch =~ /^(ppc64)$/i) { + return &add_specs ('ppc64') . ' -mbig-endian -D_CALL_ELF=1'; + } elsif ($arch =~ /^(ppc64le)$/i) { + return &add_specs ('ppc64') . ' -mlittle-endian -D_CALL_ELF=2'; + } elsif ($arch =~ /^(s390x)$/i) { + return &add_specs ('s390x'); + } elsif ($arch =~ /^(sparc64)$/i) { + return &add_specs ('sparc64'); + } elsif ($arch =~ /^arm(?:v[78]l)?$/i) { + return &add_specs ('arm'); + } elsif ($arch =~ /^(aarch64)$/i) { + return &add_specs ('aarch64'); + } } } else { die "$0: invalid specs: $spec\n"; -- 2.20.1