diff options
author | Zack Weinberg <zackw@panix.com> | 2021-09-18 11:28:35 -0400 |
---|---|---|
committer | Zack Weinberg <zackw@panix.com> | 2021-09-18 11:28:35 -0400 |
commit | d2b2a03a240be1d798612dec06e4889d98af8713 (patch) | |
tree | 53b7c18350c68a985a29bdb8a84a699ab200a4b1 | |
parent | c2e8b0ee81e9f523a1aebaa4a80cba1af660395a (diff) | |
download | autoconf-d2b2a03a240be1d798612dec06e4889d98af8713.tar.gz |
Log more stuff in log_environment
- Number of available CPUs
- On Linux, attempt to identify the build C library
(currently only knows about glibc and musl)
-rw-r--r-- | BuildCommon.pm | 48 | ||||
-rwxr-xr-x | log_environment | 80 |
2 files changed, 126 insertions, 2 deletions
diff --git a/BuildCommon.pm b/BuildCommon.pm index 2f598c42..321442ce 100644 --- a/BuildCommon.pm +++ b/BuildCommon.pm @@ -33,6 +33,7 @@ BEGIN { @EXPORT_OK = qw( ensure_C_locale error + get_status_and_output popen run sh_split @@ -181,6 +182,53 @@ sub popen { return $fh; } +# Run, and log execution of, a subprocess. Capture all of its output, +# including both stdout and stderr. +# @_ should be an argument vector. +# If the subprocess exits normally (successful or unsuccessful), +# returns a list whose first element is the exit status, followed by +# all the lines of output from the subprocess (stdout and stderr are +# intermingled). +# If the subprocess could not be started because there is no such command, +# returns (-1,). +# Otherwise invocation_error/subprocess_error are called as appropriate. +sub get_status_and_output { + die 'get_status_and_output: no command to execute' + if scalar(@_) == 0; + log_execution(@_); + + my $pid = open(my $fh, '-|') + // invocation_error($_[0]); + + if ($pid == 0) { + # child + open(STDERR, ">&STDOUT") or do { + print {*STDERR} "Can't dup STDOUT: $!\n"; + exit(127); + }; + { exec {$_[0]} @_; }; + exit(126) if $!{ENOENT}; + print {*STDERR} "exec $_[0] failed: $!\n"; + exit(127); + } + + # parent + my @lines = <$fh>; + close $fh or do { + if ($! != 0 || ($? & 0x7F) != 0) { + subprocess_error(@_); + } + }; + my $status = $? >> 8; + if ($status == 127) { + subprocess_error(@_); + } + if ($status == 126) { + $status = -1; + } + return ($status, @lines); +} + # Force use of the C locale for this process and all subprocesses. # This is necessary because subprocesses' output may be locale- # dependent. If the C.UTF-8 locale is available, it is used, diff --git a/log_environment b/log_environment index aa33591d..5aa13db1 100755 --- a/log_environment +++ b/log_environment @@ -24,7 +24,7 @@ use warnings FATAL => 'all'; use utf8; use open qw(:utf8); -use Cwd qw(cwd); +use Cwd qw(getcwd); use FindBin (); use POSIX (); @@ -32,11 +32,69 @@ use lib $FindBin::Bin; use BuildCommon qw( ensure_C_locale error + get_status_and_output run sh_quote which ); +# C library detection for Linux. Algorithm from NPM package 'detect-libc', +# <https://github.com/lovell/detect-libc>; currently only supports GNU and +# musl libc. If cross-compiling, the result is for the build environment, +# not the host or target. Does not use a C compiler. +sub report_linux_libc { + # Try getconf. + my ($gcstat, @gcout) = get_status_and_output('getconf', 'GNU_LIBC_VERSION'); + if ($gcstat == 0) { + my $gcver = $gcout[0]; + chomp $gcver; + print "C library: $gcver\n\n"; + return; + } elsif ($gcstat == -1) { + print "getconf: command not found\n"; + } + + # Try ldd --version. + my ($ldstat, @ldout) = get_status_and_output('ldd', '--version'); + if ($ldstat == 0 || $ldstat == 1) { + my $ld1 = $ldout[0]; + my $ld2 = $ldout[1]; + if ($ld1 =~ /\bmusl\b/ia) { + $ld2 =~ s/^version\s+(\S+).*$/$1/i; + print "C library: musl $ld2\n\n"; + return; + } + if ($ld2 =~ /^copyright.*free software foundation/i) { + $ld1 =~ s/^\S+\s+\([^\)]+\)\s+//; + $ld1 =~ s/\s+\z//; + print "C library: glibc $ld1\n\n"; + return; + } + + print "WARNING: ldd --version output not recognized:\n"; + for my $line (@ldout) { + print '> ', $line; + } + print "\n"; + + } elsif ($ldstat == -1) { + print "ldd: command not found\n"; + } else { + print "WARNING: ldd --version exit $ldstat\n"; + for my $line (@ldout) { + print '> ', $line; + } + print "\n"; + } + + # detect-libc goes on to poke around in /lib, which I don't think is + # solid enough to base an actual detection on, but we may as well list + # contents that may be relevant. + print "C library: unknown\n\n"; + run("ls", "-l", glob('/lib*/{libc[.-],ld[-.]*.so}*')); + print "\n"; +} + sub report_machine { print "## Machine information:\n\n"; @@ -47,7 +105,25 @@ sub report_machine { print '$(uname -v) = ', sh_quote($version || 'unknown'), "\n"; print "\n"; - my $cwd = cwd(); + if ($sysname eq 'Linux') { + report_linux_libc(); + } + + my ($npstat, @npout) = get_status_and_output('nproc'); + if ($npstat == 0) { + chomp @npout; + print '$(nproc) = ', $npout[0], "\n"; + } elsif ($npstat == -1) { + print "nproc: command not found\n"; + } else { + print "nproc: exit $npstat\n"; + for my $line (@npout) { + print '> ', $line; + } + } + + print "\n"; + my $cwd = getcwd(); my $qcwd = sh_quote($cwd); print '$(pwd) = ', $qcwd, "\n"; print "WARNING: working directory requires quotation\n" |