]> git.draconx.ca Git - dxcommon.git/blobdiff - scripts/fix-gnulib.pl
Import getline helper from cdecl99.
[dxcommon.git] / scripts / fix-gnulib.pl
index a59e4a6e3d66b1eab748754fc33b6d5eba3349f8..9a1f2731c24f477d9e37d8a83ac065ca0c8121c5 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# Copyright © 2011-2014, 2020-2021 Nick Bowler
+# Copyright © 2011-2014, 2020-2023 Nick Bowler
 #
 # Prepare the Gnulib tree for inclusion into a non-recursive automake build.
 # While the output of gnulib-tool is "include"-able if the --makefile-name
@@ -71,6 +71,13 @@ my @cleanfiles;
 # the value is always set to 1.
 my (%allvars, %sourcevars);
 
+# Collected names of subdirectories that may need to be created at build time.
+# The keys are directory names, the values are targets.
+my %gl_dirstamps;
+
+# State to drop MKDIR_P lines that have been replaced by dirstamps.
+my ($have_dirstamp) = (0);
+
 sub drop {
        undef $_;
        next;
@@ -122,7 +129,21 @@ sub mangle_target {
        @left  = map(mangle_file($_), @left);
        @right = map(mangle_file($_), @right);
 
-       return join(" ", @left) . ": " . join(" ", @right) . "\n";
+       my @dirstamps = get_dirstamps(@left);
+
+       return join(" ", @left) . ": " . join(" ", @dirstamps, @right) . "\n";
+}
+
+sub get_dirstamps {
+       my %h;
+
+       foreach (@_) {
+               next unless $_[0] =~ m|^(lib(/.*)?)/[^/]*$|;
+
+               $h{$gl_dirstamps{$1} = "$1/\$(am__dirstamp)"} = 1;
+       }
+
+       return keys %h;
 }
 
 while (<STDIN>) {
@@ -145,7 +166,7 @@ m4_unquote(m4_argn([2], [
 
 # This trick should define gnulib_orderonly to | iff we're using GNU make.
 gnulib_make_features = $(.FEATURES)
-gnulib_have_orderonly = $(findstring order-only,$(gnulib_make_features))
+gnulib_have_orderonly = $(findstring order-only,${gnulib_make_features})
 gnulib_orderonly = $(gnulib_have_orderonly:order-only=|)
 gnulib_core_headers =
 gnulib_raw_headers = $(gnulib_core_headers)
@@ -168,12 +189,12 @@ EOF
        # something actually depends on it (which is typically the case).
        if (/^noinst_LIBRARIES.*libgnu.a/) {
                s/^noinst/EXTRA/;
-               $for_library //= 0;
+               $for_library = 0 unless defined $for_library;
                $use_libtool = 0;
        }
        if (/^noinst_LTLIBRARIES.*libgnu.la/) {
                s/^noinst/EXTRA/;
-               $for_library //= 1;
+               $for_library = 1 unless defined $for_library;
                $use_libtool = 1;
        }
 
@@ -186,6 +207,16 @@ EOF
        # useful for non-recursive builds.  Strip them out.
        drop if (/^(AM_CPPFLAGS|AM_CFLAGS)/);
 
+       # We don't care about upstream warning flags that just result in adding
+       # massive amounts of additional build rules for no reason.
+       if (/_CFLAGS/) {
+               s/ *\$\(GL_CFLAG_GNULIB_WARNINGS\)// if /_CFLAGS\s*=/;
+       }
+
+       # Drop superfluous CFLAGS assignments (which may be created by above
+       # transformation).
+       drop if /_CFLAGS\s*=\s*\$\(AM_CFLAGS\)\s*$/;
+
        # Library dependencies are added automatically to libgnu.la by
        # gnulib-tool.  Unfortunately, this means that everything linking
        # against libgnu.la is forced to pull in the same deps, even if they're
@@ -211,7 +242,7 @@ EOF
        if (/^([[:word:]]+)[[:space:]]*\+?=/) {
                $allvars{$1} = 1;
 
-               if (/_SOURCES|CLEANFILES|EXTRA_DIST|[[:upper:]]+_H/) {
+               if ($1 =~ /(_SOURCES|CLEANFILES|EXTRA_DIST|[[:upper:]]+_H)$/) {
                        $_ = mangle_variable($_);
                }
        }
@@ -223,8 +254,9 @@ EOF
 
        # Targets are similar to variables: the target and its dependencies
        # need to be mangled.
-       if (/^[^\t].*:/) {
+       if (/^([^\t:]*):/) {
                $_ = mangle_target($_);
+               $have_dirstamp = /am__dirstamp/;
        }
 
        # MKDIR_P commands need to be fixed up; in principle Gnulib could also
@@ -246,18 +278,37 @@ EOF
        # component.
        s/t-\$@/\$\@-t/g;
 
-       # Finally, references to $(srcdir) and $(builddir) need to be fixed up.
+       # $(srcdir), $(builddir) and %reldir% need to be fixed up.
        s:\$\(srcdir\):\$\(top_srcdir\)/lib:g;
        s:\$\(builddir\):\$\(top_builddir\)/lib:g;
+       s:%reldir%:lib:g;
+
+       # If we installed a dirstamp prerequisite for this target, don't
+       # emit the mkdir line which creates the output directory.
+       if ($have_dirstamp && m|\$[({]MKDIR_P[})][ '"]*lib/|) {
+               drop unless s/^(\t\$[({](AM_V_GEN|gl_V_at)[})]).*/\1:/;
+       }
+       undef $have_dirstamp if /^\t/;
 } continue { s/(\n.)/\\\1/g; print; };
 
+# Define a bunch of fake programs which will ensure Automake produces the
+# necessary dirstamp rules, as unfortunately we cannot know in advance which
+# will be generated, and the usual Automake behaviour where generated rules
+# are suppressed by rules in Makefile.am doesn't actaully work for these.
+print <<EOF foreach (keys %gl_dirstamps);
+EXTRA_PROGRAMS += $_/gl-dirstamp
+${\(y|/|_|r)}_gl_dirstamp_SOURCES =
+EOF
+
 print <<'EOF' if ($use_libtool);
 gnulib_lt_objects = $(libgnu_la_OBJECTS) $(gl_LTLIBOBJS)
 gnulib_objects = $(gnulib_lt_objects)
+gnulib_all_symfiles = $(gnulib_lt_objects:.lo=.glsym)
 $(gnulib_objects): $(gnulib_headers)
 EOF
 print <<'EOF' if (!$use_libtool);
 gnulib_objects = $(libgnu_a_OBJECTS) $(gl_LIBOBJS)
+gnulib_all_symfiles = $(gnulib_objects:.@OBJEXT@=.glsym)
 $(gnulib_objects): $(gnulib_headers)
 EOF
 
@@ -270,10 +321,10 @@ if FALSE
 AC_SUBST([GLSRC], [lib])
 AC_CONFIG_LIBOBJ_DIR([lib])
 
-AC_DEFUN_ONCE([DX_GLSYM_PREFIX], [dnl
-AC_REQUIRE([DX_EXPORTED_SH])
-AC_SUBST([GLSYM_PREFIX], [$1])
-])
+AC_DEFUN_ONCE([DX_GLSYM_PREFIX],
+[AC_REQUIRE([DX_AUTOMAKE_COMPAT])AC_REQUIRE([DX_EXPORTED_SH])dnl
+AC_SUBST([GLSYM_PREFIX], [$1])dnl
+AC_SUBST([gnulib_symfiles], ['$(gnulib_all_symfiles)'])])
 EOF
 
 print <<'EOF' if ($for_library);