]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
build: Separate git operations from build operations.
authorBruno Haible <bruno@clisp.org>
Tue, 2 Apr 2019 15:51:13 +0000 (17:51 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 2 Apr 2019 15:51:43 +0000 (17:51 +0200)
* gitsub.sh: New file, from gnulib.
* autogen.sh: Remove all git operations and the --no-git option. Look at the
GNULIB_SRCDIR environment variable. Ignore the GNULIB_TOOL environment variable.
* HACKING: Explain when to use gitsub.sh.

HACKING
autogen.sh
gitsub.sh [new file with mode: 0755]

diff --git a/HACKING b/HACKING
index 7de67f7b862fe8f34933231e39c7390ae5f3868a..a2bc2884ecaac4fe18ddead18fc1f26d38bd059c 100644 (file)
--- a/HACKING
+++ b/HACKING
@@ -192,15 +192,21 @@ $ sudo localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
 $ sudo localedef -i zh_CN -f GB18030 zh_CN.GB18030
 
 
-Building off the git repository
+Building off the Git repository
 ===============================
 
-Access to the git repository is described at
-  https://savannah.gnu.org/git/?group=gettext
+Access to the Git repository is described at
+https://savannah.gnu.org/git/?group=gettext .
 
-After fetching the sources from the repository, peek at the comments in
-autogen.sh, then run "./autogen.sh"; then you can proceed with "./configure"
-as usual.
+After fetching the sources from the Git repository, peek at the comments in
+autogen.sh, then run
+  ./gitsub.sh pull
+  ./autogen.sh
+Then you can proceed with "./configure" as usual.
+
+Each time you want to update the source, do not only "git pull".  Instead do
+  git pull && ./gitsub.sh pull
+  ./autogen.sh
 
 
 Submitting patches
index f67c05ed84c5322c20e792600a4a8a9a53db100b..4c04f7f32f333bb6c31b10ea7f177c5b57476e53 100755 (executable)
 #   - Autoconf
 #   - Automake >= 1.13
 #   - Wget
-#   - Git
 #   - XZ Utils
-#
-# By default, it fetches Gnulib as a git submodule.  If you already
-# have a local copy of Gnulib, you can avoid extra network traffic by
-# setting the GNULIB_SRCDIR environment variable pointing to the path.
+# If not used from a released tarball, it also requires either
+#   - the GNULIB_SRCDIR environment variable pointing to a gnulib checkout, or
+#   - a preceding invocation of './gitsub.sh pull'.
 #
 # In addition, it fetches the archive.dir.tar.gz file, which contains
 # data files used by the autopoint program.  If you already have the
 # file, place it under gettext-tools/misc, before running this script.
 #
-# Usage: ./autogen.sh [--skip-gnulib] [--no-git]
-#
-# Usage after a git clone:              ./autogen.sh
-# Usage from a released tarball:        ./autogen.sh --skip-gnulib
-# This does not use a gnulib checkout.
+# Usage: ./autogen.sh [--skip-gnulib]
 
 # Nuisances.
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 skip_gnulib=false
 
-# Use git to update gnulib sources
-use_git=true
-
 while :; do
   case "$1" in
     --skip-gnulib) skip_gnulib=true; shift;;
-    --no-git) use_git=false; shift;;
     *) break ;;
   esac
 done
 
-if ! $use_git && ! test -d "$GNULIB_SRCDIR"; then
-  echo "error: --no-git requires GNULIB_SRCDIR to be set" 1>&2
-  exit 1
-fi
-
-cleanup_gnulib() {
-  status=$?
-  rm -fr "$gnulib_path"
-  exit $status
-}
-
-git_modules_config () {
-  test -f .gitmodules && git config --file .gitmodules "$@"
-}
-
-gnulib_path=$(git_modules_config submodule.gnulib.path)
-test -z "$gnulib_path" && gnulib_path=gnulib
-
 # The tests in gettext-tools/tests are not meant to be executable, because
 # they have a TESTS_ENVIRONMENT that specifies the shell explicitly.
 
 if ! $skip_gnulib; then
-  # Get gnulib files.
-  case ${GNULIB_SRCDIR--} in
-  -)
-    if git_modules_config submodule.gnulib.url >/dev/null; then
-      echo "$0: getting gnulib files..."
-      git submodule init || exit $?
-      git submodule update || exit $?
-
-    elif [ ! -d "$gnulib_path" ]; then
-      echo "$0: getting gnulib files..."
-
-      trap cleanup_gnulib 1 2 13 15
-
-      shallow=
-      git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
-      git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" ||
-        cleanup_gnulib
-
-      trap - 1 2 13 15
-    fi
-    GNULIB_SRCDIR=$gnulib_path
-    ;;
-  *)
-    # Use GNULIB_SRCDIR as a reference.
-    if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
-          git_modules_config submodule.gnulib.url >/dev/null; then
-      echo "$0: getting gnulib files..."
-      if git submodule -h | grep -- --reference > /dev/null; then
-        # Prefer the one-liner available in git 1.6.4 or newer.
-        git submodule update --init --reference "$GNULIB_SRCDIR" \
-          "$gnulib_path" || exit $?
-      else
-        # This fallback allows at least git 1.5.5.
-        if test -f "$gnulib_path"/gnulib-tool; then
-          # Since file already exists, assume submodule init already complete.
-          git submodule update || exit $?
-        else
-          # Older git can't clone into an empty directory.
-          rmdir "$gnulib_path" 2>/dev/null
-          git clone --reference "$GNULIB_SRCDIR" \
-            "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
-            && git submodule init && git submodule update \
-            || exit $?
-        fi
-      fi
-      GNULIB_SRCDIR=$gnulib_path
-    fi
-    ;;
-  esac
-  # Now it should contain a gnulib-tool.
-  if test -f "$GNULIB_SRCDIR"/gnulib-tool; then
-    GNULIB_TOOL="$GNULIB_SRCDIR"/gnulib-tool
+  if test -n "$GNULIB_SRCDIR"; then
+    test -d "$GNULIB_SRCDIR" || {
+      echo "*** GNULIB_SRCDIR is set but does not point to an existing directory." 1>&2
+      exit 1
+    }
   else
-    echo "** warning: gnulib-tool not found" 1>&2
-  fi
-  # Skip the gnulib-tool step if gnulib-tool was not found.
-  if test -n "$GNULIB_TOOL"; then
-    # In gettext-runtime:
-    GNULIB_MODULES_RUNTIME_FOR_SRC='
-      atexit
-      basename
-      binary-io
-      closeout
-      error
-      getopt-gnu
-      gettext-h
-      havelib
-      memmove
-      progname
-      propername
-      relocatable-prog
-      setlocale
-      sigpipe
-      stdbool
-      stdio
-      stdlib
-      strtoul
-      unistd
-      unlocked-io
-      xalloc
-    '
-    GNULIB_MODULES_RUNTIME_OTHER='
-      gettext-runtime-misc
-      ansi-c++-opt
-      csharpcomp-script
-      java
-      javacomp-script
-    '
-    $GNULIB_TOOL --dir=gettext-runtime --lib=libgrt --source-base=gnulib-lib --m4-base=gnulib-m4 --no-libtool --local-dir=gnulib-local --local-symlink \
-      --import $GNULIB_MODULES_RUNTIME_FOR_SRC $GNULIB_MODULES_RUNTIME_OTHER || exit $?
-    # In gettext-runtime/libasprintf:
-    GNULIB_MODULES_LIBASPRINTF='
-      alloca
-      errno
-      verify
-      xsize
-    '
-    GNULIB_MODULES_LIBASPRINTF_OTHER='
-    '
-    $GNULIB_TOOL --dir=gettext-runtime/libasprintf --source-base=. --m4-base=gnulib-m4 --lgpl=2 --makefile-name=Makefile.gnulib --libtool --local-dir=gnulib-local --local-symlink \
-      --import $GNULIB_MODULES_LIBASPRINTF $GNULIB_MODULES_LIBASPRINTF_OTHER || exit $?
-    $GNULIB_TOOL --copy-file m4/intmax_t.m4 gettext-runtime/libasprintf/gnulib-m4/intmax_t.m4 || exit $?
-    $GNULIB_TOOL --copy-file m4/wchar_t.m4 gettext-runtime/libasprintf/gnulib-m4/wchar_t.m4 || exit $?
-    $GNULIB_TOOL --copy-file m4/wint_t.m4 gettext-runtime/libasprintf/gnulib-m4/wint_t.m4 || exit $?
-    # In gettext-tools:
-    GNULIB_MODULES_TOOLS_FOR_SRC='
-      alloca-opt
-      atexit
-      backupfile
-      basename
-      binary-io
-      bison-i18n
-      byteswap
-      c-ctype
-      c-strcase
-      c-strcasestr
-      c-strstr
-      clean-temp
-      closedir
-      closeout
-      copy-file
-      csharpcomp
-      csharpexec
-      error
-      error-progname
-      execute
-      fd-ostream
-      file-ostream
-      filename
-      findprog
-      fnmatch
-      fopen
-      fstrcmp
-      full-write
-      fwriteerror
-      gcd
-      getline
-      getopt-gnu
-      gettext
-      gettext-h
-      hash
-      html-styled-ostream
-      iconv
-      javacomp
-      javaexec
-      libunistring-optional
-      localcharset
-      locale
-      localename
-      lock
-      memchr
-      memmove
-      memset
-      minmax
-      mkdir
-      obstack
-      open
-      opendir
-      openmp
-      ostream
-      pipe-filter-ii
-      progname
-      propername
-      read-file
-      readdir
-      relocatable-prog
-      relocatable-script
-      setlocale
-      sh-quote
-      sigpipe
-      sigprocmask
-      spawn-pipe
-      stdbool
-      stdio
-      stdlib
-      stpcpy
-      stpncpy
-      strchrnul
-      strcspn
-      strerror
-      strpbrk
-      strtol
-      strtoul
-      styled-ostream
-      sys_select
-      sys_stat
-      sys_time
-      term-styled-ostream
-      trim
-      unictype/ctype-space
-      unilbrk/ulc-width-linebreaks
-      uniname/uniname
-      unistd
-      unistr/u8-check
-      unistr/u8-mbtouc
-      unistr/u8-mbtoucr
-      unistr/u8-uctomb
-      unistr/u16-mbtouc
-      uniwidth/width
-      unlocked-io
-      vasprintf
-      wait-process
-      write
-      xalloc
-      xconcat-filename
-      xerror
-      xmalloca
-      xmemdup0
-      xsetenv
-      xstriconv
-      xstriconveh
-      xvasprintf
-    '
-    # Common dependencies of GNULIB_MODULES_TOOLS_FOR_SRC and GNULIB_MODULES_TOOLS_FOR_LIBGREP.
-    GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES='
-      alloca-opt
-      extensions
-      gettext-h
-      include_next
-      locale
-      localcharset
-      malloc-posix
-      mbrtowc
-      mbsinit
-      multiarch
-      snippet/arg-nonnull
-      snippet/c++defs
-      snippet/warn-on-use
-      ssize_t
-      stdbool
-      stddef
-      stdint
-      stdlib
-      streq
-      unistd
-      verify
-      wchar
-      wctype-h
-    '
-    GNULIB_MODULES_TOOLS_OTHER='
-      gettext-tools-misc
-      ansi-c++-opt
-      csharpcomp-script
-      csharpexec-script
-      java
-      javacomp-script
-      javaexec-script
-      stdint
-    '
-    GNULIB_MODULES_TOOLS_LIBUNISTRING_TESTS='
-      unilbrk/u8-possible-linebreaks-tests
-      unilbrk/ulc-width-linebreaks-tests
-      unistr/u8-mbtouc-tests
-      unistr/u8-mbtouc-unsafe-tests
-      uniwidth/width-tests
-    '
-    $GNULIB_TOOL --dir=gettext-tools --lib=libgettextlib --source-base=gnulib-lib --m4-base=gnulib-m4 --tests-base=gnulib-tests --makefile-name=Makefile.gnulib --libtool --with-tests --local-dir=gnulib-local --local-symlink \
-      --import --avoid=hash-tests --avoid=fdutimensat-tests --avoid=futimens-tests --avoid=utime-tests --avoid=utimens-tests --avoid=utimensat-tests \
-      `for m in $GNULIB_MODULES_TOOLS_LIBUNISTRING_TESTS; do echo --avoid=$m; done` $GNULIB_MODULES_TOOLS_FOR_SRC $GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES $GNULIB_MODULES_TOOLS_OTHER || exit $?
-    # In gettext-tools/libgrep:
-    GNULIB_MODULES_TOOLS_FOR_LIBGREP='
-      mbrlen
-      regex
-    '
-    $GNULIB_TOOL --dir=gettext-tools --macro-prefix=grgl --lib=libgrep --source-base=libgrep --m4-base=libgrep/gnulib-m4 --witness-c-macro=IN_GETTEXT_TOOLS_LIBGREP --makefile-name=Makefile.gnulib --local-dir=gnulib-local --local-symlink \
-      --import `for m in $GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES; do if test \`$GNULIB_TOOL --extract-applicability $m\` != all; then echo --avoid=$m; fi; done` $GNULIB_MODULES_TOOLS_FOR_LIBGREP || exit $?
-    # In gettext-tools/libgettextpo:
-    # This is a subset of the GNULIB_MODULES_FOR_SRC.
-    GNULIB_MODULES_LIBGETTEXTPO='
-      basename
-      close
-      c-ctype
-      c-strcase
-      c-strstr
-      error
-      error-progname
-      file-ostream
-      filename
-      fopen
-      fstrcmp
-      fwriteerror
-      gcd
-      getline
-      gettext-h
-      hash
-      iconv
-      libunistring-optional
-      markup
-      minmax
-      open
-      ostream
-      progname
-      relocatable-lib
-      sigpipe
-      stdbool
-      stdio
-      stdlib
-      stpcpy
-      stpncpy
-      strchrnul
-      strerror
-      unictype/ctype-space
-      unilbrk/ulc-width-linebreaks
-      unistr/u8-mbtouc
-      unistr/u8-mbtoucr
-      unistr/u8-uctomb
-      unistr/u16-mbtouc
-      uniwidth/width
-      unlocked-io
-      vasprintf
-      xalloc
-      xconcat-filename
-      xmalloca
-      xerror
-      xstriconv
-      xvasprintf
-    '
-    # Module 'realloc-posix' is enabled in gettext-tools/config.status, because
-    # it occurs as dependency of some module ('read-file') in
-    # GNULIB_MODULES_TOOLS_FOR_SRC. Therefore on mingw, libgettextpo/stdlib.h
-    # contains '#define realloc rpl_realloc'. Therefore we need to include
-    # realloc.lo in libgettextpo.la.
-    GNULIB_MODULES_LIBGETTEXTPO_OTHER='
-      realloc-posix
-    '
-    $GNULIB_TOOL --dir=gettext-tools --source-base=libgettextpo --m4-base=libgettextpo/gnulib-m4 --macro-prefix=gtpo --makefile-name=Makefile.gnulib --libtool --local-dir=gnulib-local --local-symlink \
-      --import $GNULIB_MODULES_LIBGETTEXTPO $GNULIB_MODULES_LIBGETTEXTPO_OTHER || exit $?
-    # Overwrite older versions of .m4 files with the up-to-date version.
-    cp gettext-runtime/m4/gettext.m4 gettext-tools/gnulib-m4/gettext.m4
-    cp gettext-runtime/m4/intl.m4 gettext-tools/gnulib-m4/intl.m4
-    # Import build tools.  We use --copy-file to avoid directory creation.
-    $GNULIB_TOOL --copy-file tests/init.sh gettext-tools || exit $?
-    $GNULIB_TOOL --copy-file build-aux/git-version-gen || exit $?
-    $GNULIB_TOOL --copy-file build-aux/gitlog-to-changelog || exit $?
-    $GNULIB_TOOL --copy-file build-aux/update-copyright || exit $?
-    $GNULIB_TOOL --copy-file build-aux/useless-if-before-free || exit $?
-    $GNULIB_TOOL --copy-file build-aux/vc-list-files || exit $?
-    $GNULIB_TOOL --copy-file top/GNUmakefile . || exit $?
-    $GNULIB_TOOL --copy-file top/maint.mk . || exit $?
+    GNULIB_SRCDIR=`pwd`/gnulib
+    test -d "$GNULIB_SRCDIR" || {
+      echo "*** Subdirectory 'gnulib' does not yet exist. Use './gitsub.sh pull' to create it, or set the environment variable GNULIB_SRCDIR." 1>&2
+      exit 1
+    }
   fi
+  # Now it should contain a gnulib-tool.
+  GNULIB_TOOL="$GNULIB_SRCDIR/gnulib-tool"
+  test -f "$GNULIB_TOOL" || {
+    echo "*** gnulib-tool not found." 1>&2
+    exit 1
+  }
+  # In gettext-runtime:
+  GNULIB_MODULES_RUNTIME_FOR_SRC='
+    atexit
+    basename
+    binary-io
+    closeout
+    error
+    getopt-gnu
+    gettext-h
+    havelib
+    memmove
+    progname
+    propername
+    relocatable-prog
+    setlocale
+    sigpipe
+    stdbool
+    stdio
+    stdlib
+    strtoul
+    unistd
+    unlocked-io
+    xalloc
+  '
+  GNULIB_MODULES_RUNTIME_OTHER='
+    gettext-runtime-misc
+    ansi-c++-opt
+    csharpcomp-script
+    java
+    javacomp-script
+  '
+  $GNULIB_TOOL --dir=gettext-runtime --lib=libgrt --source-base=gnulib-lib --m4-base=gnulib-m4 --no-libtool --local-dir=gnulib-local --local-symlink \
+    --import $GNULIB_MODULES_RUNTIME_FOR_SRC $GNULIB_MODULES_RUNTIME_OTHER || exit $?
+  # In gettext-runtime/libasprintf:
+  GNULIB_MODULES_LIBASPRINTF='
+    alloca
+    errno
+    verify
+    xsize
+  '
+  GNULIB_MODULES_LIBASPRINTF_OTHER='
+  '
+  $GNULIB_TOOL --dir=gettext-runtime/libasprintf --source-base=. --m4-base=gnulib-m4 --lgpl=2 --makefile-name=Makefile.gnulib --libtool --local-dir=gnulib-local --local-symlink \
+    --import $GNULIB_MODULES_LIBASPRINTF $GNULIB_MODULES_LIBASPRINTF_OTHER || exit $?
+  $GNULIB_TOOL --copy-file m4/intmax_t.m4 gettext-runtime/libasprintf/gnulib-m4/intmax_t.m4 || exit $?
+  $GNULIB_TOOL --copy-file m4/wchar_t.m4 gettext-runtime/libasprintf/gnulib-m4/wchar_t.m4 || exit $?
+  $GNULIB_TOOL --copy-file m4/wint_t.m4 gettext-runtime/libasprintf/gnulib-m4/wint_t.m4 || exit $?
+  # In gettext-tools:
+  GNULIB_MODULES_TOOLS_FOR_SRC='
+    alloca-opt
+    atexit
+    backupfile
+    basename
+    binary-io
+    bison-i18n
+    byteswap
+    c-ctype
+    c-strcase
+    c-strcasestr
+    c-strstr
+    clean-temp
+    closedir
+    closeout
+    copy-file
+    csharpcomp
+    csharpexec
+    error
+    error-progname
+    execute
+    fd-ostream
+    file-ostream
+    filename
+    findprog
+    fnmatch
+    fopen
+    fstrcmp
+    full-write
+    fwriteerror
+    gcd
+    getline
+    getopt-gnu
+    gettext
+    gettext-h
+    hash
+    html-styled-ostream
+    iconv
+    javacomp
+    javaexec
+    libunistring-optional
+    localcharset
+    locale
+    localename
+    lock
+    memchr
+    memmove
+    memset
+    minmax
+    mkdir
+    obstack
+    open
+    opendir
+    openmp
+    ostream
+    pipe-filter-ii
+    progname
+    propername
+    read-file
+    readdir
+    relocatable-prog
+    relocatable-script
+    setlocale
+    sh-quote
+    sigpipe
+    sigprocmask
+    spawn-pipe
+    stdbool
+    stdio
+    stdlib
+    stpcpy
+    stpncpy
+    strchrnul
+    strcspn
+    strerror
+    strpbrk
+    strtol
+    strtoul
+    styled-ostream
+    sys_select
+    sys_stat
+    sys_time
+    term-styled-ostream
+    trim
+    unictype/ctype-space
+    unilbrk/ulc-width-linebreaks
+    uniname/uniname
+    unistd
+    unistr/u8-check
+    unistr/u8-mbtouc
+    unistr/u8-mbtoucr
+    unistr/u8-uctomb
+    unistr/u16-mbtouc
+    uniwidth/width
+    unlocked-io
+    vasprintf
+    wait-process
+    write
+    xalloc
+    xconcat-filename
+    xerror
+    xmalloca
+    xmemdup0
+    xsetenv
+    xstriconv
+    xstriconveh
+    xvasprintf
+  '
+  # Common dependencies of GNULIB_MODULES_TOOLS_FOR_SRC and GNULIB_MODULES_TOOLS_FOR_LIBGREP.
+  GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES='
+    alloca-opt
+    extensions
+    gettext-h
+    include_next
+    locale
+    localcharset
+    malloc-posix
+    mbrtowc
+    mbsinit
+    multiarch
+    snippet/arg-nonnull
+    snippet/c++defs
+    snippet/warn-on-use
+    ssize_t
+    stdbool
+    stddef
+    stdint
+    stdlib
+    streq
+    unistd
+    verify
+    wchar
+    wctype-h
+  '
+  GNULIB_MODULES_TOOLS_OTHER='
+    gettext-tools-misc
+    ansi-c++-opt
+    csharpcomp-script
+    csharpexec-script
+    java
+    javacomp-script
+    javaexec-script
+    stdint
+  '
+  GNULIB_MODULES_TOOLS_LIBUNISTRING_TESTS='
+    unilbrk/u8-possible-linebreaks-tests
+    unilbrk/ulc-width-linebreaks-tests
+    unistr/u8-mbtouc-tests
+    unistr/u8-mbtouc-unsafe-tests
+    uniwidth/width-tests
+  '
+  $GNULIB_TOOL --dir=gettext-tools --lib=libgettextlib --source-base=gnulib-lib --m4-base=gnulib-m4 --tests-base=gnulib-tests --makefile-name=Makefile.gnulib --libtool --with-tests --local-dir=gnulib-local --local-symlink \
+    --import --avoid=hash-tests --avoid=fdutimensat-tests --avoid=futimens-tests --avoid=utime-tests --avoid=utimens-tests --avoid=utimensat-tests \
+    `for m in $GNULIB_MODULES_TOOLS_LIBUNISTRING_TESTS; do echo --avoid=$m; done` $GNULIB_MODULES_TOOLS_FOR_SRC $GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES $GNULIB_MODULES_TOOLS_OTHER || exit $?
+  # In gettext-tools/libgrep:
+  GNULIB_MODULES_TOOLS_FOR_LIBGREP='
+    mbrlen
+    regex
+  '
+  $GNULIB_TOOL --dir=gettext-tools --macro-prefix=grgl --lib=libgrep --source-base=libgrep --m4-base=libgrep/gnulib-m4 --witness-c-macro=IN_GETTEXT_TOOLS_LIBGREP --makefile-name=Makefile.gnulib --local-dir=gnulib-local --local-symlink \
+    --import `for m in $GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES; do if test \`$GNULIB_TOOL --extract-applicability $m\` != all; then echo --avoid=$m; fi; done` $GNULIB_MODULES_TOOLS_FOR_LIBGREP || exit $?
+  # In gettext-tools/libgettextpo:
+  # This is a subset of the GNULIB_MODULES_FOR_SRC.
+  GNULIB_MODULES_LIBGETTEXTPO='
+    basename
+    close
+    c-ctype
+    c-strcase
+    c-strstr
+    error
+    error-progname
+    file-ostream
+    filename
+    fopen
+    fstrcmp
+    fwriteerror
+    gcd
+    getline
+    gettext-h
+    hash
+    iconv
+    libunistring-optional
+    markup
+    minmax
+    open
+    ostream
+    progname
+    relocatable-lib
+    sigpipe
+    stdbool
+    stdio
+    stdlib
+    stpcpy
+    stpncpy
+    strchrnul
+    strerror
+    unictype/ctype-space
+    unilbrk/ulc-width-linebreaks
+    unistr/u8-mbtouc
+    unistr/u8-mbtoucr
+    unistr/u8-uctomb
+    unistr/u16-mbtouc
+    uniwidth/width
+    unlocked-io
+    vasprintf
+    xalloc
+    xconcat-filename
+    xmalloca
+    xerror
+    xstriconv
+    xvasprintf
+  '
+  # Module 'realloc-posix' is enabled in gettext-tools/config.status, because
+  # it occurs as dependency of some module ('read-file') in
+  # GNULIB_MODULES_TOOLS_FOR_SRC. Therefore on mingw, libgettextpo/stdlib.h
+  # contains '#define realloc rpl_realloc'. Therefore we need to include
+  # realloc.lo in libgettextpo.la.
+  GNULIB_MODULES_LIBGETTEXTPO_OTHER='
+    realloc-posix
+  '
+  $GNULIB_TOOL --dir=gettext-tools --source-base=libgettextpo --m4-base=libgettextpo/gnulib-m4 --macro-prefix=gtpo --makefile-name=Makefile.gnulib --libtool --local-dir=gnulib-local --local-symlink \
+    --import $GNULIB_MODULES_LIBGETTEXTPO $GNULIB_MODULES_LIBGETTEXTPO_OTHER || exit $?
+  # Overwrite older versions of .m4 files with the up-to-date version.
+  cp gettext-runtime/m4/gettext.m4 gettext-tools/gnulib-m4/gettext.m4
+  cp gettext-runtime/m4/intl.m4 gettext-tools/gnulib-m4/intl.m4
+  # Import build tools.  We use --copy-file to avoid directory creation.
+  $GNULIB_TOOL --copy-file tests/init.sh gettext-tools || exit $?
+  $GNULIB_TOOL --copy-file build-aux/git-version-gen || exit $?
+  $GNULIB_TOOL --copy-file build-aux/gitlog-to-changelog || exit $?
+  $GNULIB_TOOL --copy-file build-aux/update-copyright || exit $?
+  $GNULIB_TOOL --copy-file build-aux/useless-if-before-free || exit $?
+  $GNULIB_TOOL --copy-file build-aux/vc-list-files || exit $?
+  $GNULIB_TOOL --copy-file top/GNUmakefile . || exit $?
+  $GNULIB_TOOL --copy-file top/maint.mk . || exit $?
 fi
 
 # Fetch config.guess, config.sub.
diff --git a/gitsub.sh b/gitsub.sh
new file mode 100755 (executable)
index 0000000..9665198
--- /dev/null
+++ b/gitsub.sh
@@ -0,0 +1,483 @@
+#! /bin/sh
+#
+# Copyright (C) 2019 Free Software Foundation, Inc.
+# Written by Bruno Haible <bruno@clisp.org>, 2019.
+#
+# 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 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 <https://www.gnu.org/licenses/>.
+
+# Program that manages the subdirectories of a git checkout of a package
+# that come from other packages (called "dependency packages").
+#
+# This program is similar in spirit to 'git submodule', with three
+# essential differences:
+#
+#   1) Its options are easy to remember, and do not require knowledge of
+#      'git submodule'.
+#
+#   2) The developer may choose to work on a different checkout for each
+#      dependency package.  This is important when the developer is
+#      preparing simultaneous changes to the package and the dependency
+#      package, or is using the dependency package in several packages.
+#
+#      The developer indicates this different checkout by setting the
+#      environment variable <SUBDIR>_SRCDIR (e.g. GNULIB_SRCDIR) to point to it.
+#
+#   3) The package maintainer may choose to use or not use git submodules.
+#
+#      The advantages of management through a git submodule are:
+#        - Changes to the dependency package cannot suddenly break your package.
+#          In other words, when there is an incompatible change that will cause
+#          a breakage, you can fix things at your pace; you are not forced to
+#          cope with such breakages in an emergency.
+#        - When you need to make a change as a response to a change in the
+#          dependency package, your co-developers cannot accidentally mix things
+#          up (for example, use a combination of your newest change with an
+#          older version of the dependency package).
+#
+#      The advantages of management without a git submodule (just as a plain
+#      subdirectory, let's call it a "subcheckout") are:
+#        - The simplicity: you are conceptually always using the newest revision
+#          of the dependency package.
+#        - You don't have to remember to periodially upgrade the dependency.
+#          Upgrading the dependency is an implicit operation.
+
+# This program is meant to be copied to the top-level directory of the package,
+# together with a configuration file.  The configuration is supposed to be
+# named '.gitmodules' and to define:
+# * The git submodules, as described in "man 5 gitmodules" or
+#   <https://git-scm.com/docs/gitmodules>.  For example:
+#
+#       [submodule "gnulib"]
+#               url = git://git.savannah.gnu.org/gnulib.git
+#               path = gnulib
+#
+#   You don't add this piece of configuration to .gitmodules manually.  Instead,
+#   you would invoke
+#     $ git submodule add --name "gnulib" -- git://git.savannah.gnu.org/gnulib.git gnulib
+#
+# * The subdirectories that are not git submodules, in a similar syntax.  For
+#   example:
+#
+#       [subcheckout "gnulib"]
+#               url = git://git.savannah.gnu.org/gnulib.git
+#               path = gnulib
+#
+# Here the URL is the one used for anonymous checkouts of the dependency
+# package. If the developer needs a checkout with write access, they can
+# either set the GNULIB_SRCDIR environment variable to point to that checkout
+# or modify the gnulib/.git/config file to enter a different URL.
+
+scriptname="$0"
+scriptversion='2019-04-01'
+nl='
+'
+IFS=" ""       $nl"
+
+# func_usage
+# outputs to stdout the --help usage message.
+func_usage ()
+{
+  echo "\
+Usage: gitsub.sh pull [SUBDIR]
+       gitsub.sh upgrade [SUBDIR]
+       gitsub.sh checkout SUBDIR REVISION
+
+Operations:
+
+gitsub.sh pull [SUBDIR]
+        You should perform this operation after 'git clone ...' and after
+        every 'git pull'.
+        It brings your checkout in sync with what the other developers of
+        your package have committed and pushed.
+        If an environment variable <SUBDIR>_SRCDIR is set, with a non-empty
+        value, nothing is done for this SUBDIR.
+        If no SUBDIR is specified, the operation applies to all dependencies.
+
+gitsub.sh upgrade [SUBDIR]
+        You should perform this operation periodically, to ensure currency
+        of the dependency package revisions that you use.
+        This operation pulls and checks out the changes that the developers
+        of the dependency package have committed and pushed.
+        If an environment variable <SUBDIR>_SRCDIR is set, with a non-empty
+        value, nothing is done for this SUBDIR.
+        If no SUBDIR is specified, the operation applies to all dependencies.
+
+gitsub.sh checkout SUBDIR REVISION
+        Checks out a specific revision for a dependency package.
+        If an environment variable <SUBDIR>_SRCDIR is set, with a non-empty
+        value, this operation fails.
+
+This script requires the git program in the PATH and an internet connection.
+"
+}
+
+# func_version
+# outputs to stdout the --version message.
+func_version ()
+{
+  year=`echo "$scriptversion" | sed -e 's/^\(....\)-.*/\1/'`
+  echo "\
+gitsub.sh (GNU gnulib) $scriptversion
+Copyright (C) 2019-$year Free Software Foundation, Inc.
+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.
+"
+  printf "Written by %s.\n" "Bruno Haible"
+}
+
+# func_fatal_error message
+# outputs to stderr a fatal error message, and terminates the program.
+# Input:
+# - scriptname               name of this program
+func_fatal_error ()
+{
+  echo "$scriptname: *** $1" 1>&2
+  echo "$scriptname: *** Stop." 1>&2
+  exit 1
+}
+
+# func_warning message
+# Outputs to stderr a warning message,
+func_warning ()
+{
+  echo "gitsub.sh: warning: $1" 1>&2
+}
+
+# func_note message
+# Outputs to stdout a note message,
+func_note ()
+{
+  echo "gitsub.sh: note: $1"
+}
+
+# Unset CDPATH.  Otherwise, output from 'cd dir' can surprise callers.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Command-line option processing.
+mode=
+while test $# -gt 0; do
+  case "$1" in
+    --help | --hel | --he | --h )
+      func_usage
+      exit $? ;;
+    --version | --versio | --versi | --vers | --ver | --ve | --v )
+      func_version
+      exit $? ;;
+    -- )
+      # Stop option processing
+      shift
+      break ;;
+    -* )
+      echo "gitsub.sh: unknown option $1" 1>&2
+      echo "Try 'gitsub.sh --help' for more information." 1>&2
+      exit 1 ;;
+    * )
+      break ;;
+  esac
+done
+if test $# = 0; then
+  echo "gitsub.sh: missing operation argument" 1>&2
+  echo "Try 'gitsub.sh --help' for more information." 1>&2
+  exit 1
+fi
+case "$1" in
+  pull | upgrade | checkout )
+    mode="$1"
+    shift ;;
+  *)
+    echo "gitsub.sh: unknown operation '$1'" 1>&2
+    echo "Try 'gitsub.sh --help' for more information." 1>&2
+    exit 1 ;;
+esac
+if test $# = 2 && test $mode != checkout || test $# -gt 2; then
+  echo "gitsub.sh: too many arguments in '$mode' mode" 1>&2
+  echo "Try 'gitsub.sh --help' for more information." 1>&2
+  exit 1
+fi
+if test $# = 0 && test $mode = checkout; then
+  echo "gitsub.sh: too few arguments in '$mode' mode" 1>&2
+  echo "Try 'gitsub.sh --help' for more information." 1>&2
+  exit 1
+fi
+
+# Read the configuration.
+# Output:
+# - subcheckout_names        space-separated list of subcheckout names
+# - submodule_names          space-separated list of submodule names
+if test -f .gitmodules; then
+  subcheckout_names=`git config --file .gitmodules --get-regexp --name-only 'subcheckout\..*\.url' | sed -e 's/^subcheckout\.//' -e 's/\.url$//' | tr -d '\r' | tr '\n' ' '`
+  submodule_names=`git config --file .gitmodules --get-regexp --name-only 'submodule\..*\.url' | sed -e 's/^submodule\.//' -e 's/\.url$//' | tr -d '\r' | tr '\n' ' '`
+else
+  subcheckout_names=
+  submodule_names=
+fi
+
+# func_validate SUBDIR
+# Verifies that the state on the file system is in sync with the declarations
+# in the configuration file.
+# Input:
+# - subcheckout_names        space-separated list of subcheckout names
+# - submodule_names          space-separated list of submodule names
+# Output:
+# - srcdirvar                Environment that the user can set
+# - srcdir                   Value of the environment variable
+# - path                     if $srcdir = "": relative path of the subdirectory
+# - needs_init               if $srcdir = "" and $path is not yet initialized:
+#                            true
+# - url                      if $srcdir = "" and $path is not yet initialized:
+#                            the repository URL
+func_validate ()
+{
+  srcdirvar=`echo "$1" | LC_ALL=C sed -e 's/[^a-zA-Z0-9]/_/g' | LC_ALL=C tr '[a-z]' '[A-Z]'`"_SRCDIR"
+  eval 'srcdir=$'"$srcdirvar"
+  path=
+  url=
+  if test -n "$srcdir"; then
+    func_note "Ignoring '$1' because $srcdirvar is set."
+  else
+    found=false
+    needs_init=
+    case " $subcheckout_names " in *" $1 "*)
+      found=true
+      # It ought to be a subcheckout.
+      path=`git config --file .gitmodules "subcheckout.$1.path"`
+      if test -z "$path"; then
+        path="$1"
+      fi
+      if test -d "$path"; then
+        if test -d "$path/.git"; then
+          # It's a plain checkout.
+          :
+        else
+          if test -f "$path/.git"; then
+            # It's a submodule.
+            func_fatal_error "Subdirectory '$path' is supposed to be a plain checkout, but it is a submodule."
+          else
+            func_warning "Ignoring '$path' because it exists but is not a git checkout."
+          fi
+        fi
+      else
+        # The subdir does not yet exist.
+        needs_init=true
+        url=`git config --file .gitmodules "subcheckout.$1.url"`
+        if test -z "$url"; then
+          func_fatal_error "Property subcheckout.$1.url is not defined in .gitmodules"
+        fi
+      fi
+      ;;
+    esac
+    case " $submodule_names " in *" $1 "*)
+      found=true
+      # It ought to be a submodule.
+      path=`git config --file .gitmodules "submodule.$1.path"`
+      if test -z "$path"; then
+        path="$1"
+      fi
+      if test -d "$path"; then
+        if test -d "$path/.git" || test -f "$path/.git"; then
+          # It's likely a submodule.
+          :
+        else
+          path_if_empty=`find "$path" -prune -empty 2>/dev/null`
+          if test -n "$path_if_empty"; then
+            # The subdir is empty.
+            needs_init=true
+          else
+            # The subdir is not empty.
+            # It is important to report an error, because we don't want to erase
+            # the user's files and 'git submodule update gnulib' sometimes reports
+            # "fatal: destination path '$path' already exists and is not an empty directory."
+            # but sometimes does not.
+            func_fatal_error "Subdir '$path' exists but is not a git checkout."
+          fi
+        fi
+      else
+        # The subdir does not yet exist.
+        needs_init=true
+      fi
+      # Another way to determine needs_init could be:
+      # if git submodule status "$path" | grep '^-' > /dev/null; then
+      #   needs_init=true
+      # fi
+      if test -n "$needs_init"; then
+        url=`git config --file .gitmodules "submodule.$1.url"`
+        if test -z "$url"; then
+          func_fatal_error "Property submodule.$1.url is not defined in .gitmodules"
+        fi
+      fi
+      ;;
+    esac
+    if ! $found; then
+      func_fatal_error "Subdir '$1' is not configured as a subcheckout or a submodule in .gitmodules"
+    fi
+  fi
+}
+
+# func_cleanup_current_git_clone
+# Cleans up the current 'git clone' operation.
+# Input:
+# - path
+func_cleanup_current_git_clone ()
+{
+  rm -rf "$path"
+  func_fatal_error "git clone failed"
+}
+
+# func_pull SUBDIR
+# Implements the 'pull' operation.
+func_pull ()
+{
+  func_validate "$1"
+  if test -z "$srcdir"; then
+    case " $subcheckout_names " in *" $1 "*)
+      # It's a subcheckout.
+      if test -d "$path"; then
+        if test -d "$path/.git"; then
+          (cd "$path" && git pull) || func_fatal_error "git operation failed"
+        fi
+      else
+        # The subdir does not yet exist. Create a plain checkout.
+        trap func_cleanup_current_git_clone 1 2 13 15
+        git clone "$url" "$path" || func_cleanup_current_git_clone
+        trap - 1 2 13 15
+      fi
+      ;;
+    esac
+    case " $submodule_names " in *" $1 "*)
+      # It's a submodule.
+      if test -n "$needs_init"; then
+        # Create a submodule checkout.
+        git submodule init -- "$path" && git submodule update -- "$path" || func_fatal_error "git operation failed"
+      else
+        # See https://stackoverflow.com/questions/1030169/easy-way-to-pull-latest-of-all-git-submodules
+        # https://stackoverflow.com/questions/4611512/is-there-a-way-to-make-git-pull-automatically-update-submodules
+        git submodule update "$path" || func_fatal_error "git operation failed"
+      fi
+      ;;
+    esac
+  fi
+}
+
+# func_upgrade SUBDIR
+# Implements the 'upgrade' operation.
+func_upgrade ()
+{
+  func_validate "$1"
+  if test -z "$srcdir"; then
+    if test -d "$path"; then
+      case " $subcheckout_names " in *" $1 "*)
+        # It's a subcheckout.
+        if test -d "$path/.git"; then
+          (cd "$path" && git pull) || func_fatal_error "git operation failed"
+        fi
+        ;;
+      esac
+      case " $submodule_names " in *" $1 "*)
+        # It's a submodule.
+        if test -z "$needs_init"; then
+          (cd "$path" && git fetch && git merge origin/master) || func_fatal_error "git operation failed"
+        fi
+        ;;
+      esac
+    else
+      # The subdir does not yet exist.
+      func_fatal_error "Subdirectory '$path' does not exist yet. Use 'gitsub.sh pull' to create it."
+    fi
+  fi
+}
+
+# func_checkout SUBDIR REVISION
+# Implements the 'checkout' operation.
+func_checkout ()
+{
+  func_validate "$1"
+  if test -z "$srcdir"; then
+    if test -d "$path"; then
+      case " $subcheckout_names " in *" $1 "*)
+        # It's a subcheckout.
+        if test -d "$path/.git"; then
+          (cd "$path" && git checkout "$2") || func_fatal_error "git operation failed"
+        fi
+        ;;
+      esac
+      case " $submodule_names " in *" $1 "*)
+        # It's a submodule.
+        if test -z "$needs_init"; then
+          (cd "$path" && git checkout "$2") || func_fatal_error "git operation failed"
+        fi
+        ;;
+      esac
+    else
+      # The subdir does not yet exist.
+      func_fatal_error "Subdirectory '$path' does not exist yet. Use 'gitsub.sh pull' to create it."
+    fi
+  fi
+}
+
+case "$mode" in
+  pull )
+    if test $# = 0; then
+      for sub in $subcheckout_names $submodule_names; do
+        func_pull "$sub"
+      done
+    else
+      valid=false
+      for sub in $subcheckout_names $submodule_names; do
+        if test "$sub" = "$1"; then
+          valid=true
+        fi
+      done
+      if $valid; then
+        func_pull "$1"
+      else
+        func_fatal_error "Subdir '$1' is not configured as a subcheckout or a submodule in .gitmodules"
+      fi
+    fi
+    ;;
+
+  upgrade )
+    if test $# = 0; then
+      for sub in $subcheckout_names $submodule_names; do
+        func_upgrade "$sub"
+      done
+    else
+      valid=false
+      for sub in $subcheckout_names $submodule_names; do
+        if test "$sub" = "$1"; then
+          valid=true
+        fi
+      done
+      if $valid; then
+        func_upgrade "$1"
+      else
+        func_fatal_error "Subdir '$1' is not configured as a subcheckout or a submodule in .gitmodules"
+      fi
+    fi
+    ;;
+
+  checkout )
+    valid=false
+    for sub in $subcheckout_names $submodule_names; do
+      if test "$sub" = "$1"; then
+        valid=true
+      fi
+    done
+    if $valid; then
+      func_checkout "$1" "$2"
+    else
+      func_fatal_error "Subdir '$1' is not configured as a subcheckout or a submodule in .gitmodules"
+    fi
+    ;;
+esac