#! /usr/bin/perl # Written by Zack Weinberg in 2017 and 2020. # To the extent possible under law, Zack Weinberg has waived all # copyright and related or neighboring rights to this work. # # See https://creativecommons.org/publicdomain/zero/1.0/ for further # details. # Process libcrypt.minver and determine the minumum symbol version to # use for compatibility symbols. Called from configure.ac. use v5.14; # implicit use strict, use feature ':5.14' use warnings FATAL => 'all'; use utf8; use open qw(:std :utf8); no if $] >= 5.022, warnings => 'experimental::re_strict'; use if $] >= 5.022, re => 'strict'; use FindBin (); use lib ${FindBin::Bin}; use BuildCommon qw( ensure_C_locale sh_split popen subprocess_error which ); sub preprocessor_check { my ($expr) = @_; state @CC; state @CFLAGS; if (!@CC) { @CC = which($ENV{CC} // 'cc'); die "C compiler not available\n" unless @CC; @CFLAGS = sh_split($ENV{CFLAGS} // q{}); # Remove empty elements, particularly leading ones which # cause issues with popen below. @CFLAGS = grep { $_ } @CFLAGS; # We call ensure_C_locale here, not from the main section, # because this sub might not get called at all, in which # case it would be unnecessary work. ensure_C_locale(); } # FIXME: We assume the compiler understands "-fsyntax-only -xc -" # to mean "read standard input, interpret as C, check for errors, # produce no output." This is true for all commonly used C # compilers on operating systems where this feature is necessary. print {*STDERR} "${FindBin::Bin}: testing $expr\n"; my $ccpipe = popen('|-', @CC, @CFLAGS, '-fsyntax-only', '-xc', '-'); print {$ccpipe} <<"EOF"; #include #if !($expr) #error nope #endif int avoid_empty_translation_unit; EOF if (close $ccpipe) { return 1; # compilation successful } elsif ($! == 0 && ($? & 0x7F) == 0) { return 0; # compilation failed } else { subprocess_error(@CC); } } sub parse_minver_file { my ($minver_file, $system, $cpu) = @_; $system = lc $system; $cpu = lc $cpu; local $_; open my $fh, '<', $minver_file or die "$minver_file: $!\n"; while (<$fh>) { next if /^#/; chomp; s/\s+$//; next if $_ eq q{}; my ($vers, $vsys, $vcpu, $ppck) = split q{ }, $_, 4; $vsys = lc $vsys; $vcpu = lc $vcpu; return $vers if $system =~ /\A$vsys/ && $cpu =~ /\A$vcpu/ && (!defined $ppck || preprocessor_check($ppck)); } print {*STDERR} "$0: no match for ${cpu}-${system}\n"; return 'ERROR'; } # # Main # if (scalar(@ARGV) != 3) { print {*STDERR} "usage: $0 libcrypt.minver host-os host-cpu\n"; print {*STDERR} "Environment variables \$CC and \$CFLAGS are honored.\n"; exit 2; } exit 0 if eval { print parse_minver_file(@ARGV), "\n"; close STDOUT or die "write error: $!\n"; 1; }; print {*STDERR} "${FindBin::Script}: $@"; exit 1;