From dad4fe691de928b88e3c52680606ba0caabbf6bf Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 10 Sep 2012 16:38:03 +0200 Subject: [PATCH 1/3] build: new module to help make lib/ use non-recursive make * gl/modules/non-recursive-gnulib-prefix-hack: New module. * gl/m4/non-recursive-gnulib-prefix-hack.m4: (gl_NON_RECURSIVE_GNULIB_PREFIX_HACK): This is the snippet that this module inserts near the end of configure. * gl/build-aux/prefix-gnulib-mk: New script, from bison. Changes from the code in bison: (prefix_assignment): Split a long line. (prefix): Add trailing slashes to avoid a single false match. Handle imaxtostr.c and the other *tostr.c files manually. Also, use $prefix in place of hard-coded "lib/". --- gl/build-aux/prefix-gnulib-mk | 238 ++++++++++++++++++++++++++++ gl/m4/non-recursive-gnulib-prefix-hack.m4 | 29 ++++ gl/modules/non-recursive-gnulib-prefix-hack | 25 +++ 3 files changed, 292 insertions(+) create mode 100755 gl/build-aux/prefix-gnulib-mk create mode 100644 gl/m4/non-recursive-gnulib-prefix-hack.m4 create mode 100644 gl/modules/non-recursive-gnulib-prefix-hack diff --git a/gl/build-aux/prefix-gnulib-mk b/gl/build-aux/prefix-gnulib-mk new file mode 100755 index 0000000..cc74f51 --- /dev/null +++ b/gl/build-aux/prefix-gnulib-mk @@ -0,0 +1,238 @@ +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 <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 '\\'; + 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 =~ + /^(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{^ ((?:[ui]max|u?int|off)tostr\.c(:? \\)?)$}{ $prefix$1}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: diff --git a/gl/m4/non-recursive-gnulib-prefix-hack.m4 b/gl/m4/non-recursive-gnulib-prefix-hack.m4 new file mode 100644 index 0000000..3c5c48e --- /dev/null +++ b/gl/m4/non-recursive-gnulib-prefix-hack.m4 @@ -0,0 +1,29 @@ +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], +[ + # 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 +]) diff --git a/gl/modules/non-recursive-gnulib-prefix-hack b/gl/modules/non-recursive-gnulib-prefix-hack new file mode 100644 index 0000000..26cd914 --- /dev/null +++ b/gl/modules/non-recursive-gnulib-prefix-hack @@ -0,0 +1,25 @@ +Description: +Compute a good buffer size for dealing with two files. + +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 -- 1.7.12.289.g0ce9864 From ff7aae08cbb0211e3a95fd77ed19e08b31d3044c Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 9 Sep 2012 21:49:42 +0200 Subject: [PATCH 2/3] build: handle @ALLOCA@-vs-non-recursive make problems Here is a good reason to avoid alloca with non-recursive make. These: $ grep @ALLOCA lib/gnulib.mk lib_libcoreutils_a_LIBADD += lib/@ALLOCA@ lib_libcoreutils_a_DEPENDENCIES += lib/@ALLOCA@ would lead to this, when @ALLOCA@ expands to the empty string, which is essentially "always", now: $ grep ' lib/$' Makefile lib_libcoreutils_a_LIBADD = $(gl_LIBOBJS) lib/ lib_libcoreutils_a_DEPENDENCIES = $(gl_LIBOBJS) lib/ Tell the prefix-adding script not to add a prefix when the word it's prefixing is "@ALLOCA@". That is fine for most cases, but what about when the expansion of @ALLOCA@ is nonempty? * build-aux/prefix-gnulib-mk (prefix_word): Exclude @ALLOCA@. * gl/m4/non-recursive-gnulib-prefix-hack.m4: Prefix non-empty $ALLOCA with "lib/". FIXME: I'm not sure this is required, now that we... Use AC_CONFIG_LIBOBJ_DIR([lib]). Without using AC_CONFIG_LIBOBJ_DIR([lib]), automake (not autoconf) would complain of failure to find aclocal.c, due to the use of AC_LIBSOURCES(alloca.c). --- gl/build-aux/prefix-gnulib-mk | 3 ++- gl/m4/non-recursive-gnulib-prefix-hack.m4 | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gl/build-aux/prefix-gnulib-mk b/gl/build-aux/prefix-gnulib-mk index cc74f51..38471a9 100755 --- a/gl/build-aux/prefix-gnulib-mk +++ b/gl/build-aux/prefix-gnulib-mk @@ -66,7 +66,8 @@ sub prefix_word ($) { local ($_) = @_; $_ = $prefix . $_ - unless /^-/ || m{^\$\(\w+\)} || $_ eq "Makefile" || $_ eq '\\'; + unless (/^-/ || m{^\$\(\w+\)} || $_ eq "Makefile" || $_ eq '\\' + || $_ eq '@ALLOCA@'); return $_; } diff --git a/gl/m4/non-recursive-gnulib-prefix-hack.m4 b/gl/m4/non-recursive-gnulib-prefix-hack.m4 index 3c5c48e..aeb0cc4 100644 --- a/gl/m4/non-recursive-gnulib-prefix-hack.m4 +++ b/gl/m4/non-recursive-gnulib-prefix-hack.m4 @@ -9,6 +9,9 @@ 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" @@ -26,4 +29,7 @@ AC_DEFUN([gl_NON_RECURSIVE_GNULIB_PREFIX_HACK], (*_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" ]) -- 1.7.12.289.g0ce9864 From 8860acb1f6014e96c76bb2a5dc10433e3f6ef03d Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 9 Sep 2012 08:21:16 +0200 Subject: [PATCH 3/3] maint: build lib/ using non-recursive make * bootstrap.conf (gnulib_modules): Use the new module. (bootstrap_post_import_hook): Invoke prefix-gnulib-mk. * configure.ac (AC_CONFIG_FILES): Remove lib/Makefile. * lib/Makefile.am: Renamed... * lib/local.mk: ...to this. * src/local.mk (CLEANFILES): Append, don't set. (noinst_LIBRARIES): Likewise. (AM_CPPFLAGS): Don't set this here. * Makefile.am (AM_CPPFLAGS): Define here instead. (noinst_LIBRARIES, CLEANFILES, MOSTLYCLEANDIRS, MOSTLYCLEANFILES): Initialize here, so we can append to them from each included local.mk (SUBDIRS): Remove "lib". --- Makefile.am | 10 +++++++++- bootstrap.conf | 5 +++++ configure.ac | 1 - lib/Makefile.am | 37 ------------------------------------- lib/local.mk | 5 +++++ src/local.mk | 6 ++---- 6 files changed, 21 insertions(+), 43 deletions(-) delete mode 100644 lib/Makefile.am create mode 100644 lib/local.mk diff --git a/Makefile.am b/Makefile.am index 384b9e9..dfbb591 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,7 +17,7 @@ ALL_RECURSIVE_TARGETS = -SUBDIRS = lib po . gnulib-tests +SUBDIRS = po . gnulib-tests changelog_etc = \ ChangeLog-2005 \ @@ -194,6 +194,14 @@ check-git-hook-script-sync: rm -rf $$t; \ test $$fail = 0 +noinst_LIBRARIES = +MOSTLYCLEANFILES = +CLEANFILES = +MOSTLYCLEANDIRS = + +AM_CPPFLAGS = -Ilib -I$(top_srcdir)/lib -Isrc -I$(top_srcdir)/src + +include $(top_srcdir)/lib/local.mk include $(top_srcdir)/src/local.mk include $(top_srcdir)/doc/local.mk include $(top_srcdir)/man/local.mk diff --git a/bootstrap.conf b/bootstrap.conf index 0658e1b..01c85f5 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -170,6 +170,7 @@ gnulib_modules=" mountlist mpsort netinet_in + non-recursive-gnulib-prefix-hack nproc obstack parse-datetime @@ -340,8 +341,12 @@ bootstrap_post_import_hook () && build-aux/gen-lists-of-programs.sh --automake >$tmp-2 \ && chmod a-w $tmp-1 $tmp-2 \ && mv -f $tmp-1 $m4f && mv -f $tmp-2 $mkf) + + # Massage lib/gnulib.mk before using it later in the bootstrapping process. + build-aux/prefix-gnulib-mk --lib-name=$gnulib_name lib/$gnulib_mk } + bootstrap_epilogue() { # Since this is a "GNU" package, replace this line diff --git a/configure.ac b/configure.ac index c6cd8b7..713a9b9 100644 --- a/configure.ac +++ b/configure.ac @@ -482,7 +482,6 @@ gt_LOCALE_FR AC_CONFIG_FILES( Makefile - lib/Makefile po/Makefile.in gnulib-tests/Makefile ) diff --git a/lib/Makefile.am b/lib/Makefile.am deleted file mode 100644 index 885f9b2..0000000 --- a/lib/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -## Makefile for gnulib/lib -*-Makefile-*- - -# Copyright (C) 1995-2012 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 -## 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 . - -AM_CFLAGS = -AM_CPPFLAGS = -BUILT_SOURCES = -CLEANFILES = -EXTRA_DIST = -MAINTAINERCLEANFILES = -MOSTLYCLEANDIRS = -MOSTLYCLEANFILES = -SUFFIXES = -noinst_LIBRARIES = - -include gnulib.mk - -AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) - -libcoreutils_a_SOURCES += \ - buffer-lcm.c buffer-lcm.h - -libcoreutils_a_LIBADD += $(LIBOBJS) -libcoreutils_a_DEPENDENCIES += $(LIBOBJS) diff --git a/lib/local.mk b/lib/local.mk new file mode 100644 index 0000000..decbad6 --- /dev/null +++ b/lib/local.mk @@ -0,0 +1,5 @@ +include lib/gnulib.mk + +# Allow "make distdir" to succeed before "make all" has run. +dist-hook: $(noinst_LIBRARIES) +.PHONY: dist-hook diff --git a/src/local.mk b/src/local.mk index 78e7743..0f9e000 100644 --- a/src/local.mk +++ b/src/local.mk @@ -65,16 +65,14 @@ EXTRA_DIST += \ src/extract-magic \ src/c99-to-c89.diff -CLEANFILES = $(SCRIPTS) +CLEANFILES += $(SCRIPTS) # Also remove these sometimes-built programs. # For example, even when excluded, they're built via 'sc_check-AUTHORS' # or 'dist'. CLEANFILES += $(no_install__progs) -AM_CPPFLAGS = -I$(top_srcdir)/lib -Isrc - -noinst_LIBRARIES = src/libver.a +noinst_LIBRARIES += src/libver.a nodist_src_libver_a_SOURCES = src/version.c src/version.h # Tell the linker to omit references to unused shared libraries. -- 1.7.12.289.g0ce9864