summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 15:26:46 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 15:26:46 +0000
commitdf6d86d8822458cf787b5f5620490d6a962da3b8 (patch)
tree8d499fa24a32a195bd6e384dfb70639c45c4a9bb /scripts
parent2c7242b971fd7b63fa842df15ec6fa3d0ff8aeb0 (diff)
parent1949a12d5da678a8532359a95717d8e63910d93b (diff)
Merge commit 'refs/top-bases/t/____longjmp_chk' into t/____longjmp_chkt/____longjmp_chk
Diffstat (limited to 'scripts')
-rw-r--r--scripts/abilist.awk3
-rw-r--r--scripts/backport-support.sh110
-rw-r--r--scripts/begin-end-check.pl47
-rwxr-xr-xscripts/build-many-glibcs.py1676
-rwxr-xr-xscripts/check-c++-types.sh10
-rw-r--r--scripts/check-execstack.awk27
-rw-r--r--scripts/check-initfini.awk63
-rw-r--r--scripts/check-installed-headers.sh174
-rwxr-xr-xscripts/check-local-headers.sh4
-rwxr-xr-xscripts/config.guess227
-rwxr-xr-xscripts/config.sub91
-rwxr-xr-xscripts/cross-test-ssh.sh2
-rwxr-xr-xscripts/evaluate-test.sh2
-rw-r--r--scripts/gen-py-const.awk118
-rw-r--r--scripts/gen-rrtypes.py68
-rwxr-xr-xscripts/gen-sorted.awk36
-rw-r--r--scripts/gen-tunables.awk174
-rwxr-xr-xscripts/install-sh22
-rwxr-xr-xscripts/list-fixed-bugs.py2
-rwxr-xr-xscripts/merge-test-results.sh2
-rwxr-xr-xscripts/mkinstalldirs4
-rwxr-xr-xscripts/move-if-change10
-rwxr-xr-xscripts/rellns-sh2
-rw-r--r--scripts/sysd-rules.awk6
-rwxr-xr-xscripts/test-installation.pl21
-rw-r--r--scripts/test_printers_common.py368
-rw-r--r--scripts/test_printers_exceptions.py61
-rw-r--r--scripts/update-abilist.sh7
-rwxr-xr-xscripts/update-copyrights4
-rw-r--r--scripts/versionlist.awk2
-rw-r--r--scripts/versions.awk38
31 files changed, 3125 insertions, 256 deletions
diff --git a/scripts/abilist.awk b/scripts/abilist.awk
index bd740d4693..bad7c3807e 100644
--- a/scripts/abilist.awk
+++ b/scripts/abilist.awk
@@ -72,8 +72,7 @@ $2 == "g" || $2 == "w" && (NF == 7 || NF == 8) {
seen_opd = -1;
}
else if ($4 == "*ABS*") {
- type = "A";
- size = "";
+ next;
}
else if (type == "DO") {
type = "D";
diff --git a/scripts/backport-support.sh b/scripts/backport-support.sh
new file mode 100644
index 0000000000..4057e42d3c
--- /dev/null
+++ b/scripts/backport-support.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+# Create a patch which backports the support/ subdirectory.
+# Copyright (C) 2017-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# This script does not backport the Makefile tweaks outside the
+# support/ directory (which need to be backported separately), or the
+# changes to test-skeleton.c (which should not be backported).
+
+set -e
+
+export LC_ALL=C
+export GIT_CONFIG=/dev/null
+export GTT_CONFIG_NOSYSTEM=0
+export GIT_PAGER=
+
+usage () {
+ cat >&2 <<EOF
+usage: $0 {patch|commit}
+EOF
+ exit 1
+}
+
+if test $# -ne 1 ; then
+ usage
+fi
+
+command="$1"
+
+case "$command" in
+ patch|commit)
+ ;;
+ *)
+ usage
+ ;;
+esac
+
+# The upstream branch to work on.
+branch=origin/master
+
+# The commit which added the support/ directory.
+initial_commit=c23de0aacbeaa7a091609b35764bed931475a16d
+
+# We backport the support directory and this script. Directories need
+# to end in a /.
+patch_targets="support/ scripts/backport-support.sh"
+
+latest_commit="$(git log --max-count=1 --pretty=format:%H "$branch" -- \
+ $patch_targets)"
+
+# Simplify the branch name somewhat for reporting.
+branch_name="$(echo "$branch" | sed s,^origin/,,)"
+
+command_patch () {
+ cat <<EOF
+This patch creates the contents of the support/ directory up to this
+upstream commit on the $branch_name branch:
+
+EOF
+ git log --max-count=1 "$latest_commit"
+ echo
+ git diff "$initial_commit"^.."$latest_commit" $patch_targets
+ echo "# Before applying the patch, run this command:" >&2
+ echo "# rm -rf $patch_targets" >&2
+}
+
+command_commit () {
+ git status --porcelain | while read line ; do
+ echo "error: working copy is not clean, cannot commit" >&2
+ exit 1
+ done
+ for path in $patch_targets; do
+ echo "# Processing $path" >&2
+ case "$path" in
+ [a-zA-Z0-9]*/)
+ # Directory.
+ git rm --cached --ignore-unmatch -r "$path"
+ rm -rf "$path"
+ git read-tree --prefix="$path" "$latest_commit":"$path"
+ git checkout "$path"
+ ;;
+ *)
+ # File.
+ git show "$latest_commit":"$path" > "$path"
+ git add "$path"
+ esac
+ done
+ git commit -m "Synchronize support/ infrastructure with $branch_name
+
+This commit updates the support/ subdirectory to
+commit $latest_commit
+on the $branch_name branch.
+"
+}
+
+command_$command
diff --git a/scripts/begin-end-check.pl b/scripts/begin-end-check.pl
deleted file mode 100644
index 1616931bb0..0000000000
--- a/scripts/begin-end-check.pl
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-# Check __BEGIN_NAMESPACE ... __END_NAMESPACE pairing in an include file.
-
-my $code = 0;
-for my $path (@ARGV) {
- my $localcode = 0;
- my @stack;
-
- open my $in, '<', $path
- or die "open $path failed: $!";
-
- while (<$in>) {
- if ( /^\s*__BEGIN_(.*)\b/ ) {
- push @stack, $1;
- }
- elsif ( /^\s*__END_(.*)\b/ ) {
- if (@stack) {
- my $tag = pop @stack;
- if ($1 ne $tag) {
- print "$path:$.: BEGIN $tag paired with END $1\n";
- $localcode = 1;
- }
- }
- else {
- print "$path:$.: END $1 does not match a begin\n";
- $localcode = 1;
- }
- }
- }
-
- if (@stack) {
- print "$path: Unmatched begin tags " . join (' ', @stack) ."\n";
- $localcode = 1;
- }
-
- if ($localcode == 0) {
- print "$path: OK\n";
- } else {
- $code = $localcode;
- }
-}
-
-exit $code;
diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
new file mode 100755
index 0000000000..8ef463f57a
--- /dev/null
+++ b/scripts/build-many-glibcs.py
@@ -0,0 +1,1676 @@
+#!/usr/bin/python3
+# Build many configurations of glibc.
+# Copyright (C) 2016-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+"""Build many configurations of glibc.
+
+This script takes as arguments a directory name (containing a src
+subdirectory with sources of the relevant toolchain components) and a
+description of what to do: 'checkout', to check out sources into that
+directory, 'bot-cycle', to run a series of checkout and build steps,
+'bot', to run 'bot-cycle' repeatedly, 'host-libraries', to build
+libraries required by the toolchain, 'compilers', to build
+cross-compilers for various configurations, or 'glibcs', to build
+glibc for various configurations and run the compilation parts of the
+testsuite. Subsequent arguments name the versions of components to
+check out (<component>-<version), for 'checkout', or, for actions
+other than 'checkout' and 'bot-cycle', name configurations for which
+compilers or glibc are to be built.
+
+"""
+
+import argparse
+import datetime
+import email.mime.text
+import email.utils
+import json
+import os
+import re
+import shutil
+import smtplib
+import stat
+import subprocess
+import sys
+import time
+import urllib.request
+
+try:
+ os.cpu_count
+except:
+ import multiprocessing
+ os.cpu_count = lambda: multiprocessing.cpu_count()
+
+try:
+ re.fullmatch
+except:
+ re.fullmatch = lambda p,s,f=0: re.match(p+"\\Z",s,f)
+
+try:
+ subprocess.run
+except:
+ class _CompletedProcess:
+ def __init__(self, args, returncode, stdout=None, stderr=None):
+ self.args = args
+ self.returncode = returncode
+ self.stdout = stdout
+ self.stderr = stderr
+
+ def _run(*popenargs, input=None, timeout=None, check=False, **kwargs):
+ assert(timeout is None)
+ with subprocess.Popen(*popenargs, **kwargs) as process:
+ try:
+ stdout, stderr = process.communicate(input)
+ except:
+ process.kill()
+ process.wait()
+ raise
+ returncode = process.poll()
+ if check and returncode:
+ raise subprocess.CalledProcessError(returncode, popenargs)
+ return _CompletedProcess(popenargs, returncode, stdout, stderr)
+
+ subprocess.run = _run
+
+
+class Context(object):
+ """The global state associated with builds in a given directory."""
+
+ def __init__(self, topdir, parallelism, keep, replace_sources, strip,
+ action):
+ """Initialize the context."""
+ self.topdir = topdir
+ self.parallelism = parallelism
+ self.keep = keep
+ self.replace_sources = replace_sources
+ self.strip = strip
+ self.srcdir = os.path.join(topdir, 'src')
+ self.versions_json = os.path.join(self.srcdir, 'versions.json')
+ self.build_state_json = os.path.join(topdir, 'build-state.json')
+ self.bot_config_json = os.path.join(topdir, 'bot-config.json')
+ self.installdir = os.path.join(topdir, 'install')
+ self.host_libraries_installdir = os.path.join(self.installdir,
+ 'host-libraries')
+ self.builddir = os.path.join(topdir, 'build')
+ self.logsdir = os.path.join(topdir, 'logs')
+ self.logsdir_old = os.path.join(topdir, 'logs-old')
+ self.makefile = os.path.join(self.builddir, 'Makefile')
+ self.wrapper = os.path.join(self.builddir, 'wrapper')
+ self.save_logs = os.path.join(self.builddir, 'save-logs')
+ self.script_text = self.get_script_text()
+ if action != 'checkout':
+ self.build_triplet = self.get_build_triplet()
+ self.glibc_version = self.get_glibc_version()
+ self.configs = {}
+ self.glibc_configs = {}
+ self.makefile_pieces = ['.PHONY: all\n']
+ self.add_all_configs()
+ self.load_versions_json()
+ self.load_build_state_json()
+ self.status_log_list = []
+ self.email_warning = False
+
+ def get_script_text(self):
+ """Return the text of this script."""
+ with open(sys.argv[0], 'r') as f:
+ return f.read()
+
+ def exec_self(self):
+ """Re-execute this script with the same arguments."""
+ sys.stdout.flush()
+ os.execv(sys.executable, [sys.executable] + sys.argv)
+
+ def get_build_triplet(self):
+ """Determine the build triplet with config.guess."""
+ config_guess = os.path.join(self.component_srcdir('gcc'),
+ 'config.guess')
+ cg_out = subprocess.run([config_guess], stdout=subprocess.PIPE,
+ check=True, universal_newlines=True).stdout
+ return cg_out.rstrip()
+
+ def get_glibc_version(self):
+ """Determine the glibc version number (major.minor)."""
+ version_h = os.path.join(self.component_srcdir('glibc'), 'version.h')
+ with open(version_h, 'r') as f:
+ lines = f.readlines()
+ starttext = '#define VERSION "'
+ for l in lines:
+ if l.startswith(starttext):
+ l = l[len(starttext):]
+ l = l.rstrip('"\n')
+ m = re.fullmatch('([0-9]+)\.([0-9]+)[.0-9]*', l)
+ return '%s.%s' % m.group(1, 2)
+ print('error: could not determine glibc version')
+ exit(1)
+
+ def add_all_configs(self):
+ """Add all known glibc build configurations."""
+ self.add_config(arch='aarch64',
+ os_name='linux-gnu',
+ extra_glibcs=[{'variant': 'disable-multi-arch',
+ 'cfg': ['--disable-multi-arch']}])
+ self.add_config(arch='aarch64_be',
+ os_name='linux-gnu')
+ self.add_config(arch='alpha',
+ os_name='linux-gnu')
+ self.add_config(arch='arm',
+ os_name='linux-gnueabi')
+ self.add_config(arch='armeb',
+ os_name='linux-gnueabi')
+ self.add_config(arch='armeb',
+ os_name='linux-gnueabi',
+ variant='be8',
+ gcc_cfg=['--with-arch=armv7-a'])
+ self.add_config(arch='arm',
+ os_name='linux-gnueabihf',
+ gcc_cfg=['--with-float=hard', '--with-cpu=arm926ej-s'],
+ extra_glibcs=[{'variant': 'v7a',
+ 'ccopts': '-march=armv7-a -mfpu=vfpv3'},
+ {'variant': 'v7a-disable-multi-arch',
+ 'ccopts': '-march=armv7-a -mfpu=vfpv3',
+ 'cfg': ['--disable-multi-arch']}])
+ self.add_config(arch='armeb',
+ os_name='linux-gnueabihf',
+ gcc_cfg=['--with-float=hard', '--with-cpu=arm926ej-s'])
+ self.add_config(arch='armeb',
+ os_name='linux-gnueabihf',
+ variant='be8',
+ gcc_cfg=['--with-float=hard', '--with-arch=armv7-a',
+ '--with-fpu=vfpv3'])
+ self.add_config(arch='hppa',
+ os_name='linux-gnu')
+ self.add_config(arch='i686',
+ os_name='gnu')
+ self.add_config(arch='ia64',
+ os_name='linux-gnu',
+ first_gcc_cfg=['--with-system-libunwind'])
+ self.add_config(arch='m68k',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib'])
+ self.add_config(arch='m68k',
+ os_name='linux-gnu',
+ variant='coldfire',
+ gcc_cfg=['--with-arch=cf', '--disable-multilib'])
+ self.add_config(arch='m68k',
+ os_name='linux-gnu',
+ variant='coldfire-soft',
+ gcc_cfg=['--with-arch=cf', '--with-cpu=54455',
+ '--disable-multilib'])
+ self.add_config(arch='microblaze',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib'])
+ self.add_config(arch='microblazeel',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib'])
+ self.add_config(arch='mips64',
+ os_name='linux-gnu',
+ gcc_cfg=['--with-mips-plt'],
+ glibcs=[{'variant': 'n32'},
+ {'arch': 'mips',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--with-mips-plt', '--with-float=soft'],
+ glibcs=[{'variant': 'n32-soft'},
+ {'variant': 'soft',
+ 'arch': 'mips',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64-soft',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64',
+ os_name='linux-gnu',
+ variant='nan2008',
+ gcc_cfg=['--with-mips-plt', '--with-nan=2008',
+ '--with-arch-64=mips64r2',
+ '--with-arch-32=mips32r2'],
+ glibcs=[{'variant': 'n32-nan2008'},
+ {'variant': 'nan2008',
+ 'arch': 'mips',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64-nan2008',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64',
+ os_name='linux-gnu',
+ variant='nan2008-soft',
+ gcc_cfg=['--with-mips-plt', '--with-nan=2008',
+ '--with-arch-64=mips64r2',
+ '--with-arch-32=mips32r2',
+ '--with-float=soft'],
+ glibcs=[{'variant': 'n32-nan2008-soft'},
+ {'variant': 'nan2008-soft',
+ 'arch': 'mips',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64-nan2008-soft',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64el',
+ os_name='linux-gnu',
+ gcc_cfg=['--with-mips-plt'],
+ glibcs=[{'variant': 'n32'},
+ {'arch': 'mipsel',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64el',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--with-mips-plt', '--with-float=soft'],
+ glibcs=[{'variant': 'n32-soft'},
+ {'variant': 'soft',
+ 'arch': 'mipsel',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64-soft',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64el',
+ os_name='linux-gnu',
+ variant='nan2008',
+ gcc_cfg=['--with-mips-plt', '--with-nan=2008',
+ '--with-arch-64=mips64r2',
+ '--with-arch-32=mips32r2'],
+ glibcs=[{'variant': 'n32-nan2008'},
+ {'variant': 'nan2008',
+ 'arch': 'mipsel',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64-nan2008',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='mips64el',
+ os_name='linux-gnu',
+ variant='nan2008-soft',
+ gcc_cfg=['--with-mips-plt', '--with-nan=2008',
+ '--with-arch-64=mips64r2',
+ '--with-arch-32=mips32r2',
+ '--with-float=soft'],
+ glibcs=[{'variant': 'n32-nan2008-soft'},
+ {'variant': 'nan2008-soft',
+ 'arch': 'mipsel',
+ 'ccopts': '-mabi=32'},
+ {'variant': 'n64-nan2008-soft',
+ 'ccopts': '-mabi=64'}])
+ self.add_config(arch='nios2',
+ os_name='linux-gnu')
+ self.add_config(arch='powerpc',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt'],
+ extra_glibcs=[{'variant': 'power4',
+ 'ccopts': '-mcpu=power4',
+ 'cfg': ['--with-cpu=power4']}])
+ self.add_config(arch='powerpc',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--disable-multilib', '--with-float=soft',
+ '--enable-secureplt'])
+ self.add_config(arch='powerpc64',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt'])
+ self.add_config(arch='powerpc64le',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt'])
+ self.add_config(arch='powerpc',
+ os_name='linux-gnuspe',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt',
+ '--enable-e500-double', '--enable-obsolete'])
+ self.add_config(arch='powerpc',
+ os_name='linux-gnuspe',
+ variant='e500v1',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt',
+ '--enable-obsolete'])
+ self.add_config(arch='riscv64',
+ os_name='linux-gnu',
+ variant='rv64imac-lp64',
+ gcc_cfg=['--with-arch=rv64imac', '--with-abi=lp64',
+ '--disable-multilib'])
+ self.add_config(arch='riscv64',
+ os_name='linux-gnu',
+ variant='rv64imafdc-lp64',
+ gcc_cfg=['--with-arch=rv64imafdc', '--with-abi=lp64',
+ '--disable-multilib'])
+ self.add_config(arch='riscv64',
+ os_name='linux-gnu',
+ variant='rv64imafdc-lp64d',
+ gcc_cfg=['--with-arch=rv64imafdc', '--with-abi=lp64d',
+ '--disable-multilib'])
+ self.add_config(arch='s390x',
+ os_name='linux-gnu',
+ glibcs=[{},
+ {'arch': 's390', 'ccopts': '-m31'}])
+ self.add_config(arch='sh3',
+ os_name='linux-gnu')
+ self.add_config(arch='sh3eb',
+ os_name='linux-gnu')
+ self.add_config(arch='sh4',
+ os_name='linux-gnu')
+ self.add_config(arch='sh4eb',
+ os_name='linux-gnu')
+ self.add_config(arch='sh4',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--without-fp'])
+ self.add_config(arch='sh4eb',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--without-fp'])
+ self.add_config(arch='sparc64',
+ os_name='linux-gnu',
+ glibcs=[{},
+ {'arch': 'sparcv9',
+ 'ccopts': '-m32 -mlong-double-128'}],
+ extra_glibcs=[{'variant': 'disable-multi-arch',
+ 'cfg': ['--disable-multi-arch']},
+ {'variant': 'disable-multi-arch',
+ 'arch': 'sparcv9',
+ 'ccopts': '-m32 -mlong-double-128',
+ 'cfg': ['--disable-multi-arch']}])
+ self.add_config(arch='x86_64',
+ os_name='linux-gnu',
+ gcc_cfg=['--with-multilib-list=m64,m32,mx32'],
+ glibcs=[{},
+ {'variant': 'x32', 'ccopts': '-mx32'},
+ {'arch': 'i686', 'ccopts': '-m32 -march=i686'}],
+ extra_glibcs=[{'variant': 'disable-multi-arch',
+ 'cfg': ['--disable-multi-arch']},
+ {'variant': 'static-pie',
+ 'cfg': ['--enable-static-pie']},
+ {'variant': 'x32-static-pie',
+ 'ccopts': '-mx32',
+ 'cfg': ['--enable-static-pie']},
+ {'variant': 'static-pie',
+ 'arch': 'i686',
+ 'ccopts': '-m32 -march=i686',
+ 'cfg': ['--enable-static-pie']},
+ {'variant': 'disable-multi-arch',
+ 'arch': 'i686',
+ 'ccopts': '-m32 -march=i686',
+ 'cfg': ['--disable-multi-arch']},
+ {'arch': 'i486',
+ 'ccopts': '-m32 -march=i486'},
+ {'arch': 'i586',
+ 'ccopts': '-m32 -march=i586'}])
+
+ def add_config(self, **args):
+ """Add an individual build configuration."""
+ cfg = Config(self, **args)
+ if cfg.name in self.configs:
+ print('error: duplicate config %s' % cfg.name)
+ exit(1)
+ self.configs[cfg.name] = cfg
+ for c in cfg.all_glibcs:
+ if c.name in self.glibc_configs:
+ print('error: duplicate glibc config %s' % c.name)
+ exit(1)
+ self.glibc_configs[c.name] = c
+
+ def component_srcdir(self, component):
+ """Return the source directory for a given component, e.g. gcc."""
+ return os.path.join(self.srcdir, component)
+
+ def component_builddir(self, action, config, component, subconfig=None):
+ """Return the directory to use for a build."""
+ if config is None:
+ # Host libraries.
+ assert subconfig is None
+ return os.path.join(self.builddir, action, component)
+ if subconfig is None:
+ return os.path.join(self.builddir, action, config, component)
+ else:
+ # glibc build as part of compiler build.
+ return os.path.join(self.builddir, action, config, component,
+ subconfig)
+
+ def compiler_installdir(self, config):
+ """Return the directory in which to install a compiler."""
+ return os.path.join(self.installdir, 'compilers', config)
+
+ def compiler_bindir(self, config):
+ """Return the directory in which to find compiler binaries."""
+ return os.path.join(self.compiler_installdir(config), 'bin')
+
+ def compiler_sysroot(self, config):
+ """Return the sysroot directory for a compiler."""
+ return os.path.join(self.compiler_installdir(config), 'sysroot')
+
+ def glibc_installdir(self, config):
+ """Return the directory in which to install glibc."""
+ return os.path.join(self.installdir, 'glibcs', config)
+
+ def run_builds(self, action, configs):
+ """Run the requested builds."""
+ if action == 'checkout':
+ self.checkout(configs)
+ return
+ if action == 'bot-cycle':
+ if configs:
+ print('error: configurations specified for bot-cycle')
+ exit(1)
+ self.bot_cycle()
+ return
+ if action == 'bot':
+ if configs:
+ print('error: configurations specified for bot')
+ exit(1)
+ self.bot()
+ return
+ if action == 'host-libraries' and configs:
+ print('error: configurations specified for host-libraries')
+ exit(1)
+ self.clear_last_build_state(action)
+ build_time = datetime.datetime.utcnow()
+ if action == 'host-libraries':
+ build_components = ('gmp', 'mpfr', 'mpc')
+ old_components = ()
+ old_versions = {}
+ self.build_host_libraries()
+ elif action == 'compilers':
+ build_components = ('binutils', 'gcc', 'glibc', 'linux', 'mig',
+ 'gnumach', 'hurd')
+ old_components = ('gmp', 'mpfr', 'mpc')
+ old_versions = self.build_state['host-libraries']['build-versions']
+ self.build_compilers(configs)
+ else:
+ build_components = ('glibc',)
+ old_components = ('gmp', 'mpfr', 'mpc', 'binutils', 'gcc', 'linux',
+ 'mig', 'gnumach', 'hurd')
+ old_versions = self.build_state['compilers']['build-versions']
+ self.build_glibcs(configs)
+ self.write_files()
+ self.do_build()
+ if configs:
+ # Partial build, do not update stored state.
+ return
+ build_versions = {}
+ for k in build_components:
+ if k in self.versions:
+ build_versions[k] = {'version': self.versions[k]['version'],
+ 'revision': self.versions[k]['revision']}
+ for k in old_components:
+ if k in old_versions:
+ build_versions[k] = {'version': old_versions[k]['version'],
+ 'revision': old_versions[k]['revision']}
+ self.update_build_state(action, build_time, build_versions)
+
+ @staticmethod
+ def remove_dirs(*args):
+ """Remove directories and their contents if they exist."""
+ for dir in args:
+ shutil.rmtree(dir, ignore_errors=True)
+
+ @staticmethod
+ def remove_recreate_dirs(*args):
+ """Remove directories if they exist, and create them as empty."""
+ Context.remove_dirs(*args)
+ for dir in args:
+ os.makedirs(dir, exist_ok=True)
+
+ def add_makefile_cmdlist(self, target, cmdlist, logsdir):
+ """Add makefile text for a list of commands."""
+ commands = cmdlist.makefile_commands(self.wrapper, logsdir)
+ self.makefile_pieces.append('all: %s\n.PHONY: %s\n%s:\n%s\n' %
+ (target, target, target, commands))
+ self.status_log_list.extend(cmdlist.status_logs(logsdir))
+
+ def write_files(self):
+ """Write out the Makefile and wrapper script."""
+ mftext = ''.join(self.makefile_pieces)
+ with open(self.makefile, 'w') as f:
+ f.write(mftext)
+ wrapper_text = (
+ '#!/bin/sh\n'
+ 'prev_base=$1\n'
+ 'this_base=$2\n'
+ 'desc=$3\n'
+ 'dir=$4\n'
+ 'path=$5\n'
+ 'shift 5\n'
+ 'prev_status=$prev_base-status.txt\n'
+ 'this_status=$this_base-status.txt\n'
+ 'this_log=$this_base-log.txt\n'
+ 'date > "$this_log"\n'
+ 'echo >> "$this_log"\n'
+ 'echo "Description: $desc" >> "$this_log"\n'
+ 'printf "%s" "Command:" >> "$this_log"\n'
+ 'for word in "$@"; do\n'
+ ' if expr "$word" : "[]+,./0-9@A-Z_a-z-]\\\\{1,\\\\}\\$" > /dev/null; then\n'
+ ' printf " %s" "$word"\n'
+ ' else\n'
+ ' printf " \'"\n'
+ ' printf "%s" "$word" | sed -e "s/\'/\'\\\\\\\\\'\'/"\n'
+ ' printf "\'"\n'
+ ' fi\n'
+ 'done >> "$this_log"\n'
+ 'echo >> "$this_log"\n'
+ 'echo "Directory: $dir" >> "$this_log"\n'
+ 'echo "Path addition: $path" >> "$this_log"\n'
+ 'echo >> "$this_log"\n'
+ 'record_status ()\n'
+ '{\n'
+ ' echo >> "$this_log"\n'
+ ' echo "$1: $desc" > "$this_status"\n'
+ ' echo "$1: $desc" >> "$this_log"\n'
+ ' echo >> "$this_log"\n'
+ ' date >> "$this_log"\n'
+ ' echo "$1: $desc"\n'
+ ' exit 0\n'
+ '}\n'
+ 'check_error ()\n'
+ '{\n'
+ ' if [ "$1" != "0" ]; then\n'
+ ' record_status FAIL\n'
+ ' fi\n'
+ '}\n'
+ 'if [ "$prev_base" ] && ! grep -q "^PASS" "$prev_status"; then\n'
+ ' record_status UNRESOLVED\n'
+ 'fi\n'
+ 'if [ "$dir" ]; then\n'
+ ' cd "$dir"\n'
+ ' check_error "$?"\n'
+ 'fi\n'
+ 'if [ "$path" ]; then\n'
+ ' PATH=$path:$PATH\n'
+ 'fi\n'
+ '"$@" < /dev/null >> "$this_log" 2>&1\n'
+ 'check_error "$?"\n'
+ 'record_status PASS\n')
+ with open(self.wrapper, 'w') as f:
+ f.write(wrapper_text)
+ # Mode 0o755.
+ mode_exec = (stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|
+ stat.S_IROTH|stat.S_IXOTH)
+ os.chmod(self.wrapper, mode_exec)
+ save_logs_text = (
+ '#!/bin/sh\n'
+ 'if ! [ -f tests.sum ]; then\n'
+ ' echo "No test summary available."\n'
+ ' exit 0\n'
+ 'fi\n'
+ 'save_file ()\n'
+ '{\n'
+ ' echo "Contents of $1:"\n'
+ ' echo\n'
+ ' cat "$1"\n'
+ ' echo\n'
+ ' echo "End of contents of $1."\n'
+ ' echo\n'
+ '}\n'
+ 'save_file tests.sum\n'
+ 'non_pass_tests=$(grep -v "^PASS: " tests.sum | sed -e "s/^PASS: //")\n'
+ 'for t in $non_pass_tests; do\n'
+ ' if [ -f "$t.out" ]; then\n'
+ ' save_file "$t.out"\n'
+ ' fi\n'
+ 'done\n')
+ with open(self.save_logs, 'w') as f:
+ f.write(save_logs_text)
+ os.chmod(self.save_logs, mode_exec)
+
+ def do_build(self):
+ """Do the actual build."""
+ cmd = ['make', '-j%d' % self.parallelism]
+ subprocess.run(cmd, cwd=self.builddir, check=True)
+
+ def build_host_libraries(self):
+ """Build the host libraries."""
+ installdir = self.host_libraries_installdir
+ builddir = os.path.join(self.builddir, 'host-libraries')
+ logsdir = os.path.join(self.logsdir, 'host-libraries')
+ self.remove_recreate_dirs(installdir, builddir, logsdir)
+ cmdlist = CommandList('host-libraries', self.keep)
+ self.build_host_library(cmdlist, 'gmp')
+ self.build_host_library(cmdlist, 'mpfr',
+ ['--with-gmp=%s' % installdir])
+ self.build_host_library(cmdlist, 'mpc',
+ ['--with-gmp=%s' % installdir,
+ '--with-mpfr=%s' % installdir])
+ cmdlist.add_command('done', ['touch', os.path.join(installdir, 'ok')])
+ self.add_makefile_cmdlist('host-libraries', cmdlist, logsdir)
+
+ def build_host_library(self, cmdlist, lib, extra_opts=None):
+ """Build one host library."""
+ srcdir = self.component_srcdir(lib)
+ builddir = self.component_builddir('host-libraries', None, lib)
+ installdir = self.host_libraries_installdir
+ cmdlist.push_subdesc(lib)
+ cmdlist.create_use_dir(builddir)
+ cfg_cmd = [os.path.join(srcdir, 'configure'),
+ '--prefix=%s' % installdir,
+ '--disable-shared']
+ if extra_opts:
+ cfg_cmd.extend (extra_opts)
+ cmdlist.add_command('configure', cfg_cmd)
+ cmdlist.add_command('build', ['make'])
+ cmdlist.add_command('check', ['make', 'check'])
+ cmdlist.add_command('install', ['make', 'install'])
+ cmdlist.cleanup_dir()
+ cmdlist.pop_subdesc()
+
+ def build_compilers(self, configs):
+ """Build the compilers."""
+ if not configs:
+ self.remove_dirs(os.path.join(self.builddir, 'compilers'))
+ self.remove_dirs(os.path.join(self.installdir, 'compilers'))
+ self.remove_dirs(os.path.join(self.logsdir, 'compilers'))
+ configs = sorted(self.configs.keys())
+ for c in configs:
+ self.configs[c].build()
+
+ def build_glibcs(self, configs):
+ """Build the glibcs."""
+ if not configs:
+ self.remove_dirs(os.path.join(self.builddir, 'glibcs'))
+ self.remove_dirs(os.path.join(self.installdir, 'glibcs'))
+ self.remove_dirs(os.path.join(self.logsdir, 'glibcs'))
+ configs = sorted(self.glibc_configs.keys())
+ for c in configs:
+ self.glibc_configs[c].build()
+
+ def load_versions_json(self):
+ """Load information about source directory versions."""
+ if not os.access(self.versions_json, os.F_OK):
+ self.versions = {}
+ return
+ with open(self.versions_json, 'r') as f:
+ self.versions = json.load(f)
+
+ def store_json(self, data, filename):
+ """Store information in a JSON file."""
+ filename_tmp = filename + '.tmp'
+ with open(filename_tmp, 'w') as f:
+ json.dump(data, f, indent=2, sort_keys=True)
+ os.rename(filename_tmp, filename)
+
+ def store_versions_json(self):
+ """Store information about source directory versions."""
+ self.store_json(self.versions, self.versions_json)
+
+ def set_component_version(self, component, version, explicit, revision):
+ """Set the version information for a component."""
+ self.versions[component] = {'version': version,
+ 'explicit': explicit,
+ 'revision': revision}
+ self.store_versions_json()
+
+ def checkout(self, versions):
+ """Check out the desired component versions."""
+ default_versions = {'binutils': 'vcs-2.31',
+ 'gcc': 'vcs-8',
+ 'glibc': 'vcs-mainline',
+ 'gmp': '6.1.2',
+ 'linux': '4.17',
+ 'mpc': '1.1.0',
+ 'mpfr': '4.0.1',
+ 'mig': 'vcs-mainline',
+ 'gnumach': 'vcs-mainline',
+ 'hurd': 'vcs-mainline'}
+ use_versions = {}
+ explicit_versions = {}
+ for v in versions:
+ found_v = False
+ for k in default_versions.keys():
+ kx = k + '-'
+ if v.startswith(kx):
+ vx = v[len(kx):]
+ if k in use_versions:
+ print('error: multiple versions for %s' % k)
+ exit(1)
+ use_versions[k] = vx
+ explicit_versions[k] = True
+ found_v = True
+ break
+ if not found_v:
+ print('error: unknown component in %s' % v)
+ exit(1)
+ for k in default_versions.keys():
+ if k not in use_versions:
+ if k in self.versions and self.versions[k]['explicit']:
+ use_versions[k] = self.versions[k]['version']
+ explicit_versions[k] = True
+ else:
+ use_versions[k] = default_versions[k]
+ explicit_versions[k] = False
+ os.makedirs(self.srcdir, exist_ok=True)
+ for k in sorted(default_versions.keys()):
+ update = os.access(self.component_srcdir(k), os.F_OK)
+ v = use_versions[k]
+ if (update and
+ k in self.versions and
+ v != self.versions[k]['version']):
+ if not self.replace_sources:
+ print('error: version of %s has changed from %s to %s, '
+ 'use --replace-sources to check out again' %
+ (k, self.versions[k]['version'], v))
+ exit(1)
+ shutil.rmtree(self.component_srcdir(k))
+ update = False
+ if v.startswith('vcs-'):
+ revision = self.checkout_vcs(k, v[4:], update)
+ else:
+ self.checkout_tar(k, v, update)
+ revision = v
+ self.set_component_version(k, v, explicit_versions[k], revision)
+ if self.get_script_text() != self.script_text:
+ # Rerun the checkout process in case the updated script
+ # uses different default versions or new components.
+ self.exec_self()
+
+ def checkout_vcs(self, component, version, update):
+ """Check out the given version of the given component from version
+ control. Return a revision identifier."""
+ if component == 'binutils':
+ git_url = 'git://sourceware.org/git/binutils-gdb.git'
+ if version == 'mainline':
+ git_branch = 'master'
+ else:
+ trans = str.maketrans({'.': '_'})
+ git_branch = 'binutils-%s-branch' % version.translate(trans)
+ return self.git_checkout(component, git_url, git_branch, update)
+ elif component == 'gcc':
+ if version == 'mainline':
+ branch = 'trunk'
+ else:
+ trans = str.maketrans({'.': '_'})
+ branch = 'branches/gcc-%s-branch' % version.translate(trans)
+ svn_url = 'svn://gcc.gnu.org/svn/gcc/%s' % branch
+ return self.gcc_checkout(svn_url, update)
+ elif component == 'glibc':
+ git_url = 'git://sourceware.org/git/glibc.git'
+ if version == 'mainline':
+ git_branch = 'master'
+ else:
+ git_branch = 'release/%s/master' % version
+ r = self.git_checkout(component, git_url, git_branch, update)
+ self.fix_glibc_timestamps()
+ return r
+ elif component == 'gnumach':
+ git_url = 'git://git.savannah.gnu.org/hurd/gnumach.git'
+ git_branch = 'master'
+ r = self.git_checkout(component, git_url, git_branch, update)
+ subprocess.run(['autoreconf', '-i'],
+ cwd=self.component_srcdir(component), check=True)
+ return r
+ elif component == 'mig':
+ git_url = 'git://git.savannah.gnu.org/hurd/mig.git'
+ git_branch = 'master'
+ r = self.git_checkout(component, git_url, git_branch, update)
+ subprocess.run(['autoreconf', '-i'],
+ cwd=self.component_srcdir(component), check=True)
+ return r
+ elif component == 'hurd':
+ git_url = 'git://git.savannah.gnu.org/hurd/hurd.git'
+ git_branch = 'master'
+ r = self.git_checkout(component, git_url, git_branch, update)
+ subprocess.run(['autoconf'],
+ cwd=self.component_srcdir(component), check=True)
+ return r
+ else:
+ print('error: component %s coming from VCS' % component)
+ exit(1)
+
+ def git_checkout(self, component, git_url, git_branch, update):
+ """Check out a component from git. Return a commit identifier."""
+ if update:
+ subprocess.run(['git', 'remote', 'prune', 'origin'],
+ cwd=self.component_srcdir(component), check=True)
+ if self.replace_sources:
+ subprocess.run(['git', 'clean', '-dxfq'],
+ cwd=self.component_srcdir(component), check=True)
+ subprocess.run(['git', 'pull', '-q'],
+ cwd=self.component_srcdir(component), check=True)
+ else:
+ subprocess.run(['git', 'clone', '-q', '-b', git_branch, git_url,
+ self.component_srcdir(component)], check=True)
+ r = subprocess.run(['git', 'rev-parse', 'HEAD'],
+ cwd=self.component_srcdir(component),
+ stdout=subprocess.PIPE,
+ check=True, universal_newlines=True).stdout
+ return r.rstrip()
+
+ def fix_glibc_timestamps(self):
+ """Fix timestamps in a glibc checkout."""
+ # Ensure that builds do not try to regenerate generated files
+ # in the source tree.
+ srcdir = self.component_srcdir('glibc')
+ for dirpath, dirnames, filenames in os.walk(srcdir):
+ for f in filenames:
+ if (f == 'configure' or
+ f == 'preconfigure' or
+ f.endswith('-kw.h')):
+ to_touch = os.path.join(dirpath, f)
+ subprocess.run(['touch', to_touch], check=True)
+
+ def gcc_checkout(self, svn_url, update):
+ """Check out GCC from SVN. Return the revision number."""
+ if not update:
+ subprocess.run(['svn', 'co', '-q', svn_url,
+ self.component_srcdir('gcc')], check=True)
+ subprocess.run(['contrib/gcc_update', '--silent'],
+ cwd=self.component_srcdir('gcc'), check=True)
+ r = subprocess.run(['svnversion', self.component_srcdir('gcc')],
+ stdout=subprocess.PIPE,
+ check=True, universal_newlines=True).stdout
+ return r.rstrip()
+
+ def checkout_tar(self, component, version, update):
+ """Check out the given version of the given component from a
+ tarball."""
+ if update:
+ return
+ url_map = {'binutils': 'https://ftp.gnu.org/gnu/binutils/binutils-%(version)s.tar.bz2',
+ 'gcc': 'https://ftp.gnu.org/gnu/gcc/gcc-%(version)s/gcc-%(version)s.tar.gz',
+ 'gmp': 'https://ftp.gnu.org/gnu/gmp/gmp-%(version)s.tar.xz',
+ 'linux': 'https://www.kernel.org/pub/linux/kernel/v4.x/linux-%(version)s.tar.xz',
+ 'mpc': 'https://ftp.gnu.org/gnu/mpc/mpc-%(version)s.tar.gz',
+ 'mpfr': 'https://ftp.gnu.org/gnu/mpfr/mpfr-%(version)s.tar.xz',
+ 'mig': 'https://ftp.gnu.org/gnu/mig/mig-%(version)s.tar.bz2',
+ 'gnumach': 'https://ftp.gnu.org/gnu/gnumach/gnumach-%(version)s.tar.bz2',
+ 'hurd': 'https://ftp.gnu.org/gnu/hurd/hurd-%(version)s.tar.bz2'}
+ if component not in url_map:
+ print('error: component %s coming from tarball' % component)
+ exit(1)
+ url = url_map[component] % {'version': version}
+ filename = os.path.join(self.srcdir, url.split('/')[-1])
+ response = urllib.request.urlopen(url)
+ data = response.read()
+ with open(filename, 'wb') as f:
+ f.write(data)
+ subprocess.run(['tar', '-C', self.srcdir, '-x', '-f', filename],
+ check=True)
+ os.rename(os.path.join(self.srcdir, '%s-%s' % (component, version)),
+ self.component_srcdir(component))
+ os.remove(filename)
+
+ def load_build_state_json(self):
+ """Load information about the state of previous builds."""
+ if os.access(self.build_state_json, os.F_OK):
+ with open(self.build_state_json, 'r') as f:
+ self.build_state = json.load(f)
+ else:
+ self.build_state = {}
+ for k in ('host-libraries', 'compilers', 'glibcs'):
+ if k not in self.build_state:
+ self.build_state[k] = {}
+ if 'build-time' not in self.build_state[k]:
+ self.build_state[k]['build-time'] = ''
+ if 'build-versions' not in self.build_state[k]:
+ self.build_state[k]['build-versions'] = {}
+ if 'build-results' not in self.build_state[k]:
+ self.build_state[k]['build-results'] = {}
+ if 'result-changes' not in self.build_state[k]:
+ self.build_state[k]['result-changes'] = {}
+ if 'ever-passed' not in self.build_state[k]:
+ self.build_state[k]['ever-passed'] = []
+
+ def store_build_state_json(self):
+ """Store information about the state of previous builds."""
+ self.store_json(self.build_state, self.build_state_json)
+
+ def clear_last_build_state(self, action):
+ """Clear information about the state of part of the build."""
+ # We clear the last build time and versions when starting a
+ # new build. The results of the last build are kept around,
+ # as comparison is still meaningful if this build is aborted
+ # and a new one started.
+ self.build_state[action]['build-time'] = ''
+ self.build_state[action]['build-versions'] = {}
+ self.store_build_state_json()
+
+ def update_build_state(self, action, build_time, build_versions):
+ """Update the build state after a build."""
+ build_time = build_time.replace(microsecond=0)
+ self.build_state[action]['build-time'] = str(build_time)
+ self.build_state[action]['build-versions'] = build_versions
+ build_results = {}
+ for log in self.status_log_list:
+ with open(log, 'r') as f:
+ log_text = f.read()
+ log_text = log_text.rstrip()
+ m = re.fullmatch('([A-Z]+): (.*)', log_text)
+ result = m.group(1)
+ test_name = m.group(2)
+ assert test_name not in build_results
+ build_results[test_name] = result
+ old_build_results = self.build_state[action]['build-results']
+ self.build_state[action]['build-results'] = build_results
+ result_changes = {}
+ all_tests = set(old_build_results.keys()) | set(build_results.keys())
+ for t in all_tests:
+ if t in old_build_results:
+ old_res = old_build_results[t]
+ else:
+ old_res = '(New test)'
+ if t in build_results:
+ new_res = build_results[t]
+ else:
+ new_res = '(Test removed)'
+ if old_res != new_res:
+ result_changes[t] = '%s -> %s' % (old_res, new_res)
+ self.build_state[action]['result-changes'] = result_changes
+ old_ever_passed = {t for t in self.build_state[action]['ever-passed']
+ if t in build_results}
+ new_passes = {t for t in build_results if build_results[t] == 'PASS'}
+ self.build_state[action]['ever-passed'] = sorted(old_ever_passed |
+ new_passes)
+ self.store_build_state_json()
+
+ def load_bot_config_json(self):
+ """Load bot configuration."""
+ with open(self.bot_config_json, 'r') as f:
+ self.bot_config = json.load(f)
+
+ def part_build_old(self, action, delay):
+ """Return whether the last build for a given action was at least a
+ given number of seconds ago, or does not have a time recorded."""
+ old_time_str = self.build_state[action]['build-time']
+ if not old_time_str:
+ return True
+ old_time = datetime.datetime.strptime(old_time_str,
+ '%Y-%m-%d %H:%M:%S')
+ new_time = datetime.datetime.utcnow()
+ delta = new_time - old_time
+ return delta.total_seconds() >= delay
+
+ def bot_cycle(self):
+ """Run a single round of checkout and builds."""
+ print('Bot cycle starting %s.' % str(datetime.datetime.utcnow()))
+ self.load_bot_config_json()
+ actions = ('host-libraries', 'compilers', 'glibcs')
+ self.bot_run_self(['--replace-sources'], 'checkout')
+ self.load_versions_json()
+ if self.get_script_text() != self.script_text:
+ print('Script changed, re-execing.')
+ # On script change, all parts of the build should be rerun.
+ for a in actions:
+ self.clear_last_build_state(a)
+ self.exec_self()
+ check_components = {'host-libraries': ('gmp', 'mpfr', 'mpc'),
+ 'compilers': ('binutils', 'gcc', 'glibc', 'linux',
+ 'mig', 'gnumach', 'hurd'),
+ 'glibcs': ('glibc',)}
+ must_build = {}
+ for a in actions:
+ build_vers = self.build_state[a]['build-versions']
+ must_build[a] = False
+ if not self.build_state[a]['build-time']:
+ must_build[a] = True
+ old_vers = {}
+ new_vers = {}
+ for c in check_components[a]:
+ if c in build_vers:
+ old_vers[c] = build_vers[c]
+ new_vers[c] = {'version': self.versions[c]['version'],
+ 'revision': self.versions[c]['revision']}
+ if new_vers == old_vers:
+ print('Versions for %s unchanged.' % a)
+ else:
+ print('Versions changed or rebuild forced for %s.' % a)
+ if a == 'compilers' and not self.part_build_old(
+ a, self.bot_config['compilers-rebuild-delay']):
+ print('Not requiring rebuild of compilers this soon.')
+ else:
+ must_build[a] = True
+ if must_build['host-libraries']:
+ must_build['compilers'] = True
+ if must_build['compilers']:
+ must_build['glibcs'] = True
+ for a in actions:
+ if must_build[a]:
+ print('Must rebuild %s.' % a)
+ self.clear_last_build_state(a)
+ else:
+ print('No need to rebuild %s.' % a)
+ if os.access(self.logsdir, os.F_OK):
+ shutil.rmtree(self.logsdir_old, ignore_errors=True)
+ shutil.copytree(self.logsdir, self.logsdir_old)
+ for a in actions:
+ if must_build[a]:
+ build_time = datetime.datetime.utcnow()
+ print('Rebuilding %s at %s.' % (a, str(build_time)))
+ self.bot_run_self([], a)
+ self.load_build_state_json()
+ self.bot_build_mail(a, build_time)
+ print('Bot cycle done at %s.' % str(datetime.datetime.utcnow()))
+
+ def bot_build_mail(self, action, build_time):
+ """Send email with the results of a build."""
+ if not ('email-from' in self.bot_config and
+ 'email-server' in self.bot_config and
+ 'email-subject' in self.bot_config and
+ 'email-to' in self.bot_config):
+ if not self.email_warning:
+ print("Email not configured, not sending.")
+ self.email_warning = True
+ return
+
+ build_time = build_time.replace(microsecond=0)
+ subject = (self.bot_config['email-subject'] %
+ {'action': action,
+ 'build-time': str(build_time)})
+ results = self.build_state[action]['build-results']
+ changes = self.build_state[action]['result-changes']
+ ever_passed = set(self.build_state[action]['ever-passed'])
+ versions = self.build_state[action]['build-versions']
+ new_regressions = {k for k in changes if changes[k] == 'PASS -> FAIL'}
+ all_regressions = {k for k in ever_passed if results[k] == 'FAIL'}
+ all_fails = {k for k in results if results[k] == 'FAIL'}
+ if new_regressions:
+ new_reg_list = sorted(['FAIL: %s' % k for k in new_regressions])
+ new_reg_text = ('New regressions:\n\n%s\n\n' %
+ '\n'.join(new_reg_list))
+ else:
+ new_reg_text = ''
+ if all_regressions:
+ all_reg_list = sorted(['FAIL: %s' % k for k in all_regressions])
+ all_reg_text = ('All regressions:\n\n%s\n\n' %
+ '\n'.join(all_reg_list))
+ else:
+ all_reg_text = ''
+ if all_fails:
+ all_fail_list = sorted(['FAIL: %s' % k for k in all_fails])
+ all_fail_text = ('All failures:\n\n%s\n\n' %
+ '\n'.join(all_fail_list))
+ else:
+ all_fail_text = ''
+ if changes:
+ changes_list = sorted(changes.keys())
+ changes_list = ['%s: %s' % (changes[k], k) for k in changes_list]
+ changes_text = ('All changed results:\n\n%s\n\n' %
+ '\n'.join(changes_list))
+ else:
+ changes_text = ''
+ results_text = (new_reg_text + all_reg_text + all_fail_text +
+ changes_text)
+ if not results_text:
+ results_text = 'Clean build with unchanged results.\n\n'
+ versions_list = sorted(versions.keys())
+ versions_list = ['%s: %s (%s)' % (k, versions[k]['version'],
+ versions[k]['revision'])
+ for k in versions_list]
+ versions_text = ('Component versions for this build:\n\n%s\n' %
+ '\n'.join(versions_list))
+ body_text = results_text + versions_text
+ msg = email.mime.text.MIMEText(body_text)
+ msg['Subject'] = subject
+ msg['From'] = self.bot_config['email-from']
+ msg['To'] = self.bot_config['email-to']
+ msg['Message-ID'] = email.utils.make_msgid()
+ msg['Date'] = email.utils.format_datetime(datetime.datetime.utcnow())
+ with smtplib.SMTP(self.bot_config['email-server']) as s:
+ s.send_message(msg)
+
+ def bot_run_self(self, opts, action, check=True):
+ """Run a copy of this script with given options."""
+ cmd = [sys.executable, sys.argv[0], '--keep=none',
+ '-j%d' % self.parallelism]
+ cmd.extend(opts)
+ cmd.extend([self.topdir, action])
+ sys.stdout.flush()
+ subprocess.run(cmd, check=check)
+
+ def bot(self):
+ """Run repeated rounds of checkout and builds."""
+ while True:
+ self.load_bot_config_json()
+ if not self.bot_config['run']:
+ print('Bot exiting by request.')
+ exit(0)
+ self.bot_run_self([], 'bot-cycle', check=False)
+ self.load_bot_config_json()
+ if not self.bot_config['run']:
+ print('Bot exiting by request.')
+ exit(0)
+ time.sleep(self.bot_config['delay'])
+ if self.get_script_text() != self.script_text:
+ print('Script changed, bot re-execing.')
+ self.exec_self()
+
+
+class Config(object):
+ """A configuration for building a compiler and associated libraries."""
+
+ def __init__(self, ctx, arch, os_name, variant=None, gcc_cfg=None,
+ first_gcc_cfg=None, glibcs=None, extra_glibcs=None):
+ """Initialize a Config object."""
+ self.ctx = ctx
+ self.arch = arch
+ self.os = os_name
+ self.variant = variant
+ if variant is None:
+ self.name = '%s-%s' % (arch, os_name)
+ else:
+ self.name = '%s-%s-%s' % (arch, os_name, variant)
+ self.triplet = '%s-glibc-%s' % (arch, os_name)
+ if gcc_cfg is None:
+ self.gcc_cfg = []
+ else:
+ self.gcc_cfg = gcc_cfg
+ if first_gcc_cfg is None:
+ self.first_gcc_cfg = []
+ else:
+ self.first_gcc_cfg = first_gcc_cfg
+ if glibcs is None:
+ glibcs = [{'variant': variant}]
+ if extra_glibcs is None:
+ extra_glibcs = []
+ glibcs = [Glibc(self, **g) for g in glibcs]
+ extra_glibcs = [Glibc(self, **g) for g in extra_glibcs]
+ self.all_glibcs = glibcs + extra_glibcs
+ self.compiler_glibcs = glibcs
+ self.installdir = ctx.compiler_installdir(self.name)
+ self.bindir = ctx.compiler_bindir(self.name)
+ self.sysroot = ctx.compiler_sysroot(self.name)
+ self.builddir = os.path.join(ctx.builddir, 'compilers', self.name)
+ self.logsdir = os.path.join(ctx.logsdir, 'compilers', self.name)
+
+ def component_builddir(self, component):
+ """Return the directory to use for a (non-glibc) build."""
+ return self.ctx.component_builddir('compilers', self.name, component)
+
+ def build(self):
+ """Generate commands to build this compiler."""
+ self.ctx.remove_recreate_dirs(self.installdir, self.builddir,
+ self.logsdir)
+ cmdlist = CommandList('compilers-%s' % self.name, self.ctx.keep)
+ cmdlist.add_command('check-host-libraries',
+ ['test', '-f',
+ os.path.join(self.ctx.host_libraries_installdir,
+ 'ok')])
+ cmdlist.use_path(self.bindir)
+ self.build_cross_tool(cmdlist, 'binutils', 'binutils',
+ ['--disable-gdb',
+ '--disable-libdecnumber',
+ '--disable-readline',
+ '--disable-sim'])
+ if self.os.startswith('linux'):
+ self.install_linux_headers(cmdlist)
+ self.build_gcc(cmdlist, True)
+ if self.os == 'gnu':
+ self.install_gnumach_headers(cmdlist)
+ self.build_cross_tool(cmdlist, 'mig', 'mig')
+ self.install_hurd_headers(cmdlist)
+ for g in self.compiler_glibcs:
+ cmdlist.push_subdesc('glibc')
+ cmdlist.push_subdesc(g.name)
+ g.build_glibc(cmdlist, True)
+ cmdlist.pop_subdesc()
+ cmdlist.pop_subdesc()
+ self.build_gcc(cmdlist, False)
+ cmdlist.add_command('done', ['touch',
+ os.path.join(self.installdir, 'ok')])
+ self.ctx.add_makefile_cmdlist('compilers-%s' % self.name, cmdlist,
+ self.logsdir)
+
+ def build_cross_tool(self, cmdlist, tool_src, tool_build, extra_opts=None):
+ """Build one cross tool."""
+ srcdir = self.ctx.component_srcdir(tool_src)
+ builddir = self.component_builddir(tool_build)
+ cmdlist.push_subdesc(tool_build)
+ cmdlist.create_use_dir(builddir)
+ cfg_cmd = [os.path.join(srcdir, 'configure'),
+ '--prefix=%s' % self.installdir,
+ '--build=%s' % self.ctx.build_triplet,
+ '--host=%s' % self.ctx.build_triplet,
+ '--target=%s' % self.triplet,
+ '--with-sysroot=%s' % self.sysroot]
+ if extra_opts:
+ cfg_cmd.extend(extra_opts)
+ cmdlist.add_command('configure', cfg_cmd)
+ cmdlist.add_command('build', ['make'])
+ # Parallel "make install" for GCC has race conditions that can
+ # cause it to fail; see
+ # <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42980>. Such
+ # problems are not known for binutils, but doing the
+ # installation in parallel within a particular toolchain build
+ # (as opposed to installation of one toolchain from
+ # build-many-glibcs.py running in parallel to the installation
+ # of other toolchains being built) is not known to be
+ # significantly beneficial, so it is simplest just to disable
+ # parallel install for cross tools here.
+ cmdlist.add_command('install', ['make', '-j1', 'install'])
+ cmdlist.cleanup_dir()
+ cmdlist.pop_subdesc()
+
+ def install_linux_headers(self, cmdlist):
+ """Install Linux kernel headers."""
+ arch_map = {'aarch64': 'arm64',
+ 'alpha': 'alpha',
+ 'arm': 'arm',
+ 'hppa': 'parisc',
+ 'i486': 'x86',
+ 'i586': 'x86',
+ 'i686': 'x86',
+ 'i786': 'x86',
+ 'ia64': 'ia64',
+ 'm68k': 'm68k',
+ 'microblaze': 'microblaze',
+ 'mips': 'mips',
+ 'nios2': 'nios2',
+ 'powerpc': 'powerpc',
+ 's390': 's390',
+ 'riscv32': 'riscv',
+ 'riscv64': 'riscv',
+ 'sh': 'sh',
+ 'sparc': 'sparc',
+ 'x86_64': 'x86'}
+ linux_arch = None
+ for k in arch_map:
+ if self.arch.startswith(k):
+ linux_arch = arch_map[k]
+ break
+ assert linux_arch is not None
+ srcdir = self.ctx.component_srcdir('linux')
+ builddir = self.component_builddir('linux')
+ headers_dir = os.path.join(self.sysroot, 'usr')
+ cmdlist.push_subdesc('linux')
+ cmdlist.create_use_dir(builddir)
+ cmdlist.add_command('install-headers',
+ ['make', '-C', srcdir, 'O=%s' % builddir,
+ 'ARCH=%s' % linux_arch,
+ 'INSTALL_HDR_PATH=%s' % headers_dir,
+ 'headers_install'])
+ cmdlist.cleanup_dir()
+ cmdlist.pop_subdesc()
+
+ def install_gnumach_headers(self, cmdlist):
+ """Install GNU Mach headers."""
+ srcdir = self.ctx.component_srcdir('gnumach')
+ builddir = self.component_builddir('gnumach')
+ cmdlist.push_subdesc('gnumach')
+ cmdlist.create_use_dir(builddir)
+ cmdlist.add_command('configure',
+ [os.path.join(srcdir, 'configure'),
+ '--build=%s' % self.ctx.build_triplet,
+ '--host=%s' % self.triplet,
+ '--prefix=',
+ 'CC=%s-gcc -nostdlib' % self.triplet])
+ cmdlist.add_command('install', ['make', 'DESTDIR=%s' % self.sysroot,
+ 'install-data'])
+ cmdlist.cleanup_dir()
+ cmdlist.pop_subdesc()
+
+ def install_hurd_headers(self, cmdlist):
+ """Install Hurd headers."""
+ srcdir = self.ctx.component_srcdir('hurd')
+ builddir = self.component_builddir('hurd')
+ cmdlist.push_subdesc('hurd')
+ cmdlist.create_use_dir(builddir)
+ cmdlist.add_command('configure',
+ [os.path.join(srcdir, 'configure'),
+ '--build=%s' % self.ctx.build_triplet,
+ '--host=%s' % self.triplet,
+ '--prefix=',
+ '--disable-profile', '--without-parted',
+ 'CC=%s-gcc -nostdlib' % self.triplet])
+ cmdlist.add_command('install', ['make', 'prefix=%s' % self.sysroot,
+ 'no_deps=t', 'install-headers'])
+ cmdlist.cleanup_dir()
+ cmdlist.pop_subdesc()
+
+ def build_gcc(self, cmdlist, bootstrap):
+ """Build GCC."""
+ # libsanitizer commonly breaks because of glibc header
+ # changes, or on unusual targets. libssp is of little
+ # relevance with glibc's own stack checking support.
+ # libcilkrts does not support GNU/Hurd (and has been removed
+ # in GCC 8, so --disable-libcilkrts can be removed once glibc
+ # no longer supports building with older GCC versions).
+ cfg_opts = list(self.gcc_cfg)
+ cfg_opts += ['--disable-libsanitizer', '--disable-libssp',
+ '--disable-libcilkrts']
+ host_libs = self.ctx.host_libraries_installdir
+ cfg_opts += ['--with-gmp=%s' % host_libs,
+ '--with-mpfr=%s' % host_libs,
+ '--with-mpc=%s' % host_libs]
+ if bootstrap:
+ tool_build = 'gcc-first'
+ # Building a static-only, C-only compiler that is
+ # sufficient to build glibc. Various libraries and
+ # features that may require libc headers must be disabled.
+ # When configuring with a sysroot, --with-newlib is
+ # required to define inhibit_libc (to stop some parts of
+ # libgcc including libc headers); --without-headers is not
+ # sufficient.
+ cfg_opts += ['--enable-languages=c', '--disable-shared',
+ '--disable-threads',
+ '--disable-libatomic',
+ '--disable-decimal-float',
+ '--disable-libffi',
+ '--disable-libgomp',
+ '--disable-libitm',
+ '--disable-libmpx',
+ '--disable-libquadmath',
+ '--without-headers', '--with-newlib',
+ '--with-glibc-version=%s' % self.ctx.glibc_version
+ ]
+ cfg_opts += self.first_gcc_cfg
+ else:
+ tool_build = 'gcc'
+ cfg_opts += ['--enable-languages=c,c++', '--enable-shared',
+ '--enable-threads']
+ self.build_cross_tool(cmdlist, 'gcc', tool_build, cfg_opts)
+
+
+class Glibc(object):
+ """A configuration for building glibc."""
+
+ def __init__(self, compiler, arch=None, os_name=None, variant=None,
+ cfg=None, ccopts=None):
+ """Initialize a Glibc object."""
+ self.ctx = compiler.ctx
+ self.compiler = compiler
+ if arch is None:
+ self.arch = compiler.arch
+ else:
+ self.arch = arch
+ if os_name is None:
+ self.os = compiler.os
+ else:
+ self.os = os_name
+ self.variant = variant
+ if variant is None:
+ self.name = '%s-%s' % (self.arch, self.os)
+ else:
+ self.name = '%s-%s-%s' % (self.arch, self.os, variant)
+ self.triplet = '%s-glibc-%s' % (self.arch, self.os)
+ if cfg is None:
+ self.cfg = []
+ else:
+ self.cfg = cfg
+ self.ccopts = ccopts
+
+ def tool_name(self, tool):
+ """Return the name of a cross-compilation tool."""
+ ctool = '%s-%s' % (self.compiler.triplet, tool)
+ if self.ccopts and (tool == 'gcc' or tool == 'g++'):
+ ctool = '%s %s' % (ctool, self.ccopts)
+ return ctool
+
+ def build(self):
+ """Generate commands to build this glibc."""
+ builddir = self.ctx.component_builddir('glibcs', self.name, 'glibc')
+ installdir = self.ctx.glibc_installdir(self.name)
+ logsdir = os.path.join(self.ctx.logsdir, 'glibcs', self.name)
+ self.ctx.remove_recreate_dirs(installdir, builddir, logsdir)
+ cmdlist = CommandList('glibcs-%s' % self.name, self.ctx.keep)
+ cmdlist.add_command('check-compilers',
+ ['test', '-f',
+ os.path.join(self.compiler.installdir, 'ok')])
+ cmdlist.use_path(self.compiler.bindir)
+ self.build_glibc(cmdlist, False)
+ self.ctx.add_makefile_cmdlist('glibcs-%s' % self.name, cmdlist,
+ logsdir)
+
+ def build_glibc(self, cmdlist, for_compiler):
+ """Generate commands to build this glibc, either as part of a compiler
+ build or with the bootstrapped compiler (and in the latter case, run
+ tests as well)."""
+ srcdir = self.ctx.component_srcdir('glibc')
+ if for_compiler:
+ builddir = self.ctx.component_builddir('compilers',
+ self.compiler.name, 'glibc',
+ self.name)
+ installdir = self.compiler.sysroot
+ srcdir_copy = self.ctx.component_builddir('compilers',
+ self.compiler.name,
+ 'glibc-src',
+ self.name)
+ else:
+ builddir = self.ctx.component_builddir('glibcs', self.name,
+ 'glibc')
+ installdir = self.ctx.glibc_installdir(self.name)
+ srcdir_copy = self.ctx.component_builddir('glibcs', self.name,
+ 'glibc-src')
+ cmdlist.create_use_dir(builddir)
+ # glibc builds write into the source directory, and even if
+ # not intentionally there is a risk of bugs that involve
+ # writing into the working directory. To avoid possible
+ # concurrency issues, copy the source directory.
+ cmdlist.create_copy_dir(srcdir, srcdir_copy)
+ use_usr = self.os != 'gnu'
+ prefix = '/usr' if use_usr else ''
+ cfg_cmd = [os.path.join(srcdir_copy, 'configure'),
+ '--prefix=%s' % prefix,
+ '--enable-profile',
+ '--build=%s' % self.ctx.build_triplet,
+ '--host=%s' % self.triplet,
+ 'CC=%s' % self.tool_name('gcc'),
+ 'CXX=%s' % self.tool_name('g++'),
+ 'AR=%s' % self.tool_name('ar'),
+ 'AS=%s' % self.tool_name('as'),
+ 'LD=%s' % self.tool_name('ld'),
+ 'NM=%s' % self.tool_name('nm'),
+ 'OBJCOPY=%s' % self.tool_name('objcopy'),
+ 'OBJDUMP=%s' % self.tool_name('objdump'),
+ 'RANLIB=%s' % self.tool_name('ranlib'),
+ 'READELF=%s' % self.tool_name('readelf'),
+ 'STRIP=%s' % self.tool_name('strip')]
+ if self.os == 'gnu':
+ cfg_cmd += ['MIG=%s' % self.tool_name('mig')]
+ cfg_cmd += self.cfg
+ cmdlist.add_command('configure', cfg_cmd)
+ cmdlist.add_command('build', ['make'])
+ cmdlist.add_command('install', ['make', 'install',
+ 'install_root=%s' % installdir])
+ # GCC uses paths such as lib/../lib64, so make sure lib
+ # directories always exist.
+ mkdir_cmd = ['mkdir', '-p',
+ os.path.join(installdir, 'lib')]
+ if use_usr:
+ mkdir_cmd += [os.path.join(installdir, 'usr', 'lib')]
+ cmdlist.add_command('mkdir-lib', mkdir_cmd)
+ if not for_compiler:
+ if self.ctx.strip:
+ cmdlist.add_command('strip',
+ ['sh', '-c',
+ ('%s $(find %s/lib* -name "*.so")' %
+ (self.tool_name('strip'), installdir))])
+ cmdlist.add_command('check', ['make', 'check'])
+ cmdlist.add_command('save-logs', [self.ctx.save_logs],
+ always_run=True)
+ cmdlist.cleanup_dir('cleanup-src', srcdir_copy)
+ cmdlist.cleanup_dir()
+
+
+class Command(object):
+ """A command run in the build process."""
+
+ def __init__(self, desc, num, dir, path, command, always_run=False):
+ """Initialize a Command object."""
+ self.dir = dir
+ self.path = path
+ self.desc = desc
+ trans = str.maketrans({' ': '-'})
+ self.logbase = '%03d-%s' % (num, desc.translate(trans))
+ self.command = command
+ self.always_run = always_run
+
+ @staticmethod
+ def shell_make_quote_string(s):
+ """Given a string not containing a newline, quote it for use by the
+ shell and make."""
+ assert '\n' not in s
+ if re.fullmatch('[]+,./0-9@A-Z_a-z-]+', s):
+ return s
+ strans = str.maketrans({"'": "'\\''"})
+ s = "'%s'" % s.translate(strans)
+ mtrans = str.maketrans({'$': '$$'})
+ return s.translate(mtrans)
+
+ @staticmethod
+ def shell_make_quote_list(l, translate_make):
+ """Given a list of strings not containing newlines, quote them for use
+ by the shell and make, returning a single string. If translate_make
+ is true and the first string is 'make', change it to $(MAKE)."""
+ l = [Command.shell_make_quote_string(s) for s in l]
+ if translate_make and l[0] == 'make':
+ l[0] = '$(MAKE)'
+ return ' '.join(l)
+
+ def shell_make_quote(self):
+ """Return this command quoted for the shell and make."""
+ return self.shell_make_quote_list(self.command, True)
+
+
+class CommandList(object):
+ """A list of commands run in the build process."""
+
+ def __init__(self, desc, keep):
+ """Initialize a CommandList object."""
+ self.cmdlist = []
+ self.dir = None
+ self.path = None
+ self.desc = [desc]
+ self.keep = keep
+
+ def desc_txt(self, desc):
+ """Return the description to use for a command."""
+ return '%s %s' % (' '.join(self.desc), desc)
+
+ def use_dir(self, dir):
+ """Set the default directory for subsequent commands."""
+ self.dir = dir
+
+ def use_path(self, path):
+ """Set a directory to be prepended to the PATH for subsequent
+ commands."""
+ self.path = path
+
+ def push_subdesc(self, subdesc):
+ """Set the default subdescription for subsequent commands (e.g., the
+ name of a component being built, within the series of commands
+ building it)."""
+ self.desc.append(subdesc)
+
+ def pop_subdesc(self):
+ """Pop a subdescription from the list of descriptions."""
+ self.desc.pop()
+
+ def create_use_dir(self, dir):
+ """Remove and recreate a directory and use it for subsequent
+ commands."""
+ self.add_command_dir('rm', None, ['rm', '-rf', dir])
+ self.add_command_dir('mkdir', None, ['mkdir', '-p', dir])
+ self.use_dir(dir)
+
+ def create_copy_dir(self, src, dest):
+ """Remove a directory and recreate it as a copy from the given
+ source."""
+ self.add_command_dir('copy-rm', None, ['rm', '-rf', dest])
+ parent = os.path.dirname(dest)
+ self.add_command_dir('copy-mkdir', None, ['mkdir', '-p', parent])
+ self.add_command_dir('copy', None, ['cp', '-a', src, dest])
+
+ def add_command_dir(self, desc, dir, command, always_run=False):
+ """Add a command to run in a given directory."""
+ cmd = Command(self.desc_txt(desc), len(self.cmdlist), dir, self.path,
+ command, always_run)
+ self.cmdlist.append(cmd)
+
+ def add_command(self, desc, command, always_run=False):
+ """Add a command to run in the default directory."""
+ cmd = Command(self.desc_txt(desc), len(self.cmdlist), self.dir,
+ self.path, command, always_run)
+ self.cmdlist.append(cmd)
+
+ def cleanup_dir(self, desc='cleanup', dir=None):
+ """Clean up a build directory. If no directory is specified, the
+ default directory is cleaned up and ceases to be the default
+ directory."""
+ if dir is None:
+ dir = self.dir
+ self.use_dir(None)
+ if self.keep != 'all':
+ self.add_command_dir(desc, None, ['rm', '-rf', dir],
+ always_run=(self.keep == 'none'))
+
+ def makefile_commands(self, wrapper, logsdir):
+ """Return the sequence of commands in the form of text for a Makefile.
+ The given wrapper script takes arguments: base of logs for
+ previous command, or empty; base of logs for this command;
+ description; directory; PATH addition; the command itself."""
+ # prev_base is the base of the name for logs of the previous
+ # command that is not always-run (that is, a build command,
+ # whose failure should stop subsequent build commands from
+ # being run, as opposed to a cleanup command, which is run
+ # even if previous commands failed).
+ prev_base = ''
+ cmds = []
+ for c in self.cmdlist:
+ ctxt = c.shell_make_quote()
+ if prev_base and not c.always_run:
+ prev_log = os.path.join(logsdir, prev_base)
+ else:
+ prev_log = ''
+ this_log = os.path.join(logsdir, c.logbase)
+ if not c.always_run:
+ prev_base = c.logbase
+ if c.dir is None:
+ dir = ''
+ else:
+ dir = c.dir
+ if c.path is None:
+ path = ''
+ else:
+ path = c.path
+ prelims = [wrapper, prev_log, this_log, c.desc, dir, path]
+ prelim_txt = Command.shell_make_quote_list(prelims, False)
+ cmds.append('\t@%s %s' % (prelim_txt, ctxt))
+ return '\n'.join(cmds)
+
+ def status_logs(self, logsdir):
+ """Return the list of log files with command status."""
+ return [os.path.join(logsdir, '%s-status.txt' % c.logbase)
+ for c in self.cmdlist]
+
+
+def get_parser():
+ """Return an argument parser for this module."""
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('-j', dest='parallelism',
+ help='Run this number of jobs in parallel',
+ type=int, default=os.cpu_count())
+ parser.add_argument('--keep', dest='keep',
+ help='Whether to keep all build directories, '
+ 'none or only those from failed builds',
+ default='none', choices=('none', 'all', 'failed'))
+ parser.add_argument('--replace-sources', action='store_true',
+ help='Remove and replace source directories '
+ 'with the wrong version of a component')
+ parser.add_argument('--strip', action='store_true',
+ help='Strip installed glibc libraries')
+ parser.add_argument('topdir',
+ help='Toplevel working directory')
+ parser.add_argument('action',
+ help='What to do',
+ choices=('checkout', 'bot-cycle', 'bot',
+ 'host-libraries', 'compilers', 'glibcs'))
+ parser.add_argument('configs',
+ help='Versions to check out or configurations to build',
+ nargs='*')
+ return parser
+
+
+def main(argv):
+ """The main entry point."""
+ parser = get_parser()
+ opts = parser.parse_args(argv)
+ topdir = os.path.abspath(opts.topdir)
+ ctx = Context(topdir, opts.parallelism, opts.keep, opts.replace_sources,
+ opts.strip, opts.action)
+ ctx.run_builds(opts.action, opts.configs)
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/scripts/check-c++-types.sh b/scripts/check-c++-types.sh
index 489c4f066f..d02e77d23b 100755
--- a/scripts/check-c++-types.sh
+++ b/scripts/check-c++-types.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright (C) 2003-2016 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -15,6 +15,14 @@
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <http://www.gnu.org/licenses/>.
+
+# This script creates a list of data types where each type is followed
+# by the C++ mangled name for that type. That list is then compared
+# against the list in the c++-types.data file for the platform being
+# checked. Any difference between the two would mean that the C++ ABI
+# had changed and that should not happen even if the change is compatible
+# at the C language level.
+
#
# The list of data types has been created with
# cat <<EOF |
diff --git a/scripts/check-execstack.awk b/scripts/check-execstack.awk
index 21d37e9f47..cd6b30ed3c 100644
--- a/scripts/check-execstack.awk
+++ b/scripts/check-execstack.awk
@@ -6,7 +6,12 @@
# It fails (1) if any did indicate executable stack.
# It fails (2) if the input did not take the expected form.
-BEGIN { result = sanity = 0; default_exec = -1 }
+BEGIN {
+ result = sanity = 0; default_exec = -1;
+ split(xfail, xfails, " ");
+ for (x in xfails)
+ expected_fails[xfails[x] ".phdr"] = 1;
+}
/^execstack-no$/ { default_exec = 0; next }
/^execstack-yes$/ { default_exec = 1; next }
@@ -17,6 +22,10 @@ function check_one(name) {
result = 2;
}
+ n = split(name, parts, "/");
+ basename = parts[n];
+ expected_fail = basename in expected_fails;
+
if (!sanity) {
print name ": *** input did not look like readelf -l output";
result = 2;
@@ -24,12 +33,20 @@ function check_one(name) {
if (stack_line ~ /^.*RW .*$/) {
print name ": OK";
} else if (stack_line ~ /^.*E.*$/) {
- print name ": *** executable stack signaled";
- result = result ? result : 1;
+ if (expected_fail) {
+ print name ": *** executable stack signaled, expected";
+ } else {
+ print name ": *** executable stack signaled";
+ result = result ? result : 1;
+ }
}
} else if (default_exec) {
- print name ": *** no PT_GNU_STACK entry";
- result = result ? result : 1;
+ if (expected_fail) {
+ print name ": *** no PT_GNU_STACK entry, expected";
+ } else {
+ print name ": *** no PT_GNU_STACK entry";
+ result = result ? result : 1;
+ }
} else {
print name ": no PT_GNU_STACK but default is OK";
}
diff --git a/scripts/check-initfini.awk b/scripts/check-initfini.awk
new file mode 100644
index 0000000000..19514a98ad
--- /dev/null
+++ b/scripts/check-initfini.awk
@@ -0,0 +1,63 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# This awk script expects to get command-line files that are each
+# the output of 'readelf -W --dyn-syms' on a single shared object.
+# It exits successfully (0) if none contained _init nor _fini in dynamic
+# symbol table.
+# It fails (1) if any did contain _init or _fini in dynamic symbol table.
+# It fails (2) if the input did not take the expected form.
+
+BEGIN { result = _init = _fini = sanity = 0 }
+
+function check_one(name) {
+ if (!sanity) {
+ print name ": *** input did not look like readelf -d output";
+ result = 2;
+ } else {
+ ok = 1;
+ if (_init) {
+ print name ": *** _init is in dynamic symbol table";
+ result = result ? result : 1;
+ ok = 0;
+ }
+ if (_fini) {
+ print name ": *** _fini is in dynamic symbol table";
+ result = result ? result : 1;
+ ok = 0;
+ }
+ if (ok)
+ print name ": OK";
+ }
+
+ _init = _fini = sanity = 0
+}
+
+FILENAME != lastfile {
+ if (lastfile)
+ check_one(lastfile);
+ lastfile = FILENAME;
+}
+
+$1 == "Symbol" && $2 == "table" && $3 == "'.dynsym'" { sanity = 1 }
+$8 == "_init" { _init = 1 }
+$8 == "_fini" { _fini = 1 }
+
+END {
+ check_one(lastfile);
+ exit(result);
+}
diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh
new file mode 100644
index 0000000000..4a062e9cda
--- /dev/null
+++ b/scripts/check-installed-headers.sh
@@ -0,0 +1,174 @@
+#! /bin/sh
+# Copyright (C) 2016-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# Check installed headers for cleanliness. For each header, confirm
+# that it's possible to compile a file that includes that header and
+# does nothing else, in several different compilation modes. Also,
+# scan the header for a set of obsolete typedefs that should no longer
+# appear.
+
+# These compilation switches assume GCC or compatible, which is probably
+# fine since we also assume that when _building_ glibc.
+c_modes="-std=c89 -std=gnu89 -std=c11 -std=gnu11"
+cxx_modes="-std=c++98 -std=gnu++98 -std=c++11 -std=gnu++11"
+
+# An exhaustive test of feature selection macros would take far too long.
+# These are probably the most commonly used three.
+lib_modes="-D_DEFAULT_SOURCE=1 -D_GNU_SOURCE=1 -D_XOPEN_SOURCE=700"
+
+# sys/types.h+bits/types.h have to define the obsolete types.
+# rpc(svc)/* have the obsolete types too deeply embedded in their API
+# to remove.
+skip_obsolete_type_check='*/sys/types.h|*/bits/types.h|*/rpc/*|*/rpcsvc/*'
+obsolete_type_re=\
+'\<((__)?(quad_t|u(short|int|long|_(char|short|int([0-9]+_t)?|long|quad_t))))\>'
+
+if [ $# -lt 3 ]; then
+ echo "usage: $0 c|c++ \"compile command\" header header header..." >&2
+ exit 2
+fi
+case "$1" in
+ (c)
+ lang_modes="$c_modes"
+ cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.c)
+ already="$skip_obsolete_type_check"
+ ;;
+ (c++)
+ lang_modes="$cxx_modes"
+ cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.cc)
+ # The obsolete-type check can be skipped for C++; it is
+ # sufficient to do it for C.
+ already="*"
+ ;;
+ (*)
+ echo "usage: $0 c|c++ \"compile command\" header header header..." >&2
+ exit 2;;
+esac
+shift
+cc_cmd="$1"
+shift
+trap "rm -f '$cih_test_c'" 0
+
+failed=0
+is_x86_64=unknown
+is_x32=unknown
+for header in "$@"; do
+ # Skip various headers for which this test gets a false failure.
+ case "$header" in
+ # bits/* are not meant to be included directly and usually #error
+ # out if you try it.
+ # regexp.h is a stub containing only an #error.
+ # Sun RPC's .x files are traditionally installed in
+ # $prefix/include/rpcsvc, but they are not C header files.
+ (bits/* | regexp.h | rpcsvc/*.x)
+ continue;;
+
+ # All extant versions of sys/elf.h contain nothing more than an
+ # exhortation (either a #warning or an #error) to use sys/procfs.h
+ # instead, plus an inclusion of that header.
+ (sys/elf.h)
+ continue;;
+
+ # sys/sysctl.h is unsupported for x32.
+ (sys/sysctl.h)
+ case "$is_x32" in
+ (yes) continue;;
+ (no) ;;
+ (unknown)
+ cat >"$cih_test_c" <<EOF
+#if defined __x86_64__ && defined __ILP32__
+# error "is x32"
+#endif
+EOF
+ if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
+ then
+ is_x32=no
+ else
+ is_x32=yes
+ continue
+ fi
+ ;;
+ esac
+ ;;
+
+ # sys/vm86.h is "unsupported on x86-64" and errors out on that target.
+ (sys/vm86.h)
+ case "$is_x86_64" in
+ (yes) continue;;
+ (no) ;;
+ (unknown)
+ cat >"$cih_test_c" <<EOF
+#if defined __x86_64__ && __x86_64__
+#error "is x86-64"
+#endif
+EOF
+ if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
+ then
+ is_x86_64=no
+ else
+ is_x86_64=yes
+ continue
+ fi
+ ;;
+ esac
+ ;;
+ esac
+
+ echo :: "$header"
+ for lang_mode in "" $lang_modes; do
+ for lib_mode in "" $lib_modes; do
+ echo :::: $lang_mode $lib_mode
+ if [ -z "$lib_mode" ]; then
+ expanded_lib_mode='/* default library mode */'
+ else
+ expanded_lib_mode=$(echo : $lib_mode | \
+ sed 's/^: -D/#define /; s/=/ /')
+ fi
+ cat >"$cih_test_c" <<EOF
+/* These macros may have been defined on the command line. They are
+ inappropriate for this test. */
+#undef _LIBC
+#undef _GNU_SOURCE
+/* The library mode is selected here rather than on the command line to
+ ensure that this selection wins. */
+$expanded_lib_mode
+#include <$header>
+int avoid_empty_translation_unit;
+EOF
+ if $cc_cmd -fsyntax-only $lang_mode "$cih_test_c" 2>&1
+ then
+ includes=$($cc_cmd -fsyntax-only -H $lang_mode \
+ "$cih_test_c" 2>&1 | sed -ne 's/^[.][.]* //p')
+ for h in $includes; do
+ # Don't repeat work.
+ eval 'case "$h" in ('"$already"') continue;; esac'
+
+ if grep -qE "$obsolete_type_re" "$h"; then
+ echo "*** Obsolete types detected:"
+ grep -HE "$obsolete_type_re" "$h"
+ failed=1
+ fi
+ already="$already|$h"
+ done
+ else
+ failed=1
+ fi
+ done
+ done
+done
+exit $failed
diff --git a/scripts/check-local-headers.sh b/scripts/check-local-headers.sh
index 0670da16bc..0c45cc4079 100755
--- a/scripts/check-local-headers.sh
+++ b/scripts/check-local-headers.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright (C) 2005-2016 Free Software Foundation, Inc.
+# Copyright (C) 2005-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -33,7 +33,7 @@ exec ${AWK} -v includedir="$includedir" '
BEGIN {
status = 0
exclude = "^" includedir \
- "/(.*-.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs)|cthreads\\.h|gd|nss3/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)"
+ "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h)|cthreads\\.h|gd|nss3/|nspr4?/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)"
}
/^[^ ]/ && $1 ~ /.*:/ { obj = $1 }
{
diff --git a/scripts/config.guess b/scripts/config.guess
index dcd5149681..588fe82a42 100755
--- a/scripts/config.guess
+++ b/scripts/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2016 Free Software Foundation, Inc.
+# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2016-01-01'
+timestamp='2018-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2016-01-01'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,7 +27,7 @@ timestamp='2016-01-01'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
#
# Please send patches to <config-patches@gnu.org>.
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
+ # to ELF recently (or will in the future) and ABI.
case "${UNAME_MACHINE_ARCH}" in
- arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@@ -237,6 +240,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ exit ;;
+ *:MidnightBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-midnightbsd${UNAME_RELEASE}
+ exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
@@ -252,6 +262,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:Sortix:*:*)
echo ${UNAME_MACHINE}-unknown-sortix
exit ;;
+ *:Redox:*:*)
+ echo ${UNAME_MACHINE}-unknown-redox
+ exit ;;
+ mips:OSF1:*.*)
+ echo mips-dec-osf1
+ exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
@@ -268,55 +284,46 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
+ UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
+ UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
+ UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
+ UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
+ UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
+ UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
+ UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
+ UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
+ UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
@@ -376,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
- SUN_ARCH="i386"
+ SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
- SUN_ARCH="x86_64"
+ SUN_ARCH=x86_64
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
@@ -410,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
@@ -478,13 +485,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
@@ -607,7 +614,7 @@ EOF
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
@@ -628,20 +635,20 @@ EOF
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
@@ -680,11 +687,11 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
+ if [ ${HP_ARCH} = hppa2.0w ]
then
eval $set_cc_for_build
@@ -697,12 +704,12 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
- HP_ARCH="hppa2.0w"
+ HP_ARCH=hppa2.0w
else
- HP_ARCH="hppa64"
+ HP_ARCH=hppa64
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -742,7 +749,7 @@ EOF
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
@@ -751,7 +758,7 @@ EOF
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
@@ -807,14 +814,14 @@ EOF
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -830,10 +837,11 @@ EOF
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
esac
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -847,10 +855,6 @@ EOF
*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
@@ -866,27 +870,12 @@ EOF
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
@@ -896,7 +885,7 @@ EOF
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
@@ -919,7 +908,7 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
@@ -993,6 +982,9 @@ EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
+ mips64el:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
openrisc*:Linux:*:*)
echo or1k-unknown-linux-${LIBC}
exit ;;
@@ -1025,6 +1017,9 @@ EOF
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC}
exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
@@ -1083,7 +1078,7 @@ EOF
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ i*86:*:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
@@ -1272,6 +1267,9 @@ EOF
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1285,16 +1283,23 @@ EOF
UNAME_PROCESSOR=powerpc
fi
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
+ fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
@@ -1309,7 +1314,7 @@ EOF
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
+ if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
@@ -1318,15 +1323,18 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
+ NEO-*:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
+ NSR-*:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk${UNAME_RELEASE}
+ exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
@@ -1340,7 +1348,7 @@ EOF
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- if test "$cputype" = "386"; then
+ if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
@@ -1382,7 +1390,7 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
@@ -1398,21 +1406,32 @@ EOF
exit ;;
esac
+echo "$0: unable to guess system type" >&2
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}" in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
+esac
+
cat >&2 <<EOF
-$0: unable to guess system type
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
config.guess timestamp = $timestamp
@@ -1440,7 +1459,7 @@ EOF
exit 1
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/scripts/config.sub b/scripts/config.sub
index da6d1b6826..f2632cd8a2 100755
--- a/scripts/config.sub
+++ b/scripts/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2016 Free Software Foundation, Inc.
+# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2016-01-01'
+timestamp='2018-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2016-01-01'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -33,7 +33,7 @@ timestamp='2016-01-01'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
- kopensolaris*-gnu* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -229,9 +229,6 @@ case $os in
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
-psos*)
os=-psos
;;
@@ -263,7 +260,7 @@ case $basic_machine in
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
- | i370 | i860 | i960 | ia64 \
+ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
@@ -301,6 +298,7 @@ case $basic_machine in
| open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
| pyramid \
| riscv32 | riscv64 \
| rl78 | rx \
@@ -314,7 +312,7 @@ case $basic_machine in
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
- | we32k \
+ | wasm32 \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
@@ -387,7 +385,7 @@ case $basic_machine in
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
@@ -428,6 +426,7 @@ case $basic_machine in
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
| pyramid-* \
| riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \
@@ -444,6 +443,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
+ | wasm32-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -639,10 +639,18 @@ case $basic_machine in
basic_machine=rs6000-bull
os=-bosx
;;
- dpx2* | dpx2*-bull)
+ dpx2*)
basic_machine=m68k-bull
os=-sysv3
;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
@@ -893,7 +901,7 @@ case $basic_machine in
basic_machine=v70-nec
os=-sysv
;;
- next | m*-next )
+ next | m*-next)
basic_machine=m68k-next
case $os in
-nextstep* )
@@ -938,6 +946,9 @@ case $basic_machine in
nsr-tandem)
basic_machine=nsr-tandem
;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
@@ -1022,7 +1033,7 @@ case $basic_machine in
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
+ ppcle | powerpclittle)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
@@ -1032,7 +1043,7 @@ case $basic_machine in
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
@@ -1233,6 +1244,9 @@ case $basic_machine in
basic_machine=a29k-wrs
os=-vxworks
;;
+ wasm32)
+ basic_machine=wasm32-unknown
+ ;;
w65*)
basic_machine=w65-wdc
os=-none
@@ -1241,6 +1255,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
+ x64)
+ basic_machine=x86_64-pc
+ ;;
xbox)
basic_machine=i686-pc
os=-mingw32
@@ -1348,8 +1365,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases that might get confused
+ # with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
@@ -1369,9 +1386,9 @@ case $os in
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
- # First accept the basic system types.
+ # Now accept the basic system types.
# The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
+ # Each alternative MUST end in a * to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
@@ -1382,14 +1399,14 @@ case $os in
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
+ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
@@ -1399,7 +1416,7 @@ case $os in
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos*)
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1474,7 +1491,7 @@ case $os in
-nova*)
os=-rtmk-nova
;;
- -ns2 )
+ -ns2)
os=-nextstep2
;;
-nsk*)
@@ -1529,8 +1546,23 @@ case $os in
-dicos*)
os=-dicos
;;
+ -pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $basic_machine in
+ arm*)
+ os=-eabi
+ ;;
+ *)
+ os=-elf
+ ;;
+ esac
+ ;;
-nacl*)
;;
+ -ios)
+ ;;
-none)
;;
*)
@@ -1626,6 +1658,9 @@ case $basic_machine in
sparc-* | *-sun)
os=-sunos4.1.1
;;
+ pru-*)
+ os=-elf
+ ;;
*-be)
os=-beos
;;
@@ -1671,7 +1706,7 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
- *-next )
+ *-next)
os=-nextstep
;;
*-sequent)
@@ -1806,7 +1841,7 @@ echo $basic_machine$os
exit
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/scripts/cross-test-ssh.sh b/scripts/cross-test-ssh.sh
index 73c4e3ea0f..400ef7d595 100755
--- a/scripts/cross-test-ssh.sh
+++ b/scripts/cross-test-ssh.sh
@@ -1,6 +1,6 @@
#!/bin/bash
# Run a testcase on a remote system, via ssh.
-# Copyright (C) 2012-2016 Free Software Foundation, Inc.
+# Copyright (C) 2012-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
diff --git a/scripts/evaluate-test.sh b/scripts/evaluate-test.sh
index f2c85ed192..b6420ea9fc 100755
--- a/scripts/evaluate-test.sh
+++ b/scripts/evaluate-test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Output a test status line.
-# Copyright (C) 2012-2016 Free Software Foundation, Inc.
+# Copyright (C) 2012-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
diff --git a/scripts/gen-py-const.awk b/scripts/gen-py-const.awk
new file mode 100644
index 0000000000..91220281c5
--- /dev/null
+++ b/scripts/gen-py-const.awk
@@ -0,0 +1,118 @@
+# Script to generate constants for Python pretty printers.
+#
+# Copyright (C) 2016-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# This script is a smaller version of the clever gen-asm-const.awk hack used to
+# generate ASM constants from .sym files. We'll use this to generate constants
+# for Python pretty printers.
+#
+# The input to this script are .pysym files that look like:
+# #C_Preprocessor_Directive...
+# NAME1
+# NAME2 expression...
+#
+# A line giving just a name implies an expression consisting of just that name.
+# Comments start with '--'.
+#
+# The output of this script is a 'dummy' function containing 'asm' declarations
+# for each non-preprocessor line in the .pysym file. The expression values
+# will appear as input operands to the 'asm' declaration. For example, if we
+# have:
+#
+# /* header.h */
+# #define MACRO 42
+#
+# struct S {
+# char c1;
+# char c2;
+# char c3;
+# };
+#
+# enum E {
+# ZERO,
+# ONE
+# };
+#
+# /* symbols.pysym */
+# #include <stddef.h>
+# #include "header.h"
+# -- This is a comment
+# MACRO
+# C3_OFFSET offsetof(struct S, c3)
+# E_ONE ONE
+#
+# the output will be:
+#
+# #include <stddef.h>
+# #include "header.h"
+# void dummy(void)
+# {
+# asm ("@name@MACRO@value@%0@" : : "i" (MACRO));
+# asm ("@name@C3_OFFSET@value@%0@" : : "i" (offsetof(struct S, c3)));
+# asm ("@name@E_ONE@value@%0@" : : "i" (ONE));
+# }
+#
+# We'll later feed this output to gcc -S. Since '-S' tells gcc to compile but
+# not assemble, gcc will output something like:
+#
+# dummy:
+# ...
+# @name@MACRO@value@$42@
+# @name@C3_OFFSET@value@$2@
+# @name@E_ONE@value@$1@
+#
+# Finally, we can process that output to extract the constant values.
+# Notice gcc may prepend a special character such as '$' to each value.
+
+# found_symbol indicates whether we found a non-comment, non-preprocessor line.
+BEGIN { found_symbol = 0 }
+
+# C preprocessor directives go straight through.
+/^#/ { print; next; }
+
+# Skip comments.
+/--/ { next; }
+
+# Trim leading whitespace.
+{ sub(/^[[:blank:]]*/, ""); }
+
+# If we found a non-comment, non-preprocessor line, print the 'dummy' function
+# header.
+NF > 0 && !found_symbol {
+ print "void dummy(void)\n{";
+ found_symbol = 1;
+}
+
+# If the line contains just a name, duplicate it so we can use that name
+# as the value of the expression.
+NF == 1 { sub(/^.*$/, "& &"); }
+
+# If a line contains a name and an expression...
+NF > 1 {
+ name = $1;
+
+ # Remove any characters before the second field.
+ sub(/^[^[:blank:]]+[[:blank:]]+/, "");
+
+ # '$0' ends up being everything that appeared after the first field
+ # separator.
+ printf " asm (\"@name@%s@value@%0@\" : : \"i\" (%s));\n", name, $0;
+}
+
+# Close the 'dummy' function.
+END { if (found_symbol) print "}"; }
diff --git a/scripts/gen-rrtypes.py b/scripts/gen-rrtypes.py
new file mode 100644
index 0000000000..a71e1e108b
--- /dev/null
+++ b/scripts/gen-rrtypes.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python3
+# Generate DNS RR type constants for resolv header files.
+# Copyright (C) 2016-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+"""Generate DNS RR type constants for resolv header files.
+
+resolv/arpa/nameser.h and resolv/arpa/nameser_compat.h contain lists
+of RR type constants. This script downloads the current definitions
+from the IANA DNS Parameters protocol registry and translates it into
+the two different lists.
+
+Two lists are written to standard output. The first one contains enum
+constants for resolv/arpa/nameser.h. The second one lists the
+preprocessor macros for resolv/arpa/nameser_compat.h.
+
+"""
+
+# URL of the IANA registry.
+source = "http://www.iana.org/assignments/dns-parameters/dns-parameters-4.csv"
+
+import collections
+import csv
+import io
+import urllib.request
+
+Type = collections.namedtuple("Type", "name number comment")
+
+def get_types(source):
+ for row in csv.reader(io.TextIOWrapper(urllib.request.urlopen(source))):
+ if row[0] in ('TYPE', 'Unassigned', 'Private use', 'Reserved'):
+ continue
+ name, number, comment = row[:3]
+ if name == '*':
+ name = 'ANY'
+ comment = 'request for all cached records'
+ number = int(number)
+ yield Type(name, number, comment)
+
+types = list(get_types(source))
+
+print("// enum constants for resolv/arpa/nameser.h")
+print()
+for typ in types:
+ name = typ.name.replace("-", "_").lower()
+ print(" ns_t_{0} = {1.number},".format(name, typ))
+print()
+
+print("// macro aliases resolv/arpa/nameser_compat.h")
+print()
+for typ in types:
+ name = typ.name.replace("-", "_")
+ print("#define T_{0} ns_t_{1}".format(name.upper(), name.lower()))
+print()
diff --git a/scripts/gen-sorted.awk b/scripts/gen-sorted.awk
index 9669277b31..f338807e8e 100755
--- a/scripts/gen-sorted.awk
+++ b/scripts/gen-sorted.awk
@@ -1,7 +1,7 @@
#!/usr/bin/awk -f
# Generate sorted list of directories. The sorting is stable but with
# dependencies between directories resolved by moving dependees in front.
-# Copyright (C) 1998-2016 Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 Free Software Foundation, Inc.
# Written by Ulrich Drepper <drepper@cygnus.com>, 1998.
BEGIN {
@@ -46,36 +46,10 @@ type == "Subdirs" && NF == 2 && $1 == "inhibit" {
type == "Subdirs" && thisdir {
all[cnt++] = thisdir;
- if (FILENAME ~ (srcpfx ? /^\.\.\/sysdeps\// : /^sysdeps\//) \
- || system("test -d " srcpfx thisdir) == 0) {
- # This Subdirs file is in the main source tree,
- # or this subdirectory exists in the main source tree.
- this_srcdir = srcpfx thisdir
- }
- else {
- # The Subdirs file comes from an add-on that should have the subdirectory.
- dir = FILENAME;
- do
- sub(/\/[^/]+$/, "", dir);
- while (dir !~ /\/sysdeps$/);
- sub(/\/sysdeps$/, "", dir);
- if (system("test -d " dir "/" thisdir) == 0)
- dir = dir "/" thisdir;
- else {
- sub(/\/[^/]+$/, "", dir);
- if (system("test -d " dir "/" thisdir) == 0)
- dir = dir "/" thisdir;
- else {
- print FILENAME ":" FNR ":", "cannot find", thisdir > "/dev/stderr";
- exit 2
- }
- }
- file = dir "/Depend";
- if (srcpfx)
- sub(/^\.\.\//, "", dir);
- if (dir !~ /^\/.*$/)
- dir = "$(..)" dir;
- print thisdir "-srcdir", ":=", dir;
+ this_srcdir = srcpfx thisdir
+ if (system("test -d " this_srcdir) != 0) {
+ print FILENAME ":" FNR ":", "cannot find", this_srcdir > "/dev/stderr";
+ exit 2
}
file = this_srcdir "/Depend";
if (system("test -f " file) == 0) {
diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
new file mode 100644
index 0000000000..622199061a
--- /dev/null
+++ b/scripts/gen-tunables.awk
@@ -0,0 +1,174 @@
+# Generate dl-tunable-list.h from dl-tunables.list
+
+BEGIN {
+ min_of["STRING"]="0"
+ max_of["STRING"]="0"
+ min_of["INT_32"]="INT32_MIN"
+ max_of["INT_32"]="INT32_MAX"
+ min_of["UINT_64"]="0"
+ max_of["UINT_64"]="UINT64_MAX"
+ min_of["SIZE_T"]="0"
+ max_of["SIZE_T"]="SIZE_MAX"
+ tunable=""
+ ns=""
+ top_ns=""
+}
+
+# Skip over blank lines and comments.
+/^#/ {
+ next
+}
+
+/^[ \t]*$/ {
+ next
+}
+
+# Beginning of either a top namespace, tunable namespace or a tunable, decided
+# on the current value of TUNABLE, NS or TOP_NS.
+$2 == "{" {
+ if (top_ns == "") {
+ top_ns = $1
+ }
+ else if (ns == "") {
+ ns = $1
+ }
+ else if (tunable == "") {
+ tunable = $1
+ }
+ else {
+ printf ("Unexpected occurrence of '{': %s:%d\n", FILENAME, FNR)
+ exit 1
+ }
+
+ next
+}
+
+# End of either a top namespace, tunable namespace or a tunable.
+$1 == "}" {
+ if (tunable != "") {
+ # Tunables definition ended, now fill in default attributes.
+ if (!types[top_ns,ns,tunable]) {
+ types[top_ns,ns,tunable] = "STRING"
+ }
+ if (!minvals[top_ns,ns,tunable]) {
+ minvals[top_ns,ns,tunable] = min_of[types[top_ns,ns,tunable]]
+ }
+ if (!maxvals[top_ns,ns,tunable]) {
+ maxvals[top_ns,ns,tunable] = max_of[types[top_ns,ns,tunable]]
+ }
+ if (!env_alias[top_ns,ns,tunable]) {
+ env_alias[top_ns,ns,tunable] = "NULL"
+ }
+ if (!security_level[top_ns,ns,tunable]) {
+ security_level[top_ns,ns,tunable] = "SXID_ERASE"
+ }
+
+ tunable = ""
+ }
+ else if (ns != "") {
+ ns = ""
+ }
+ else if (top_ns != "") {
+ top_ns = ""
+ }
+ else {
+ printf ("syntax error: extra }: %s:%d\n", FILENAME, FNR)
+ exit 1
+ }
+ next
+}
+
+# Everything else, which could either be a tunable without any attributes or a
+# tunable attribute.
+{
+ if (ns == "") {
+ printf("Line %d: Invalid tunable outside a namespace: %s\n", NR, $0)
+ exit 1
+ }
+
+ if (tunable == "") {
+ # We encountered a tunable without any attributes, so note it with a
+ # default.
+ types[top_ns,ns,$1] = "STRING"
+ next
+ }
+
+ # Otherwise, we have encountered a tunable attribute.
+ split($0, arr, ":")
+ attr = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[1])
+ val = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[2])
+
+ if (attr == "type") {
+ types[top_ns,ns,tunable] = val
+ }
+ else if (attr == "minval") {
+ minvals[top_ns,ns,tunable] = val
+ }
+ else if (attr == "maxval") {
+ maxvals[top_ns,ns,tunable] = val
+ }
+ else if (attr == "env_alias") {
+ env_alias[top_ns,ns,tunable] = sprintf("\"%s\"", val)
+ }
+ else if (attr == "security_level") {
+ if (val == "SXID_ERASE" || val == "SXID_IGNORE" || val == "NONE") {
+ security_level[top_ns,ns,tunable] = val
+ }
+ else {
+ printf("Line %d: Invalid value (%s) for security_level: %s, ", NR, val,
+ $0)
+ print("Allowed values are 'SXID_ERASE', 'SXID_IGNORE', or 'NONE'")
+ exit 1
+ }
+ }
+ else if (attr == "default") {
+ if (types[top_ns,ns,tunable] == "STRING") {
+ default_val[top_ns,ns,tunable] = sprintf(".strval = \"%s\"", val);
+ }
+ else {
+ default_val[top_ns,ns,tunable] = sprintf(".numval = %s", val)
+ }
+ }
+}
+
+END {
+ if (ns != "") {
+ print "Unterminated namespace. Is a closing brace missing?"
+ exit 1
+ }
+
+ print "/* AUTOGENERATED by gen-tunables.awk. */"
+ print "#ifndef _TUNABLES_H_"
+ print "# error \"Do not include this file directly.\""
+ print "# error \"Include tunables.h instead.\""
+ print "#endif"
+ print "#include <dl-procinfo.h>\n"
+
+ # Now, the enum names
+ print "\ntypedef enum"
+ print "{"
+ for (tnm in types) {
+ split (tnm, indices, SUBSEP);
+ t = indices[1];
+ n = indices[2];
+ m = indices[3];
+ printf (" TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m);
+ }
+ print "} tunable_id_t;\n"
+
+ # Finally, the tunable list.
+ print "\n#ifdef TUNABLES_INTERNAL"
+ print "static tunable_t tunable_list[] attribute_relro = {"
+ for (tnm in types) {
+ split (tnm, indices, SUBSEP);
+ t = indices[1];
+ n = indices[2];
+ m = indices[3];
+ printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m)
+ printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, NULL, TUNABLE_SECLEVEL_%s, %s},\n",
+ types[t,n,m], minvals[t,n,m], maxvals[t,n,m],
+ default_val[t,n,m], security_level[t,n,m], env_alias[t,n,m]);
+ }
+ print "};"
+ print "#endif"
+}
diff --git a/scripts/install-sh b/scripts/install-sh
index 0b0fdcbba6..ac159ceda4 100755
--- a/scripts/install-sh
+++ b/scripts/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2013-12-25.23; # UTC
+scriptversion=2017-09-23.17; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -271,15 +271,18 @@ do
fi
dst=$dst_arg
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
+ # If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
- dst=$dstdir/`basename "$src"`
+ dstbase=`basename "$src"`
+ case $dst in
+ */) dst=$dst$dstbase;;
+ *) dst=$dst/$dstbase;;
+ esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
@@ -288,6 +291,11 @@ do
fi
fi
+ case $dstdir in
+ */) dstdirslash=$dstdir;;
+ *) dstdirslash=$dstdir/;;
+ esac
+
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
@@ -427,8 +435,8 @@ do
else
# Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
+ dsttmp=${dstdirslash}_inst.$$_
+ rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@@ -496,6 +504,6 @@ done
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/scripts/list-fixed-bugs.py b/scripts/list-fixed-bugs.py
index 51f3c36e69..b62f3b2146 100755
--- a/scripts/list-fixed-bugs.py
+++ b/scripts/list-fixed-bugs.py
@@ -1,5 +1,5 @@
#!/usr/bin/python3
-# Copyright (C) 2015-2016 Free Software Foundation, Inc.
+# Copyright (C) 2015-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
# The GNU C Library is free software; you can redistribute it and/or
diff --git a/scripts/merge-test-results.sh b/scripts/merge-test-results.sh
index 1175b20717..24f2b3fc81 100755
--- a/scripts/merge-test-results.sh
+++ b/scripts/merge-test-results.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Merge test results of individual tests or subdirectories.
-# Copyright (C) 2014-2016 Free Software Foundation, Inc.
+# Copyright (C) 2014-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
diff --git a/scripts/mkinstalldirs b/scripts/mkinstalldirs
index 55d537f872..a31ce6d029 100755
--- a/scripts/mkinstalldirs
+++ b/scripts/mkinstalldirs
@@ -1,7 +1,7 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2016-01-11.22; # UTC
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
@@ -157,6 +157,6 @@ exit $errstatus
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/scripts/move-if-change b/scripts/move-if-change
index cd744a92f3..f15923613c 100755
--- a/scripts/move-if-change
+++ b/scripts/move-if-change
@@ -2,13 +2,13 @@
# Like mv $1 $2, but if the files are the same, just delete $1.
# Status is zero if successful, nonzero otherwise.
-VERSION='2012-01-06 07:23'; # UTC
+VERSION='2017-09-13 06:45'; # UTC
# The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook
# do its job. Otherwise, update this string manually.
-# Copyright (C) 2002-2016 Free Software Foundation, Inc.
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@ VERSION='2012-01-06 07:23'; # UTC
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
usage="usage: $0 SOURCE DEST"
@@ -39,7 +39,7 @@ Report bugs to <bug-gnulib@gnu.org>."
version=`expr "$VERSION" : '\([^ ]*\)'`
version="move-if-change (gnulib) $version
Copyright (C) 2011 Free Software Foundation, Inc.
-License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law."
@@ -78,6 +78,6 @@ fi
## eval: (add-hook 'write-file-hooks 'time-stamp)
## time-stamp-start: "VERSION='"
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
-## time-stamp-time-zone: "UTC"
+## time-stamp-time-zone: "UTC0"
## time-stamp-end: "'; # UTC"
## End:
diff --git a/scripts/rellns-sh b/scripts/rellns-sh
index a57f601a90..9d4f4ab177 100755
--- a/scripts/rellns-sh
+++ b/scripts/rellns-sh
@@ -1,6 +1,6 @@
#!/bin/sh
# rellns-sh - Simplified ln program to generate relative symbolic link.
-# Copyright (C) 1996-2016 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Written by Ulrich Drepper <drepper@cygnus.com>, October 1996
#
# This program is free software; you can redistribute it and/or modify
diff --git a/scripts/sysd-rules.awk b/scripts/sysd-rules.awk
index cebc9d3e1b..c82e8fd607 100644
--- a/scripts/sysd-rules.awk
+++ b/scripts/sysd-rules.awk
@@ -50,11 +50,15 @@ BEGIN {
split(pattern, td, ":");
target_pattern = td[1];
dep_pattern = td[2];
+ # rtld objects are always PIC.
+ if (target_pattern ~ /^rtld/ && o != ".os") {
+ continue;
+ }
if (target_pattern == "%") {
command_suffix = "";
} else {
prefix = gensub(/%/, "", 1, target_pattern);
- command_suffix = " $(" prefix "CPPFLAGS)";
+ command_suffix = " $(" prefix "CPPFLAGS)" " $(" prefix "CFLAGS)";
}
target = "$(objpfx)" target_pattern o ":";
if (asm_rules) {
diff --git a/scripts/test-installation.pl b/scripts/test-installation.pl
index 5e84dd7184..b2e4ba7646 100755
--- a/scripts/test-installation.pl
+++ b/scripts/test-installation.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
-# Copyright (C) 1997-2016 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1997.
@@ -59,7 +59,7 @@ arglist: while (@ARGV) {
$ARGV[0] eq "--vers" || $ARGV[0] eq "--versi" ||
$ARGV[0] eq "--versio" || $ARGV[0] eq "--version") {
print "test-installation (GNU $PACKAGE)\n";
- print "Copyright (C) 2016 Free Software Foundation, Inc.\n";
+ print "Copyright (C) 2018 Free Software Foundation, Inc.\n";
print "This is free software; see the source for copying conditions. There is NO\n";
print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
print "Written by Andreas Jaeger <aj\@arthur.rhein-neckar.de>\n";
@@ -79,10 +79,12 @@ arglist: while (@ARGV) {
# We expect none or one argument.
if ($#ARGV == -1) {
+ $dir = ".";
$soversions="soversions.mk";
$config="config.make";
} elsif ($#ARGV == 0) {
if (-d $ARGV[0]) {
+ $dir = $ARGV[0];
$soversions = "$ARGV[0]/soversions.mk";
$config = "$ARGV[0]/config.make";
} else {
@@ -116,14 +118,13 @@ while (<SOVERSIONS>) {
# Filter out some libraries we don't want to link:
# - nss_ldap since it's not yet available
# - libdb1 since it conflicts with libdb
- # - libnss1_* from glibc-compat add-on
# - libthread_db since it contains unresolved references
# - it's just a test NSS module
# - We don't provide the libgcc so we don't test it
# - libmvec if it wasn't built
next if ($build_mathvec == 0 && $name eq "mvec");
if ($name ne "nss_ldap" && $name ne "db1"
- && !($name =~/^nss1_/) && $name ne "thread_db"
+ && $name ne "thread_db"
&& $name ne "nss_test1" && $name ne "libgcc_s") {
$link_libs .= " -l$name";
$versions{$name} = $version;
@@ -142,8 +143,8 @@ close SOVERSIONS;
# Create test program and link it against all
# shared libraries
-open PRG, ">/tmp/test-prg$$.c"
- or die ("Couldn't write test file /tmp/test-prg$$.c");
+open PRG, ">$dir/test-prg$$.c"
+ or die ("Couldn't write test file $dir/test-prg$$.c");
print PRG '
#include <stdio.h>
@@ -155,7 +156,7 @@ int main(void) {
';
close PRG;
-open GCC, "$CC /tmp/test-prg$$.c $link_libs -o /tmp/test-prg$$ 2>&1 |"
+open GCC, "$CC $dir/test-prg$$.c $link_libs -o $dir/test-prg$$ 2>&1 |"
or die ("Couldn't execute $CC!");
while (<GCC>) {
@@ -173,7 +174,7 @@ if ($?) {
$ok = 1;
%found = ();
-open LDD, "ldd /tmp/test-prg$$ |"
+open LDD, "ldd $dir/test-prg$$ |"
or die ("Couldn't execute ldd");
while (<LDD>) {
if (/^\s*lib/) {
@@ -213,8 +214,8 @@ foreach (keys %versions) {
&installation_problem unless $ok;
# Finally execute the test program
-system ("/tmp/test-prg$$") == 0
+system ("$dir/test-prg$$") == 0
or die ("Execution of test program failed");
# Clean up after ourselves
-unlink ("/tmp/test-prg$$", "/tmp/test-prg$$.c");
+unlink ("$dir/test-prg$$", "$dir/test-prg$$.c");
diff --git a/scripts/test_printers_common.py b/scripts/test_printers_common.py
new file mode 100644
index 0000000000..cf4de5ae23
--- /dev/null
+++ b/scripts/test_printers_common.py
@@ -0,0 +1,368 @@
+# Common functions and variables for testing the Python pretty printers.
+#
+# Copyright (C) 2016-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+"""These tests require PExpect 4.0 or newer.
+
+Exported constants:
+ PASS, FAIL, UNSUPPORTED (int): Test exit codes, as per evaluate-test.sh.
+"""
+
+import os
+import re
+from test_printers_exceptions import *
+
+PASS = 0
+FAIL = 1
+UNSUPPORTED = 77
+
+gdb_bin = 'gdb'
+gdb_options = '-q -nx'
+gdb_invocation = '{0} {1}'.format(gdb_bin, gdb_options)
+pexpect_min_version = 4
+gdb_min_version = (7, 8)
+encoding = 'utf-8'
+
+try:
+ import pexpect
+except ImportError:
+ print('PExpect 4.0 or newer must be installed to test the pretty printers.')
+ exit(UNSUPPORTED)
+
+pexpect_version = pexpect.__version__.split('.')[0]
+
+if int(pexpect_version) < pexpect_min_version:
+ print('PExpect 4.0 or newer must be installed to test the pretty printers.')
+ exit(UNSUPPORTED)
+
+if not pexpect.which(gdb_bin):
+ print('gdb 7.8 or newer must be installed to test the pretty printers.')
+ exit(UNSUPPORTED)
+
+timeout = 5
+TIMEOUTFACTOR = os.environ.get('TIMEOUTFACTOR')
+
+if TIMEOUTFACTOR:
+ timeout = int(TIMEOUTFACTOR)
+
+try:
+ # Check the gdb version.
+ version_cmd = '{0} --version'.format(gdb_invocation, timeout=timeout)
+ gdb_version_out = pexpect.run(version_cmd, encoding=encoding)
+
+ # The gdb version string is "GNU gdb <PKGVERSION><version>", where
+ # PKGVERSION can be any text. We assume that there'll always be a space
+ # between PKGVERSION and the version number for the sake of the regexp.
+ version_match = re.search(r'GNU gdb .* ([1-9]+)\.([0-9]+)', gdb_version_out)
+
+ if not version_match:
+ print('The gdb version string (gdb -v) is incorrectly formatted.')
+ exit(UNSUPPORTED)
+
+ gdb_version = (int(version_match.group(1)), int(version_match.group(2)))
+
+ if gdb_version < gdb_min_version:
+ print('gdb 7.8 or newer must be installed to test the pretty printers.')
+ exit(UNSUPPORTED)
+
+ # Check if gdb supports Python.
+ gdb_python_cmd = '{0} -ex "python import os" -batch'.format(gdb_invocation,
+ timeout=timeout)
+ gdb_python_error = pexpect.run(gdb_python_cmd, encoding=encoding)
+
+ if gdb_python_error:
+ print('gdb must have python support to test the pretty printers.')
+ print('gdb output: {!r}'.format(gdb_python_error))
+ exit(UNSUPPORTED)
+
+ # If everything's ok, spawn the gdb process we'll use for testing.
+ gdb = pexpect.spawn(gdb_invocation, echo=False, timeout=timeout,
+ encoding=encoding)
+ gdb_prompt = u'\(gdb\)'
+ gdb.expect(gdb_prompt)
+
+except pexpect.ExceptionPexpect as exception:
+ print('Error: {0}'.format(exception))
+ exit(FAIL)
+
+def test(command, pattern=None):
+ """Sends 'command' to gdb and expects the given 'pattern'.
+
+ If 'pattern' is None, simply consumes everything up to and including
+ the gdb prompt.
+
+ Args:
+ command (string): The command we'll send to gdb.
+ pattern (raw string): A pattern the gdb output should match.
+
+ Returns:
+ string: The string that matched 'pattern', or an empty string if
+ 'pattern' was None.
+ """
+
+ match = ''
+
+ gdb.sendline(command)
+
+ if pattern:
+ # PExpect does a non-greedy match for '+' and '*'. Since it can't look
+ # ahead on the gdb output stream, if 'pattern' ends with a '+' or a '*'
+ # we may end up matching only part of the required output.
+ # To avoid this, we'll consume 'pattern' and anything that follows it
+ # up to and including the gdb prompt, then extract 'pattern' later.
+ index = gdb.expect([u'{0}.+{1}'.format(pattern, gdb_prompt),
+ pexpect.TIMEOUT])
+
+ if index == 0:
+ # gdb.after now contains the whole match. Extract the text that
+ # matches 'pattern'.
+ match = re.match(pattern, gdb.after, re.DOTALL).group()
+ elif index == 1:
+ # We got a timeout exception. Print information on what caused it
+ # and bail out.
+ error = ('Response does not match the expected pattern.\n'
+ 'Command: {0}\n'
+ 'Expected pattern: {1}\n'
+ 'Response: {2}'.format(command, pattern, gdb.before))
+
+ raise pexpect.TIMEOUT(error)
+ else:
+ # Consume just the the gdb prompt.
+ gdb.expect(gdb_prompt)
+
+ return match
+
+def init_test(test_bin, printer_files, printer_names):
+ """Loads the test binary file and the required pretty printers to gdb.
+
+ Args:
+ test_bin (string): The name of the test binary file.
+ pretty_printers (list of strings): A list with the names of the pretty
+ printer files.
+ """
+
+ # Load all the pretty printer files. We're assuming these are safe.
+ for printer_file in printer_files:
+ test('source {0}'.format(printer_file))
+
+ # Disable all the pretty printers.
+ test('disable pretty-printer', r'0 of [0-9]+ printers enabled')
+
+ # Enable only the required printers.
+ for printer in printer_names:
+ test('enable pretty-printer {0}'.format(printer),
+ r'[1-9][0-9]* of [1-9]+ printers enabled')
+
+ # Finally, load the test binary.
+ test('file {0}'.format(test_bin))
+
+ # Disable lock elision.
+ test('set environment GLIBC_TUNABLES glibc.elision.enable=0')
+
+def go_to_main():
+ """Executes a gdb 'start' command, which takes us to main."""
+
+ test('start', r'main')
+
+def get_line_number(file_name, string):
+ """Returns the number of the line in which 'string' appears within a file.
+
+ Args:
+ file_name (string): The name of the file we'll search through.
+ string (string): The string we'll look for.
+
+ Returns:
+ int: The number of the line in which 'string' appears, starting from 1.
+ """
+ number = -1
+
+ with open(file_name) as src_file:
+ for i, line in enumerate(src_file):
+ if string in line:
+ number = i + 1
+ break
+
+ if number == -1:
+ raise NoLineError(file_name, string)
+
+ return number
+
+def break_at(file_name, string, temporary=True, thread=None):
+ """Places a breakpoint on the first line in 'file_name' containing 'string'.
+
+ 'string' is usually a comment like "Stop here". Notice this may fail unless
+ the comment is placed inline next to actual code, e.g.:
+
+ ...
+ /* Stop here */
+ ...
+
+ may fail, while:
+
+ ...
+ some_func(); /* Stop here */
+ ...
+
+ will succeed.
+
+ If 'thread' isn't None, the breakpoint will be set for all the threads.
+ Otherwise, it'll be set only for 'thread'.
+
+ Args:
+ file_name (string): The name of the file we'll place the breakpoint in.
+ string (string): A string we'll look for inside the file.
+ We'll place a breakpoint on the line which contains it.
+ temporary (bool): Whether the breakpoint should be automatically deleted
+ after we reach it.
+ thread (int): The number of the thread we'll place the breakpoint for,
+ as seen by gdb. If specified, it should be greater than zero.
+ """
+
+ if not thread:
+ thread_str = ''
+ else:
+ thread_str = 'thread {0}'.format(thread)
+
+ if temporary:
+ command = 'tbreak'
+ break_type = 'Temporary breakpoint'
+ else:
+ command = 'break'
+ break_type = 'Breakpoint'
+
+ line_number = str(get_line_number(file_name, string))
+
+ test('{0} {1}:{2} {3}'.format(command, file_name, line_number, thread_str),
+ r'{0} [0-9]+ at 0x[a-f0-9]+: file {1}, line {2}\.'.format(break_type,
+ file_name,
+ line_number))
+
+def continue_cmd(thread=None):
+ """Executes a gdb 'continue' command.
+
+ If 'thread' isn't None, the command will be applied to all the threads.
+ Otherwise, it'll be applied only to 'thread'.
+
+ Args:
+ thread (int): The number of the thread we'll apply the command to,
+ as seen by gdb. If specified, it should be greater than zero.
+ """
+
+ if not thread:
+ command = 'continue'
+ else:
+ command = 'thread apply {0} continue'.format(thread)
+
+ test(command)
+
+def next_cmd(count=1, thread=None):
+ """Executes a gdb 'next' command.
+
+ If 'thread' isn't None, the command will be applied to all the threads.
+ Otherwise, it'll be applied only to 'thread'.
+
+ Args:
+ count (int): The 'count' argument of the 'next' command.
+ thread (int): The number of the thread we'll apply the command to,
+ as seen by gdb. If specified, it should be greater than zero.
+ """
+
+ if not thread:
+ command = 'next'
+ else:
+ command = 'thread apply {0} next'
+
+ test('{0} {1}'.format(command, count))
+
+def select_thread(thread):
+ """Selects the thread indicated by 'thread'.
+
+ Args:
+ thread (int): The number of the thread we'll switch to, as seen by gdb.
+ This should be greater than zero.
+ """
+
+ if thread > 0:
+ test('thread {0}'.format(thread))
+
+def get_current_thread_lwpid():
+ """Gets the current thread's Lightweight Process ID.
+
+ Returns:
+ string: The current thread's LWP ID.
+ """
+
+ # It's easier to get the LWP ID through the Python API than the gdb CLI.
+ command = 'python print(gdb.selected_thread().ptid[1])'
+
+ return test(command, r'[0-9]+')
+
+def set_scheduler_locking(mode):
+ """Executes the gdb 'set scheduler-locking' command.
+
+ Args:
+ mode (bool): Whether the scheduler locking mode should be 'on'.
+ """
+ modes = {
+ True: 'on',
+ False: 'off'
+ }
+
+ test('set scheduler-locking {0}'.format(modes[mode]))
+
+def test_printer(var, to_string, children=None, is_ptr=True):
+ """ Tests the output of a pretty printer.
+
+ For a variable called 'var', this tests whether its associated printer
+ outputs the expected 'to_string' and children (if any).
+
+ Args:
+ var (string): The name of the variable we'll print.
+ to_string (raw string): The expected output of the printer's 'to_string'
+ method.
+ children (map {raw string->raw string}): A map with the expected output
+ of the printer's children' method.
+ is_ptr (bool): Whether 'var' is a pointer, and thus should be
+ dereferenced.
+ """
+
+ if is_ptr:
+ var = '*{0}'.format(var)
+
+ test('print {0}'.format(var), to_string)
+
+ if children:
+ for name, value in children.items():
+ # Children are shown as 'name = value'.
+ test('print {0}'.format(var), r'{0} = {1}'.format(name, value))
+
+def check_debug_symbol(symbol):
+ """ Tests whether a given debugging symbol exists.
+
+ If the symbol doesn't exist, raises a DebugError.
+
+ Args:
+ symbol (string): The symbol we're going to check for.
+ """
+
+ try:
+ test('ptype {0}'.format(symbol), r'type = {0}'.format(symbol))
+
+ except pexpect.TIMEOUT:
+ # The symbol doesn't exist.
+ raise DebugError(symbol)
diff --git a/scripts/test_printers_exceptions.py b/scripts/test_printers_exceptions.py
new file mode 100644
index 0000000000..cf10a356de
--- /dev/null
+++ b/scripts/test_printers_exceptions.py
@@ -0,0 +1,61 @@
+# Exception classes used when testing the Python pretty printers.
+#
+# Copyright (C) 2016-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+class NoLineError(Exception):
+ """Custom exception to indicate that a test file doesn't contain
+ the requested string.
+ """
+
+ def __init__(self, file_name, string):
+ """Constructor.
+
+ Args:
+ file_name (string): The name of the test file.
+ string (string): The string that was requested.
+ """
+
+ super(NoLineError, self).__init__()
+ self.file_name = file_name
+ self.string = string
+
+ def __str__(self):
+ """Shows a readable representation of the exception."""
+
+ return ('File {0} has no line containing the following string: {1}'
+ .format(self.file_name, self.string))
+
+class DebugError(Exception):
+ """Custom exception to indicate that a required debugging symbol is missing.
+ """
+
+ def __init__(self, symbol):
+ """Constructor.
+
+ Args:
+ symbol (string): The name of the entity whose debug info is missing.
+ """
+
+ super(DebugError, self).__init__()
+ self.symbol = symbol
+
+ def __str__(self):
+ """Shows a readable representation of the exception."""
+
+ return ('The required debugging information for {0} is missing.'
+ .format(self.symbol))
diff --git a/scripts/update-abilist.sh b/scripts/update-abilist.sh
index f9ffb954f9..28953bfe28 100644
--- a/scripts/update-abilist.sh
+++ b/scripts/update-abilist.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Update abilist files based on differences on one architecture.
-# Copyright (C) 2015-2016 Free Software Foundation, Inc.
+# Copyright (C) 2015-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
# The GNU C Library is free software; you can redistribute it and/or
@@ -20,9 +20,12 @@
set -e
export LC_ALL=C
-if [ $# -lt 3 ]; then
+if [ $# -lt 2 ]; then
echo "usage: $0 OLD-FILE NEW-FILE FILES-TO-BE-PATCHED..." 1>&2
exit 2
+elif [ $# -eq 2 ]; then
+ echo "info: no files to patch" 1>&2
+ exit 0
fi
old_file="$1"
diff --git a/scripts/update-copyrights b/scripts/update-copyrights
index 588041ce86..f048600e2a 100755
--- a/scripts/update-copyrights
+++ b/scripts/update-copyrights
@@ -1,6 +1,6 @@
#!/bin/sh
# Update copyright year lists.
-# Copyright (C) 2012-2016 Free Software Foundation, Inc.
+# Copyright (C) 2012-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -54,7 +54,7 @@ for f in $files; do
po/*.po)
# Files imported verbatim from the Translation Project.
;;
- INSTALL | intl/plural.c | locale/C-translit.h \
+ INSTALL | locale/C-translit.h \
| locale/programs/charmap-kw.h | locale/programs/locfile-kw.h \
| po/libc.pot | sysdeps/gnu/errlist.c)
# Generated files.
diff --git a/scripts/versionlist.awk b/scripts/versionlist.awk
index a9908033fa..fd51ff3fed 100644
--- a/scripts/versionlist.awk
+++ b/scripts/versionlist.awk
@@ -1,5 +1,5 @@
# Extract ordered list of version sets from Versions files.
-# Copyright (C) 2014-2016 Free Software Foundation, Inc.
+# Copyright (C) 2014-2018 Free Software Foundation, Inc.
BEGIN { in_lib = ""; in_version = 0 }
diff --git a/scripts/versions.awk b/scripts/versions.awk
index 408f7d06fb..a3df316c70 100644
--- a/scripts/versions.awk
+++ b/scripts/versions.awk
@@ -1,5 +1,5 @@
# Combine version map fragments into version scripts for our shared objects.
-# Copyright (C) 1998-2016 Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 Free Software Foundation, Inc.
# Written by Ulrich Drepper <drepper@cygnus.com>, 1998.
# This script expects the following variables to be defined:
@@ -101,6 +101,17 @@ END {
oldlib = "";
oldver = "";
+ real_first_ver_header = buildroot "first-versions.h"
+ first_ver_header = real_first_ver_header "T"
+ printf("#ifndef _FIRST_VERSIONS_H\n") > first_ver_header;
+ printf("#define _FIRST_VERSIONS_H\n") > first_ver_header;
+ real_ldbl_compat_header = buildroot "ldbl-compat-choose.h"
+ ldbl_compat_header = real_ldbl_compat_header "T"
+ printf("#ifndef _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header;
+ printf("#define _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header;
+ printf("#ifndef LONG_DOUBLE_COMPAT\n") > ldbl_compat_header;
+ printf("# error LONG_DOUBLE_COMPAT not defined\n") > ldbl_compat_header;
+ printf("#endif\n") > ldbl_compat_header;
printf("version-maps =");
while (getline < tmpfile) {
if ($1 != oldlib) {
@@ -127,11 +138,36 @@ END {
printf(" ") > outfile;
for (n = 3; n <= NF; ++n) {
printf(" %s", $n) > outfile;
+ sym = $n;
+ sub(";", "", sym);
+ first_ver_macro = "FIRST_VERSION_" oldlib "_" sym;
+ if (!(first_ver_macro in first_ver_seen) \
+ && oldver ~ "^GLIBC_[0-9]" \
+ && sym ~ "^[A-Za-z0-9_]*$") {
+ ver_val = oldver;
+ gsub("\\.", "_", ver_val);
+ printf("#define %s %s\n", first_ver_macro, ver_val) > first_ver_header;
+ first_ver_seen[first_ver_macro] = 1;
+ if (oldlib == "libc" || oldlib == "libm") {
+ printf("#if LONG_DOUBLE_COMPAT (%s, %s)\n",
+ oldlib, ver_val) > ldbl_compat_header;
+ printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) a\n",
+ oldlib, sym) > ldbl_compat_header;
+ printf("#else\n") > ldbl_compat_header;
+ printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) b\n",
+ oldlib, sym) > ldbl_compat_header;
+ printf("#endif\n") > ldbl_compat_header;
+ }
+ }
}
printf("\n") > outfile;
}
printf("\n");
+ printf("#endif /* first-versions.h */\n") > first_ver_header;
+ printf("#endif /* ldbl-compat-choose.h */\n") > ldbl_compat_header;
closeversion(oldver, veryoldver);
close_and_move(outfile, real_outfile);
+ close_and_move(first_ver_header, real_first_ver_header);
+ close_and_move(ldbl_compat_header, real_ldbl_compat_header);
#system("rm -f " tmpfile);
}