]> git.draconx.ca Git - cdecl99.git/commitdiff
Integrate Gnulib non-recursively.
authorNick Bowler <nbowler@draconx.ca>
Mon, 19 Sep 2011 01:46:14 +0000 (21:46 -0400)
committerNick Bowler <nbowler@draconx.ca>
Wed, 21 Sep 2011 23:25:09 +0000 (19:25 -0400)
With a little bit of mangling, it's possible to make the makefile
fragment produced by gnulib-tool suitable for use in our non-recursive
makefile.

Makefile.am
README
bootstrap
configure.ac
fix-gnulib.pl [new file with mode: 0755]
m4/.gitignore
m4/gnulib-cache.m4

index 094c3099a297c3189a32680d8b1a421795e03136..dcc43c60703dd5029d19851f44ebfc20120bdd23 100644 (file)
@@ -6,7 +6,11 @@
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = lib .
+# For Gnulib
+BUILT_SOURCES =
+MOSTLYCLEANFILES =
+noinst_LTLIBRARIES =
+
 AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src \
        -I$(top_builddir)/lib -I$(top_srcdir)/lib \
        -DBISON_LOCALEDIR=\"$(BISON_LOCALEDIR)\" \
@@ -36,7 +40,7 @@ libcdecl_la_LIBADD = $(LTLIBINTL) $(LTLIBTHREAD)
 
 bin_PROGRAMS = cdecl99
 cdecl99_SOURCES = src/cdecl99.c
-cdecl99_LDADD = libcdecl.la lib/libgnu.la
+cdecl99_LDADD = libcdecl.la libgnu.la
 
 src/parse.lo: src/scan.h
 src/scan.lo: src/parse.h
@@ -132,3 +136,5 @@ FLEX_V_0 = @echo "  FLEX  " $<;
                rm -f $<; \
                $(MAKE) $(AM_MAKEFLAGS) $<; \
        fi
+
+include $(top_srcdir)/lib/gnulib.mk
diff --git a/README b/README
index cdf8d05fee76e1156caa74fcd1613bd5055dfc3d..7781aae2b9e23d6cdf876db9378e0f6476b3f3c9 100644 (file)
--- a/README
+++ b/README
@@ -33,6 +33,11 @@ but older versions should not be expected to.
  * GNU Gettext version 0.18.1
  * GNU Bison version 2.4.3
  * flex version 2.5.35
+ * perl version 5.12
+
+Additionally, the following perl modules from CPAN are used:
+
+ * List::Compare version 0.37
 
 To generate the build system from Git, run the 'bootstrap' script in the
 top-level directory.  This will automatically check out the full Gnulib
index 94d0bc859e2739fe6fc495c9ff1214ba5c54dbf4..a9ad6714f4035790cea4e6d7bdc1723d2b0c8ddb 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -6,6 +6,7 @@ die() { printf '%s\n' "$@" 1>&2; kill -USR1 $$; }
 : ${AUTORECONF=autoreconf}
 : ${GNULIB=gnulib}
 : ${GIT=git}
+: ${PERL=perl}
 
 $GIT submodule update --init \
        || echo "Failed to update Gnulib sources from git."
@@ -16,4 +17,7 @@ else
        die "Gnulib sources are not properly installed in gnulib/."
 fi
 
+$PERL fix-gnulib.pl -o lib/gnulib.mk -i lib/gnulib.mk.in -m m4/fix-gnulib.m4 \
+       || die "Failed to fixup Gnulib makefile fragment."
+
 $AUTORECONF -fis
index 103bae2253fe0caa874c87fdadef91f958d32f23..50eaf75df4cc48a37264ce15d53f2f4a457d4920 100644 (file)
@@ -18,6 +18,8 @@ gl_EARLY
 LT_INIT
 gl_INIT
 
+DX_FIX_GNULIB
+
 dnl We provide our own makefile rules for gettext.  Disable tracing of
 dnl AM_GNU_GETTEXT to prevent autoreconf from running autopoint, and to
 dnl prevent automake from growing gratuitous error conditions.
@@ -35,7 +37,6 @@ AC_CHECK_PROGS([BISON], [bison], [bison])
 BISON_I18N
 
 AC_CONFIG_FILES([
-       lib/Makefile
        Makefile
 ])
 AC_OUTPUT
diff --git a/fix-gnulib.pl b/fix-gnulib.pl
new file mode 100755 (executable)
index 0000000..6663e6e
--- /dev/null
@@ -0,0 +1,154 @@
+#!/usr/bin/env perl
+#
+# Copyright © 2011 Nick Bowler
+#
+# Prepare the Gnulib tree for inclusion into a non-recursive automake build.
+#
+# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+# This is free software: you are free to do what the fuck you want to.
+# There is NO WARRANTY, to the extent permitted by law.
+
+use strict;
+use List::Compare;
+use Getopt::Long;
+
+my $output   = undef;
+my $input    = undef;
+my $m4output = undef;
+my $m4macro  = "DX_FIX_GNULIB";
+
+Getopt::Long::Configure("gnu_getopt", "no_auto_abbrev");
+GetOptions(
+       "o|output=s"   => \$output,
+       "i|input=s"    => \$input,
+       "m|m4output=s" => \$m4output,
+       "M|m4macro=s"  => \$m4macro,
+);
+
+open STDOUT, ">", $output or die "$output: $!\n" if (defined $output);
+open STDIN,  "<", $input  or die "$input: $!\n"  if (defined $input);
+
+my $printed_header = 0;
+my (%allvars, %sourcevars);
+
+sub drop {
+       undef $_;
+       next;
+}
+
+sub basename {
+       my $file = shift;
+       $file =~ m|(?:.+/)?([^/]+)/?|;
+       return $1;
+}
+
+sub mangle_file {
+       my $word = shift;
+
+       if ($word =~ /^\$\(([[:word:].]+)\)$/) {
+               # Don't touch variables now, but record them for later.
+               $sourcevars{$1} = 1;
+       } elsif ($word =~ /^\$\((?:top_)?(?:srcdir|builddir)\)/) {
+               # Do nothing.  Generic transformation will take care of
+               # $(srcdir) and $(builddir).
+       } elsif ($word =~ /^[[:word:].+\/-]+$/) {
+               # Fix up things that look like filenames.
+               $word = "lib/$word";
+       } else {
+               print STDERR "$0: warning: unrecognized source file: $word\n";
+       }
+
+       return "$word";
+}
+
+sub mangle_variable {
+       my $raw = shift;
+
+       $raw =~ /([^=]+=)[[:space:]]*(.*)/;
+       my ($left, @right) = ($1, split(/[[:space:]]+/, $2));
+
+       return join(" ", ($left, map(mangle_file($_), @right))) . "\n";
+}
+
+sub mangle_target {
+       my $raw = shift;
+
+       $raw =~ /([^:]+):[[:space:]]*(.*)/;
+       my @left  = split(/[[:space:]]+/, $1);
+       my @right = split(/[[:space:]]+/, $2);
+
+       @left  = map(mangle_file($_), @left);
+       @right = map(mangle_file($_), @right);
+
+       return join(" ", @left) . ": " . join(" ", @right) . "\n";
+}
+
+while (<STDIN>) {
+       next if (/^#/);
+
+       if (!$printed_header) {
+               print "# Postprocessed by ", basename($0), "\n";
+               $printed_header = 1;
+               drop;
+       }
+
+       # For some reason, gnulib-tool adds core dumps to "make mostlyclean".
+       # Since these files are (hopefully!) not created by make, they should
+       # not be cleaned.
+       drop if (/^MOSTLYCLEANFILES.*core/);
+
+       # Some modules set AM_CPPFLAGS/AM_CFLAGS/etc. in a manner that is not
+       # useful for non-recursive builds.  Strip them out.
+       drop if (/^(AM_CPPFLAGS|AM_CFLAGS)/);
+
+       # Rewrite automake hook targets to be more generic.
+       if (s/^(.*)-local:/\1-gnulib:/) {
+               print ".PHONY: $1-gnulib\n";
+               print "$1-local: $1-gnulib\n";
+               s/$1-generic//;
+
+               # Don't let these targets get confused with filenames below.
+               next;
+       }
+
+       # We need to mangle filenames in make variables; prepending a lib/ on
+       # relative paths.  The following should catch all variable assignments
+       # that need mangling.
+       if (/^([[:word:]]+)[[:space:]]*\+?=/) {
+               $allvars{$1} = 1;
+
+               if (/_SOURCES|CLEANFILES|EXTRA_DIST|[[:upper:]]+_H/) {
+                       $_ = mangle_variable($_);
+               }
+       }
+
+       # Targets are similar to variables: the target and its dependencies
+       # need to be mangled.
+       if (/:/) {
+               $_ = mangle_target($_);
+       }
+
+       # Finally, references to $(srcdir) and $(builddir) need to be fixed up.
+       s:\$\(srcdir\):\$\(top_srcdir\)/lib:g;
+       s:\$\(builddir\):\$\(top_builddir\)/lib:g;
+} continue { print };
+
+# Some filenames are AC_SUBSTed by the Gnulib macros, and thus we need to
+# prepend lib/ if and only if they're not empty.  Unfortunately, make is not
+# powerful to do this, so we need to put this transformation into configure
+# itself by defining a new autoconf macro.
+if (defined $m4output) {
+       my $lc = List::Compare->new('-u', '-a', \%sourcevars, \%allvars);
+       my @vars = $lc->get_unique;
+
+       open(M4OUT, '>', $m4output) or die "$m4output: $!\n";
+
+       print M4OUT "dnl This file was generated by fix-gnulib.pl\n";
+       print M4OUT "AC_DEFUN([$m4macro], [dnl\n";
+       foreach (@vars) {
+               print M4OUT "$_=\${$_:+lib/\$$_}\n";
+       }
+       print M4OUT "])\n";
+
+       close M4OUT;
+}
index c23c58be18b5385b9110d22abb07748d82c64b9c..14287ab6a99a215c80d82da74ad56d0d4c781eec 100644 (file)
@@ -3,6 +3,7 @@ codeset.m4
 errno_h.m4
 extensions.m4
 fcntl-o.m4
+fix-gnulib.m4
 getdelim.m4
 getline.m4
 getopt.m4
index 6acb89f9d2aa6b4d8e469deab9e11ad809521c71..09fc0cdee865e5cbfabd209b4662dd5042b1df4d 100644 (file)
@@ -15,7 +15,7 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --conditional-dependencies --libtool --macro-prefix=gl --no-vc-files getopt-gnu gettext lock readline
+#   gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk.in --conditional-dependencies --libtool --macro-prefix=gl --no-vc-files getopt-gnu gettext lock readline
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
@@ -32,7 +32,7 @@ gl_PO_BASE([])
 gl_DOC_BASE([doc])
 gl_TESTS_BASE([tests])
 gl_LIB([libgnu])
-gl_MAKEFILE_NAME([])
+gl_MAKEFILE_NAME([gnulib.mk.in])
 gl_CONDITIONAL_DEPENDENCIES
 gl_LIBTOOL
 gl_MACRO_PREFIX([gl])