changeset 17093:d31c977f5af4

non-recursive-gnulib-prefix-hack: new module * build-aux/prefix-gnulib-mk: Copied from coreutils, derived from the file that originated in Bison. * m4/non-recursive-gnulib-prefix-hack.m4: Likewise, this code is largely copied from a snippet that resided in bison's configure.ac. * modules/non-recursive-gnulib-prefix-hack: New file. * MODULES.html.sh (Support for maintaining and releasing projects): Add it.
author Jim Meyering <meyering@redhat.com>
date Thu, 20 Sep 2012 14:02:36 +0200
parents 4c739ea762f1
children 67cb7096523b
files ChangeLog MODULES.html.sh build-aux/prefix-gnulib-mk m4/non-recursive-gnulib-prefix-hack.m4 modules/non-recursive-gnulib-prefix-hack
diffstat 5 files changed, 316 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-09-20  Jim Meyering  <meyering@redhat.com>
+
+	non-recursive-gnulib-prefix-hack: new module
+	* build-aux/prefix-gnulib-mk: Copied from coreutils, derived from
+	the file that originated in Bison.
+	* m4/non-recursive-gnulib-prefix-hack.m4: Likewise, this code is
+	largely copied from a snippet that resided in bison's configure.ac.
+	* modules/non-recursive-gnulib-prefix-hack: New file.
+	* MODULES.html.sh (Support for maintaining and releasing projects):
+	Add it.
+
 2012-09-18  Jim Meyering  <meyering@redhat.com>
 
 	maint.mk: generalize _gl_tight_scope for non-recursive make
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -3527,6 +3527,7 @@
   func_module gnupload
   func_module maintainer-makefile
   func_module mktempd
+  func_module non-recursive-gnulib-prefix-hack
   func_module readme-release
   func_module test-framework-sh
   func_module update-copyright
new file mode 100755
--- /dev/null
+++ b/build-aux/prefix-gnulib-mk
@@ -0,0 +1,243 @@
+eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
+  & eval 'exec perl -wS "$0" $argv:q'
+    if 0;
+
+use strict;
+use IO::File;
+use Getopt::Long;
+use File::Basename; # for dirname
+
+my $VERSION = '2012-01-21 17:13'; # UTC
+(my $ME = $0) =~ s|.*/||;
+
+my $prefix;
+my $lib_name;
+
+sub usage ($)
+{
+  my ($exit_code) = @_;
+  my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
+  if ($exit_code != 0)
+    {
+      print $STREAM "Try '$ME --help' for more information.\n";
+    }
+  else
+    {
+      print $STREAM <<EOF;
+Usage: $ME --lib-name=NAME FILE
+   or: $ME [--help|--version]
+Rewrite a gnulib-tool-generated FILE like lib/gnulib.mk to work with
+automake's subdir-objects.
+
+OPTIONS:
+
+This option must be specified:
+
+   --lib-name=NAME    library name, often "lib\$project"
+
+The following are optional:
+
+   --help             display this help and exit
+   --version          output version information and exit
+
+EOF
+    }
+  exit $exit_code;
+}
+
+# contents ($FILE_NAME)
+# ---------------------
+sub contents ($)
+{
+  my ($file) = @_;
+  local $/;                     # Turn on slurp-mode.
+  my $f = new IO::File "< $file" or die "$file";
+  my $contents = $f->getline or die "$file";
+  $f->close;
+  return $contents;
+}
+
+# prefix_word ($WORD)
+# -------------------
+# Do not prefix special words such as variable dereferences.  Also,
+# "Makefile" is really "Makefile", since precisely there is no
+# lib/Makefile.
+sub prefix_word ($)
+{
+  local ($_) = @_;
+  $_ = $prefix . $_
+    unless (/^-/ || m{^\$\(\w+\)} || $_ eq "Makefile" || $_ eq '\\'
+            || $_ eq '@ALLOCA@');
+  return $_;
+}
+
+
+# prefix_words ($TEXT)
+# --------------------
+sub prefix_words ($)
+{
+  local ($_) = @_;
+  s{(\S+)}{prefix_word($1)}gem;
+  return $_;
+}
+
+
+# prefix_assignment ($LHS-AND-ASSIGN-OP, $RHS)
+# --------------------------------------------
+sub prefix_assignment ($$)
+{
+  my ($lhs_and_assign_op, $rhs) = @_;
+  my $res;
+
+  # Some variables are initialized by gnulib.mk, and we don't want
+  # that.  Change '=' to '+='.
+  if ($lhs_and_assign_op =~ /^GPERF =$/)
+    {
+      # Do not change the RHS, which specifies the GPERF program.
+    }
+  elsif ($lhs_and_assign_op =~
+      /^(SUBDIRS|EXTRA_DIST|BUILT_SOURCES|SUFFIXES|MOSTLYCLEANFILES
+         |CLEANFILES|DISTCLEANFILES|MAINTAINERCLEANFILES|AM_CFLAGS
+         |AM_CPPFLAGS|AM_GNU_GETTEXT)\ =/x)
+    {
+      $lhs_and_assign_op =~ s/=/+=/;
+    }
+  # We don't want to inherit gnulib's AUTOMAKE_OPTIONS, comment them.
+  elsif ($lhs_and_assign_op =~ /^AUTOMAKE_OPTIONS =/)
+    {
+      $lhs_and_assign_op =~ s/^/# /;
+    }
+  elsif ($lhs_and_assign_op =~ /^SUFFIXES /)
+    {
+      # Elide any SUFFIXES assignment or concatenation.
+      $lhs_and_assign_op =~ s/^/# /;
+    }
+  # The words are (probably) paths to files in lib/: prefix them.
+  else
+    {
+      $rhs = prefix_words($rhs)
+    }
+
+  # Variables which name depend on the location: libbison_a_SOURCES =>
+  # lib_libbison_a_SOURCES.
+  $lhs_and_assign_op =~ s/($lib_name)/lib_$1/g;
+
+  return $lhs_and_assign_op . $rhs;
+}
+
+# prefix $CONTENTS
+# ----------------
+# $CONTENTS is a Makefile content.  Post-process it so that each file-name
+# is prefixed with $prefix (e.g., "lib/").
+#
+# Relies heavily on the regularity of the file generated by gnulib-tool.
+sub prefix ($)
+{
+  # Work on $_.
+  local ($_) = @_;
+
+  # Prefix all the occurrence of files in rules.  If there is nothing
+  # after in the :, it's probably a phony target, or a suffix rule.
+  # Don't touch it.
+  s{^([-\w+/]+\.[-\w.]+ *: *\S.*)$}
+   {prefix_words($1)}gem;
+
+  # Prefix files in variables.
+  s{^([\w.]+\s*\+?=)(.*)$}
+   {prefix_assignment($1, $2)}gem;
+
+  # These three guys escape all the other regular rules.
+  s{(charset\.alias|ref-add\.sed|ref-del\.sed)}{$prefix$1}g;
+  # Unfortunately, as a result we sometimes have lib/lib.
+  s{($prefix){2}}{$1}g;
+
+  # lib_libcoreutils_a_SOURCES += \
+  #   imaxtostr.c \
+  #   inttostr.c \
+  #   offtostr.c \
+  #   uinttostr.c \
+  #   umaxtostr.c
+  # The above are not handled since they're on continued lines, so
+  # deal with them manually:
+  s{^(\s*)((?:[ui]max|u?int|off)tostr\.c(:? \\)?)$}{$1$prefix$2}gm;
+
+  # $(srcdir)/ is actually $(top_srcdir)/$prefix/.
+  # The trailing slash is required to avoid matching this rule:
+  #   test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile
+  s{\$\(srcdir\)/}{\$(top_srcdir)/$prefix}g;
+
+  # Sometimes, t-$@ is used instead of $@-t, which, of course, does
+  # not work when we have a $@ with a directory in it.
+  s{t-\$\@}{\$\@-t}g;
+
+  # Some AC_SUBST patterns remain and would better be Make macros.
+  s{\@(MKDIR_P)\@}{\$($1)}g;
+
+  # Adjust paths in mkdir.
+  s{(\$\(MKDIR_P\))\s*(\w+)}{$1 $prefix$2}g;
+
+  return $_;
+}
+
+# process ($IN)
+# -------------
+sub process ($)
+{
+  my ($file) = @_;
+  my ($bak) = "$file.bak";
+  rename ($file, $bak) or die;
+  my $contents = contents ($bak);
+  $contents = prefix ($contents);
+  my $out = new IO::File(">$file") or die;
+  print $out $contents;
+}
+
+{
+  GetOptions
+    (
+     'lib-name=s' => \$lib_name,
+     help => sub { usage 0 },
+     version => sub { print "$ME version $VERSION\n"; exit },
+    ) or usage 1;
+
+  my $fail = 0;
+  defined $lib_name
+    or (warn "$ME: no library name; use --lib-name=NAME\n"), $fail = 1;
+
+  # There must be exactly one argument.
+  @ARGV == 0
+    and (warn "$ME: missing FILE argument\n"), $fail = 1;
+  1 < @ARGV
+    and (warn "$ME: too many arguments:\n", join ("\n", @ARGV), "\n"),
+      $fail = 1;
+  $fail
+    and usage 1;
+
+  my $file = $ARGV[0];
+  $prefix = (dirname $file) . '/';
+  warn "prefix=$prefix\n";
+
+  process $file;
+}
+
+### Setup "GNU" style for perl-mode and cperl-mode.
+## Local Variables:
+## perl-indent-level: 2
+## perl-continued-statement-offset: 2
+## perl-continued-brace-offset: 0
+## perl-brace-offset: 0
+## perl-brace-imaginary-offset: 0
+## perl-label-offset: -2
+## cperl-indent-level: 2
+## cperl-brace-offset: 0
+## cperl-continued-brace-offset: 0
+## cperl-label-offset: -2
+## cperl-extra-newline-before-brace: t
+## cperl-merge-trailing-else: nil
+## cperl-continued-statement-offset: 2
+## eval: (add-hook 'write-file-hooks 'time-stamp)
+## time-stamp-start: "my $VERSION = '"
+## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
+## time-stamp-time-zone: "UTC"
+## time-stamp-end: "'; # UTC"
+## End:
new file mode 100644
--- /dev/null
+++ b/m4/non-recursive-gnulib-prefix-hack.m4
@@ -0,0 +1,35 @@
+dnl Copyright (C) 2012 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl gl_NON_RECURSIVE_GNULIB_PREFIX_HACK LIB_DIR
+dnl Adjust configure-set $gl_LIBOBJS and each AC_SUBST'd *_H variable
+dnl with a value ending in ".h" to reflect that these files are located
+dnl in the directory specified by LIB_DIR.
+AC_DEFUN([gl_NON_RECURSIVE_GNULIB_PREFIX_HACK],
+[
+  # Tell AC_LIBSOURCES where to find source files like alloca.c.
+  AC_CONFIG_LIBOBJ_DIR([lib])
+
+  # This hack originated in bison.  It is required when using non-recursive
+  # automake rules to build from gnulib-provided lib/ sources.  Hence, LIB_DIR
+  # is usually simply "lib".  Those rules use the list of names like "fchdir.o"
+  # and "strstr.o" in gl_LIBOBJS.  With non-recursive make, we must prefix each
+  # such file name with the "lib/" prefix.  See also build-aux/prefix-gnulib-mk.
+  gl_LIBOBJS=`echo "$gl_LIBOBJS" | sed -e 's, , $1/,g'`
+
+  # Listing the names of the variables to prefix is error-prone.
+  # Rather, adjust each AC_SUBST'd variable whose name ends in '_H'
+  # and whose value ends in '.h'.
+  for ac_var in $ac_subst_vars
+  do
+    eval "ac_val=\$$ac_var"
+    case $ac_var:$ac_val in
+      (*_H:*.h) eval "$ac_var=$1/\$$ac_var";;
+    esac
+  done
+
+  # If $ALLOCA is not empty, prefix its value with "lib/".
+  test -n "$ALLOCA" && ALLOCA="lib/$ALLOCA"
+])
new file mode 100644
--- /dev/null
+++ b/modules/non-recursive-gnulib-prefix-hack
@@ -0,0 +1,26 @@
+Description:
+Adjust a gnulib-generated gnulib.mk file and configure script so
+that they are usable in a non-recursive make framework.
+
+Files:
+build-aux/prefix-gnulib-mk
+m4/non-recursive-gnulib-prefix-hack.m4
+
+Depends-on:
+
+configure.ac:
+dnl Run our hack near the end, just before config.status creation.
+dnl It must happen late, i.e., after gl_LIBOBJS has been finalized.
+AC_CONFIG_COMMANDS_PRE([
+  gl_NON_RECURSIVE_GNULIB_PREFIX_HACK([lib])
+  ])
+
+Makefile.am:
+
+Include:
+
+License:
+unlimited
+
+Maintainer:
+Jim Meyering