On Fri, 19 Apr 2024 at 11:03, Christophe Lyon
<christophe.l...@linaro.org> wrote:
>
> This script is a copy of the current script used by Sourceware's
> autoregen buildbots.
>
> It is intended as a helper to regenerate files managed by autotools
> (autoconf, automake, aclocal, ....), as well as the toplevel
> Makefile.in which is created by autogen.
>
> Other files can be updated when using maintainer-mode, but this is not
> covered by this script.
>
> 2024-04-19  Christophe Lyon  <christophe.l...@linaro.org>
>
>         contrib/
>         * autogen.py: New script.
Of course this should read "autoregen.py" :-)

> ---
>  contrib/autoregen.py | 221 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 221 insertions(+)
>  create mode 100755 contrib/autoregen.py
>
> diff --git a/contrib/autoregen.py b/contrib/autoregen.py
> new file mode 100755
> index 00000000000..faffc88c5bd
> --- /dev/null
> +++ b/contrib/autoregen.py
> @@ -0,0 +1,221 @@
> +#!/usr/bin/env python3
> +
> +# This script helps to regenerate files managed by autotools and
> +# autogen in binutils-gdb and gcc repositories.
> +
> +# It can be used by buildbots to check that the current repository
> +# contents has been updated correctly, and by developers to update
> +# such files as expected.
> +
> +import os
> +import shutil
> +import subprocess
> +from pathlib import Path
> +
> +
> +# On Gentoo, vanilla unpatched autotools are packaged separately.
> +# We place the vanilla names first as we want to prefer those if both exist.
> +AUTOCONF_NAMES = ["autoconf-vanilla-2.69", "autoconf-2.69", "autoconf"]
> +AUTOMAKE_NAMES = ["automake-vanilla-1.15", "automake-1.15.1", "automake"]
> +ACLOCAL_NAMES = ["aclocal-vanilla-1.15", "aclocal-1.15.1", "aclocal"]
> +AUTOHEADER_NAMES = ["autoheader-vanilla-2.69", "autoheader-2.69", 
> "autoheader"]
> +AUTORECONF_NAMES = ["autoreconf-vanilla-2.69", "autoreconf-2.69", 
> "autoreconf"]
> +
> +# Pick the first for each list that exists on this system.
> +AUTOCONF_BIN = next(name for name in AUTOCONF_NAMES if shutil.which(name))
> +AUTOMAKE_BIN = next(name for name in AUTOMAKE_NAMES if shutil.which(name))
> +ACLOCAL_BIN = next(name for name in ACLOCAL_NAMES if shutil.which(name))
> +AUTOHEADER_BIN = next(name for name in AUTOHEADER_NAMES if 
> shutil.which(name))
> +AUTORECONF_BIN = next(name for name in AUTORECONF_NAMES if 
> shutil.which(name))
> +
> +AUTOGEN_BIN = "autogen"
> +
> +# autoconf-wrapper and automake-wrapper from Gentoo look at this environment 
> variable.
> +# It's harmless to set it on other systems though.
> +EXTRA_ENV = {
> +    "WANT_AUTOCONF": AUTOCONF_BIN.split("-", 1)[1] if "-" in AUTOCONF_BIN 
> else "",
> +    "WANT_AUTOMAKE": AUTOMAKE_BIN.split("-", 1)[1] if "-" in AUTOMAKE_BIN 
> else "",
> +    "AUTOCONF": AUTOCONF_BIN,
> +    "ACLOCAL": ACLOCAL_BIN,
> +    "AUTOMAKE": AUTOMAKE_BIN,
> +    "AUTOGEN": AUTOGEN_BIN,
> +}
> +ENV = os.environ.copy()
> +ENV.update(EXTRA_ENV)
> +
> +
> +# Directories we should skip entirely because they're vendored or have 
> different
> +# autotools versions.
> +SKIP_DIRS = [
> +    # readline and minizip are maintained with different autotools versions
> +    "readline",
> +    "minizip",
> +]
> +
> +# these directories are known to be re-generatable with a simple autoreconf
> +# without special -I flags
> +# Entries commented out (and directories not listed) are handled by
> +# regenerate_manually().
> +AUTORECONF_DIRS = [
> +    # subdirs common to binutils-gdb and gcc
> +    "libbacktrace",
> +    "libdecnumber", # No Makefile.am
> +    "libiberty", # No Makefile.am
> +    "zlib",
> +
> +    # binutils-gdb subdirs
> +    "bfd",
> +    "binutils",
> +    "etc",
> +    "gas",
> +    "gdb",
> +    "gdbserver",
> +    "gdbsupport",
> +    "gnulib",
> +    "gold",
> +    "gprof",
> +    "gprofng",
> +    "gprofng/libcollector",
> +    "ld",
> +    "libctf",
> +    "libsframe",
> +    "opcodes",
> +    "sim",
> +
> +    # gcc subdirs
> +    "c++tools", # No aclocal.m4
> +    "gcc", # No Makefile.am
> +    #"fixincludes", # autoreconf complains about GCC_AC_FUNC_MMAP_BLACKLIST
> +    "gnattools", # No aclocal.m4
> +    "gotools",
> +    "libada", # No aclocal.m4
> +    "libatomic",
> +    "libcc1",
> +    "libcody", # No aclocal.m4
> +    "libcpp", # No Makefile.am
> +    "libffi",
> +    "libgcc", # No aclocal.m4
> +    "libgfortran",
> +    # Hack: ACLOCAL_AMFLAGS = -I .. -I ../config in Makefile.in but we
> +    # apply -I../config -I.. otherwise we do not match the current
> +    # contents
> +    #"libgm2",
> +    "libgo",
> +    "libgomp",
> +    "libgrust",
> +    "libitm",
> +    "libobjc", # No Makefile.am
> +    "libphobos",
> +    "libquadmath",
> +    "libsanitizer",
> +    "libssp",
> +    "libstdc++-v3",
> +    # This does not cover libvtv/testsuite/other-tests/Makefile.in
> +    "libvtv",
> +    "lto-plugin",
> +]
> +
> +
> +# Run the shell command CMD.
> +#
> +# Print the command on stdout prior to running it.
> +def run_shell(cmd: str):
> +    print(f"+ {cmd}", flush=True)
> +    res = subprocess.run(
> +        f"{cmd}",
> +        shell=True,
> +        encoding="utf8",
> +        env=ENV,
> +    )
> +    res.check_returncode()
> +
> +
> +def regenerate_with_autoreconf():
> +    run_shell(f"{AUTORECONF_BIN} -f")
> +
> +def regenerate_with_autogen():
> +    run_shell(f"{AUTOGEN_BIN} Makefile.def")
> +
> +def regenerate_manually():
> +    configure_lines = open("configure.ac").read().splitlines()
> +    if folder.stem == "fixincludes" or folder.stem == "libgm2" or any(
> +            True for line in configure_lines if 
> line.startswith("AC_CONFIG_MACRO_DIR")
> +    ):
> +        include_arg = ""
> +        include_arg2 = ""
> +        if (folder / ".." / "config").is_dir():
> +            include_arg = "-I../config"
> +
> +        # this is really a hack just for binutils-gdb/gprofng/libcollector
> +        # make sure that the order of includes is done as 
> --enable-maintainer-mode
> +        if (folder / ".." / ".." / "config").is_dir():
> +            include_arg = "-I../.."
> +            include_arg2 = "-I../../config"
> +
> +        if folder.stem == "fixincludes":
> +            include_arg = "-I.."
> +            include_arg2 = "-I../config"
> +
> +        if folder.stem == "libgm2":
> +            include_arg = "-I../config"
> +            include_arg2 = "-I.."
> +
> +        # aclocal does not support the -f short option for force
> +        run_shell(f"{ACLOCAL_BIN} --force {include_arg} {include_arg2}")
> +
> +    if (folder / "config.in").is_file() or any(
> +        True for line in configure_lines if 
> line.startswith("AC_CONFIG_HEADERS")
> +    ):
> +        run_shell(f"{AUTOHEADER_BIN} -f")
> +
> +    # The few lines below do not regenerate the exact same content as
> +    # currently in the repo. Disable them for now.
> +    # if (folder / "gm2-libs").is_dir():
> +    #     run_shell(f"{AUTOCONF_BIN} -f gm2-libs/config-host.in > 
> gm2-libs/config-host")
> +    #     run_shell(f"{AUTOHEADER_BIN} gm2-libs/config-host.in")
> +
> +
> +    # apparently automake is somehow unstable -> skip it for gotools
> +    if any(
> +        True for line in configure_lines if 
> line.startswith("AM_INIT_AUTOMAKE")
> +    ) and not str(folder).endswith("gotools"):
> +        run_shell(f"{AUTOMAKE_BIN} -f")
> +
> +    run_shell(f"{AUTOCONF_BIN} -f")
> +
> +
> +run_shell(f"{AUTOCONF_BIN} --version")
> +run_shell(f"{AUTOMAKE_BIN} --version")
> +run_shell(f"{ACLOCAL_BIN} --version")
> +run_shell(f"{AUTOHEADER_BIN} --version")
> +
> +print(f"Extra environment: {EXTRA_ENV}", flush=True)
> +
> +config_folders: list[Path] = []
> +autogen_folders: list[Path] = []
> +repo_root = Path.cwd()
> +
> +for root, _, files in os.walk("."):
> +    for file in files:
> +        if file == "configure.ac":
> +            config_folders.append(Path(root).resolve())
> +        if file == "Makefile.tpl":
> +            autogen_folders.append(Path(root).resolve())
> +
> +for folder in sorted(autogen_folders):
> +    print(f"Entering directory {folder}", flush=True)
> +    os.chdir(folder)
> +    regenerate_with_autogen()
> +
> +for folder in sorted(config_folders):
> +    if folder.stem in SKIP_DIRS:
> +        print(f"Skipping directory {folder}", flush=True)
> +        continue
> +
> +    print(f"Entering directory {folder}", flush=True)
> +    os.chdir(folder)
> +
> +    if str(folder.relative_to(repo_root)) in AUTORECONF_DIRS:
> +        regenerate_with_autoreconf()
> +    else:
> +        regenerate_manually()
> --
> 2.34.1
>

Reply via email to