#! /usr/bin/perl
# Written by Zack Weinberg <zackw at panix.com> 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 <limits.h>
#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;