]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Log more stuff in log_environment
authorZack Weinberg <zackw@panix.com>
Sat, 18 Sep 2021 15:28:35 +0000 (11:28 -0400)
committerZack Weinberg <zackw@panix.com>
Sat, 18 Sep 2021 15:28:35 +0000 (11:28 -0400)
- Number of available CPUs
- On Linux, attempt to identify the build C library
  (currently only knows about glibc and musl)

BuildCommon.pm
log_environment

index 2f598c423430e0be220903bd0b735e8967afc84e..321442cef0dffb0ac42209ac17f78f2dc0d0892d 100644 (file)
@@ -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,
index aa33591d3928da722e9155f59b3303fe2d1ba557..5aa13db17faee8839ce9772cae41b098062f5985 100755 (executable)
@@ -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"