summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2021-09-18 11:28:35 -0400
committerZack Weinberg <zackw@panix.com>2021-09-18 11:28:35 -0400
commitd2b2a03a240be1d798612dec06e4889d98af8713 (patch)
tree53b7c18350c68a985a29bdb8a84a699ab200a4b1
parentc2e8b0ee81e9f523a1aebaa4a80cba1af660395a (diff)
downloadautoconf-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.pm48
-rwxr-xr-xlog_environment80
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"