automake-ng
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Automake-NG] [FYI] [ng] automake: allow user to pass Makefile content (


From: Stefano Lattarini
Subject: [Automake-NG] [FYI] [ng] automake: allow user to pass Makefile content (mostly) unprocessed
Date: Tue, 22 May 2012 11:19:53 +0200

All the lines starting with a '!' character are now passed unprocessed
(apart from the stripping of that leading character) into the generated
Makefile.in, and placed between the variables' definitions and the
Makefile targets and recipes.  This will provide the users wanting to
use more advanced GNU make features (like the 'ifeq' or 'define'
builtins) with a mean to do so, without automake pre-processing getting
in the way.  More importantly, this will provide us with a way to do
so in out internal .am fragments ;-)

This is basically just a quick hack to allow us to implement some further
refactorings, and to move yet more logic and processing from the Automake
script to the generated Makefiles.  Still, it's an unobtrusive and easy
to implement hack, so there will be no problem in ripping it out if it
turns out to be a bad idea.

* automake.in ($output_verbatim): New global variable.
(initialize_per_input): Reset it.
(read_am_file, file_contents_internal): When a line starting with "!" is
read, append its content to the '$output_verbatim', and do no further
processing on it.
* t/verbatim.sh: New test.

Signed-off-by: Stefano Lattarini <address@hidden>
---
 automake.in   |   53 ++++++++++++++++------
 t/verbatim.sh |  141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 180 insertions(+), 14 deletions(-)
 create mode 100755 t/verbatim.sh

diff --git a/automake.in b/automake.in
index 7596ada..7b0ac7a 100644
--- a/automake.in
+++ b/automake.in
@@ -528,6 +528,7 @@ my $output_deps_greatest_timestamp;
 # They hold the Makefile.in until it is ready to be printed.
 my $output_vars;
 my $output_header;
+my $output_verbatim;
 my $output_rules;
 my $output_trailer;
 
@@ -661,6 +662,7 @@ sub initialize_per_input ()
 
     $output_vars = '';
     $output_header = '';
+    $output_verbatim = '';
     $output_rules = '';
     $output_trailer = '';
 
@@ -6285,14 +6287,23 @@ sub read_am_file ($$)
     my $last_var_value = '';
     my $last_where;
     # FIXME: shouldn't use $_ in this loop; it is too big.
-    while ($_)
-    {
+    for (; defined $_; $_ = $am_file->getline)
+      {
        $where->set ("$amfile:$.");
 
        # Make sure the line is \n-terminated.
        chomp;
        $_ .= "\n";
 
+       if (s/^!//)
+         {
+           # A line starting with '!' must be passed verbatim to the
+           # output Makefile, placed after the variables' definitions
+           # and before the Makefile targets.
+           $output_verbatim .= $_;
+           next;
+         }
+
        # Don't look at MAINTAINER_MODE_TRUE here.  That shouldn't be
        # used by users.  @MAINT@ is an anachronism now.
        $_ =~ s/address@hidden@//g
@@ -6474,7 +6485,6 @@ sub read_am_file ($$)
        }
 
        $saw_bk = $new_saw_bk;
-       $_ = $am_file->getline;
     }
 
     $output_trailer .= $comment;
@@ -6759,24 +6769,36 @@ sub file_contents_internal ($$$%)
        # FIXME: no line number available.
        $where->set ($file);
 
+        # A line starting with '!' must be passed verbatim to the output
+        # Makefile, placed after the variables' definitions and before the
+        # Makefile targets.
+        if (s/^!//)
+          {
+            $output_verbatim .= "$_\n";
+          }
+
        # Sanity checks.
-       error $where, "blank line following trailing backslash:\n$_"
-         if /\\$/;
-       error $where, "comment following trailing backslash:\n$_"
-         if /\\#/;
+       elsif (/\\$/)
+          {
+           error $where, "blank line following trailing backslash:\n$_"
+          }
+       elsif (/\\#/)
+          {
+           error $where, "comment following trailing backslash:\n$_"
+          }
 
-       if (/^$/)
-       {
+       elsif (/^$/)
+         {
            $is_rule = 0;
            # Stick empty line before the incoming macro or rule.
            $spacing = "\n";
-       }
+         }
        elsif (/$COMMENT_PATTERN/mso)
-       {
+         {
            $is_rule = 0;
            # Stick comments before the incoming macro or rule.
            $comment = "$_\n";
-       }
+         }
 
        # Handle inclusion of other files.
        elsif (/$INCLUDE_PATTERN/o)
@@ -7829,8 +7851,11 @@ sub generate_makefile ($$)
   mkdir ($am_relative_dir, 0755) if ! -d $am_relative_dir;
 
   # We make sure that 'all:' is the first target.
-  my $output =
-    "$output_vars$output_header$output_rules$output_trailer";
+  my $output = $output_vars .
+               $output_header .
+               $output_verbatim .
+               $output_rules .
+               $output_trailer;
 
   # Decide whether we must update the output file or not.
   # We have to update in the following situations.
diff --git a/t/verbatim.sh b/t/verbatim.sh
new file mode 100755
index 0000000..44151d9
--- /dev/null
+++ b/t/verbatim.sh
@@ -0,0 +1,141 @@
+#! /bin/sh
+# Copyright (C) 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 2, 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 <http://www.gnu.org/licenses/>.
+
+# A line starting with '!' is passed verbatim to the output Makefile,
+# and in the right place too.
+
+. ./defs || Exit 1
+
+cat >> configure.ac << 'END'
+AC_CONFIG_FILES([Makefile2 Makefile3])
+AC_OUTPUT
+END
+
+long1=long
+long2="$long1 $long1"
+long4="$long2 $long2"
+long8="$long4 $long4"
+long16="$long8 $long8"
+long32="$long16 $long16"
+long64="$long32 $long32"
+long128="$long64 $long64"
+long256="$long128 $long128"
+long512="$long256 $long265"
+
+# Sanity check.
+case $long512 in
+  *' long long '*) ;;
+  *) fatal_ 'defining $long512' ;;
+esac
+
+cat > Makefile.am << END
+!x = $long256
+!!unmodified!
+!## unmodified
+! foo = \
+rule:
+END
+
+cat > Makefile2.am << 'END'
+!badrule1: ; @echo "'$@' unexpectedly won over 'all'!"; exit 1
+!badrule2:
+!      @echo "'$@' unexpectedly won over 'all'!"; exit 1
+all-local: verbatim-rule
+       test -f $<.ok
+!verbatim-rule:
+!ifeq (ok,ok)
+!      @echo $@ run correctly
+!      : > address@hidden
+!else
+!      echo $@ failure; exit 1
+!endif
+# We want this deliberately after verbatim-rule.
+x = ok
+END
+
+cat > Makefile3.am << 'END'
+x1 := 1
+x2 := 2
+
+foo = .
+
+!ifndef FOO
+!foo += $(x1)
+!else
+!foo += $(x2)
+!endif
+
+!ifeq ($(BAR),1)
+!bar = aaa
+!else
+!ifeq "$(BAR)" "2"
+!bar = lol
+!else
+!bar = default
+!endif # this comment should be comment ignored
+!endif
+
+check-var:
+       test '$($(var))' = '$(val)'
+END
+
+# Avoid interferences from the environment.
+FOO= BAR=; unset FOO BAR
+
+$ACLOCAL
+$AUTOMAKE
+
+grep '^!' Makefile.in | grep -v '^!unmodified!$' && Exit 1
+grep '^!' Makefile[23].in && Exit 1
+
+# Use perl, to avoid possible issues with regex length in vendor greps.
+$PERL -e "
+  while (<>) { exit 0 if (/^x = $long256$/); }
+  exit 1;
+" Makefile.in
+
+grep '^!unmodified!$' Makefile.in
+grep '^## unmodified$' Makefile.in
+# FIXME: automake is not yet smart enough to handle line continuation
+# FIXME: on the last line of a '!' series correctly.
+#grep '^ foo = \\$' Makefile.in
+
+$EGREP 'foo|bar' Makefile3.in # For debugging.
+test `grep -c '^foo +=' Makefile3.in` -eq 2
+test `grep -c '^bar =' Makefile3.in` -eq 3
+
+$AUTOCONF
+./configure
+
+# FIXME: automake is not yet smart enough to handle line continuation
+# FIXME: on the last line of a '!' series correctly.
+#grep '^ foo = \\$' Makefile.in
+#$MAKE rule
+
+$MAKE -f Makefile2
+test -f verbatim-rule.ok
+
+$MAKE -f Makefile3 check-var var=foo val='. 1'
+$MAKE -f Makefile3 check-var var=foo val='. 1' FOO=''
+$MAKE -f Makefile3 check-var var=foo val='. 2' FOO=yes
+$MAKE -f Makefile3 check-var var=foo val='. 2' FOO=' who cares!'
+
+$MAKE -f Makefile3 check-var var=bar val=default
+$MAKE -f Makefile3 check-var var=bar val=aaa     BAR=1
+$MAKE -f Makefile3 check-var var=bar val=lol     BAR=2
+$MAKE -f Makefile3 check-var var=bar val=default BAR=3
+
+:
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]