automake
[Top][All Lists]
Advanced

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

RE: monolithic Makefile.am


From: Robert Collins
Subject: RE: monolithic Makefile.am
Date: Sun, 12 May 2002 13:42:28 +1000

> -----Original Message-----
> From: Tom Tromey [mailto:address@hidden 
> Sent: Sunday, May 12, 2002 9:15 AM
> To: Robert Collins
> Cc: Richard Boulton; Harlan Stenn; Automake
> Subject: Re: monolithic Makefile.am
> 
> 
> >>>>> "Rob" == Robert Collins <address@hidden> writes:
> 
>
> I looked at this.  I think it is missing one of the major 
> features I'd like out from `import', namely the ability to 
> have targets like `subdir/clean' and `subdir/all'.

Are targets like 
foo/all:
portable?

Emitting 
foo_all:
would be trivial.

Emitting foo/all: may be more difficult, I really don't know.

I've update the patch to be against 1.6, and to emit
foo_bar_SOURCES: 
for the rule
bar_SOURCES = 
in a subdir Makefile.rules.
 
> I think doing this requires the bulk of the work, since it 
> means a lot of code generation changes in automake.  I'd be 
> delighted to be proven wrong :-)

--- ../automake-1.6/automake.in Wed Mar  6 15:46:14 2002
+++ automake.in Sun May 12 13:34:00 2002
@@ -157,6 +157,11 @@ my $INCLUDE_PATTERN = ('^include\s+'
                       . '|(\$\(srcdir\)/' . $PATH_PATTERN . ')'
                       . '|([^/\$]' . $PATH_PATTERN. '))\s*(#.*)?$');
 
+my $SUBDIR_INCLUDE_PATTERN = ('^subdir_include\s+'
+                       . '((\$\(top_srcdir\)/' . $PATH_PATTERN . ')'
+                      . '|(\$\(srcdir\)/' . $PATH_PATTERN . ')'
+                      . '|([^/\$]' . $PATH_PATTERN. '))\s*(#.*)?$');
+
 # Some regular expressions.  One reason to put them here is that it
 # makes indentation work better in Emacs.
 my $AC_CONFIG_AUX_DIR_PATTERN = 'AC_CONFIG_AUX_DIR\(([^)]+)\)';
@@ -208,7 +213,7 @@ my @common_files =
        ansi2knr.1 ansi2knr.c compile config.guess config.rpath
config.sub
        configure configure.ac configure.in depcomp elisp-comp
        install-sh libversion.in mdate-sh missing mkinstalldirs
-       py-compile texinfo.tex ylwrap),
+       py-compile texinfo.tex ylwrap Makefile.rules),
      @libtool_files, @libtool_sometimes);
 
 # Commonly used files we auto-include, but only sometimes.
@@ -2121,6 +2126,39 @@ sub handle_single_transform_list ($$$$@)
     return @result;
 }
 
+# $VALUE
+# transform_file_list ($PREPEND, @FILES)
+# ----------------------------------------
+# insert $PREPEND before every file path that is not absolute
+#
+sub transform_file_list ($$)
+{
+      my ($prepend, $tmpfiles) = @_;
+      my $result = "";
+      my @files = ();
+      @files = split(/ /, $tmpfiles); 
+      while (scalar @files > 0)
+      {
+       $_ = shift @files;
+
+       if ($_ =~ s/^\$\(top_srcdir\)\///)
+         {
+           $result .= " \$\(top_srcdir\)\/" . $_;
+         }
+         elsif ( $_ =~ s/^\$\(srcdir\)\///)
+         {
+           $result .= " \$\(srcdir\)\/$prepend" . $_;
+         }
+         else
+         {
+           $result .= " $prepend" . $_;
+         }
+      }
+       print "result:$result\n";
+      return $result . "\n";
+}
+         
+
 # $BOOL
 # define_objects_from_sources ($VAR, $OBJVAR, $NODEFINE, $ONE_FILE,
 #                              $OBJ, $PARENT, $TOPPARENT)
@@ -2223,6 +2261,8 @@ sub define_objects_from_sources ($$$$$$$
 }
 
 
+
+
 # $OBJNAME
 # subobjname ($VARNAME)
 # ---------------------
@@ -2889,7 +2929,7 @@ sub handle_ltlibraries
        # Canonicalize names and check for misspellings.
        my $xlib = &check_canonical_spelling ($onelib, '_LIBADD',
'_LDFLAGS',
                                              '_SOURCES', '_OBJECTS',
-                                             '_DEPENDENCIES');
+                                             '_DEPENDENCIES',
'_CFLAGS');
 
        if (! variable_defined ($xlib . '_LDFLAGS'))
        {
@@ -2897,6 +2937,19 @@ sub handle_ltlibraries
            &define_variable ($xlib . '_LDFLAGS', '');
        }
 
+       # Tell the source code what library we are building
+#      my $tempvariable = '';
+#      if ( &variable_defined ($xlib . '_CFLAGS'))
+#      {
+#          # Define the lib_CFLAGS variable.
+#          $tempvariable .= &variable_value ($xlib . '_CFLAGS');
+#          &variable_delete ($xlib . '_CFLAGS');
+#      }
+#      my $libname_short = $xlib;
+#      $libname_short =~ s/_la$//  ;
+#      $libname_short = uc ($libname_short);
+#      &define_variable ($xlib . '_CFLAGS', ' -D' . $libname_short .
'_COMPILATION ' . $tempvariable);
+
        # Check that the library fits the standard naming convention.
        my $libname_rx = "^lib.*\.la";
        if ((variable_defined ($xlib . '_LDFLAGS')
@@ -6887,6 +6940,297 @@ sub target_defined
     return defined $targets{$target};
 }
 
+################################################################
+
+# Read Makefile.am and set up %contents.  Simultaneously copy lines
+# from Makefile.am into $output_trailer or $output_vars as
+# appropriate.  NOTE we put rules in the trailer section.  We want
+# user rules to come after our generated stuff.
+#
+# This version translates the file on-the-fly, prepending the leading
path to all targets
+
+sub read_am_file_translate
+{
+    my ($amfile, $prepend) = @_;
+
+    my $prepend_macro = $prepend;
+    $prepend_macro =~ s/\//_/;
+
+    my $am_file = new IO::File ("< $amfile");
+    if (! $am_file)
+    {
+        die "$me: couldn't open `$amfile': $!\n";
+    }
+    print "$me: reading $amfile with translation path $prepend\n" if
$verbose;
+
+    my $spacing = '';
+    my $comment = '';
+    my $blank = 0;
+
+    while ($_ = $am_file->getline)
+    {
+        if (/$IGNORE_PATTERN/o)
+        {
+            # Merely delete comments beginning with two hashes.
+        }
+        elsif (/$WHITE_PATTERN/o)
+        {
+            # Stick a single white line before the incoming macro or
rule.
+            $spacing = "\n";
+            $blank = 1;
+        }
+        elsif (/$COMMENT_PATTERN/o)
+        {
+            # Stick comments before the incoming macro or rule.  Make
+            # sure a blank line preceeds first block of comments.
+            $spacing = "\n" unless $blank;
+            $blank = 1;
+            $comment .= $spacing . $_;
+            $spacing = '';
+        }
+        else
+        {
+            last;
+        }
+    }
+
+    $output_vars .= $comment . "\n";
+    $comment = '';
+    $spacing = "\n";
+
+    # We save the conditional stack on entry, and then check to make
+    # sure it is the same on exit.  This lets us conditonally include
+    # other files.
+    my @saved_cond_stack = @cond_stack;
+    my $cond = conditional_string (@cond_stack);
+
+    my $saw_bk = 0;
+    my $was_rule = 0;
+    my $last_var_name = '';
+    my $last_var_type = '';
+    my $last_var_value = '';
+    # FIXME: shouldn't use $_ in this loop; it is too big.
+    while ($_)
+    {
+        $_ .= "\n"
+            unless substr ($_, -1, 1) eq "\n";
+
+        # Don't look at MAINTAINER_MODE_TRUE here.  That shouldn't be
+        # used by users.  @MAINT@ is an anachronism now.
+        $_ =~ s/address@hidden@//g
+            unless $seen_maint_mode;
+
+        my $new_saw_bk = /\\$/ && ! /$COMMENT_PATTERN/o;
+
+        if (/$IGNORE_PATTERN/o)
+        {
+            # Merely delete comments beginning with two hashes.
+        }
+        elsif (/$WHITE_PATTERN/o)
+        {
+            # Stick a single white line before the incoming macro or
rule.
+            $spacing = "\n";
+            &am_line_error ($., "blank line following trailing
backslash")
+                if $saw_bk;
+        }
+        elsif (/$COMMENT_PATTERN/o)
+        {
+            # Stick comments before the incoming macro or rule.
+            $comment .= $spacing . $_;
+            $spacing = '';
+            &am_line_error ($., "comment following trailing backslash")
+                if $saw_bk;
+        }
+        elsif ($saw_bk)
+        {
+            if ($was_rule)
+            {
+                $output_trailer .= &make_condition (@cond_stack);
+                $output_trailer .= $_;
+               #unhandled yet
+               &am_error ("can't translate saw-bk, was_rule, $_");
+            }
+            else
+            {
+              $last_var_value .= ' '
+                unless $last_var_value =~ /\s$/;
+              $last_var_value .= $_;
+
+              if (!/\\$/)
+                {
+                  $var_comment{$last_var_name} .= "$spacing"
+                    if (!defined $var_comment{$last_var_name}
+                        || substr ($var_comment{$last_var_name}, -1) ne
"\n");
+                  $var_comment{$last_var_name} .= "$comment";
+                  $comment = $spacing = '';
+                  macro_define ($last_var_name, 0,
+                                $last_var_type, $cond,
+                                $last_var_value, $.)
+                    if $cond ne 'FALSE';
+                  push (@var_list, $last_var_name);
+                 &am_error ("pushlist $last_var_name,
$last_var_value");
+                }
+            }
+        }
+
+        elsif (/$IF_PATTERN/o)
+          {
+            $cond = cond_stack_if ($1, $2, "$amfile:$.");
+          }
+        elsif (/$ELSE_PATTERN/o)
+          {
+            $cond = cond_stack_else ($1, $2, "$amfile:$.");
+          }
+        elsif (/$ENDIF_PATTERN/o)
+          {
+            $cond = cond_stack_endif ($1, $2, "$amfile:$.");
+          }
+
+        elsif (/$RULE_PATTERN/o)
+        {
+            # Found a rule.
+            $was_rule = 1;
+
+            rule_define ($1, 0, $cond, $.);
+           &am_error ("rule define $1");
+
+#$var_line{$1} = $.;
+            $output_trailer .= $comment . $spacing;
+            $output_trailer .= &make_condition (@cond_stack);
+            $output_trailer .= $_;
+            $comment = $spacing = '';
+        }
+        elsif (/$ASSIGNMENT_PATTERN/o)
+        {
+            # Found a macro definition.
+           # Q: when do we translate macro's?
+            $was_rule = 0;
+            $last_var_name = $1;
+            $last_var_type = $2;
+            $last_var_value = $3;
+           # TODO: translate every element in value
+            if ($3 ne '' && substr ($3, -1) eq "\\")
+            {
+                # We preserve the `\' because otherwise the long lines
+                # that are generated will be truncated by broken
+                # `sed's.
+                $last_var_value = $3 . "\n";
+            }
+
+            if (!/\\$/)
+              {
+                # FIXME: this doesn't always work correctly; it will
+                # group all comments for a given variable, no matter
+                # where defined.
+                # Accumulating variables must not be output.
+                $var_comment{$last_var_name} .= "$spacing"
+                  if (!defined $var_comment{$last_var_name}
+                      || substr ($var_comment{$last_var_name}, -1) ne
"\n");
+                $var_comment{$last_var_name} .= "$comment";
+                $comment = $spacing = '';
+
+               # add this definition to the global list
+               #macro_define ($last_var_name, 1, '+', $cond,
+               #             $last_var_value, $.) if $cond ne 'FALSE';
+
+               # transform the macro name. PROGRAMS etc transform the
value, 
+               # Sources etc transform the name and the value.
+
+               # TODO: fixup every element in the macro
+               if (substr($last_var_name, -7) eq "SOURCES" )
+               {
+                 macro_define ("$prepend_macro$last_var_name", 0,
+                       $last_var_type, $cond,
+                       &transform_file_list($prepend, $last_var_value),
$.)
+                  if $cond ne 'FALSE';
+                  push (@var_list, "$prepend_macro$last_var_name");
+               }
+               else
+               {
+
+                macro_define ("$last_var_name", 0,
+                              $last_var_type, $cond,
+                              "$prepend_macro$last_var_value", $.)
+                  if $cond ne 'FALSE';
+                push (@var_list, "$last_var_name");
+               }
+               print "pushlist 2
$prepend_macro$last_var_name,$last_var_type,$prepend_macro$last_var_valu
e\n";
+                                 
+              }
+        }
+        elsif (/$INCLUDE_PATTERN/o)
+        {
+           # should included includes be translated?
+            my $path = $1;
+
+            if ($path =~ s/^\$\(top_srcdir\)\///)
+            {
+                push (@include_stack, "\$\(top_srcdir\)/$path");
+            }
+            else
+            {
+                $path =~ s/\$\(srcdir\)\///;
+                push (@include_stack, "\$\(srcdir\)/$path");
+                $path = $relative_dir . "/" . $prepend . $path;
+            }
+            &read_am_file ($path);
+        }
+        elsif (/$SUBDIR_INCLUDE_PATTERN/o)
+        {
+            my $path = $1;
+            my $prepend_path = "";
+
+            if ($path =~ s/^\$\(top_srcdir\)\///)
+            {
+                # the same stack used, as all it does is let us add a
dependency for Makefile.am
+                push (@include_stack, "\$\(top_srcdir\)/$path");
+                &am_error ("attempt to translate a top_srcdir include
file: $path");
+            }
+            else
+            {
+                $path =~ s/\$\(srcdir\)\///;
+                push (@include_stack, "\$\(srcdir\)/$path");
+                $prepend_path = $path;
+                $prepend_path =~ s/[^\/]*$//;
+               $prepend_path = $prepend . $prepend_path;
+                $path = $relative_dir . "/" . $prepend . $path;
+            }
+            &read_am_file_translate ($path, $prepend_path);
+        }
+        else
+        {
+            # This isn't an error; it is probably a continued rule.
+            # In fact, this is what we assume.
+            $was_rule = 1;
+            $output_trailer .= $comment . $spacing;
+            $output_trailer .= &make_condition  (@cond_stack);
+            $output_trailer .= $_;
+            $comment = $spacing = '';
+            &am_line_error ($., "`#' comment at start of rule is
unportable")
+                if $_ =~ /^\t\s*\#/;
+        }
+
+        $saw_bk = $new_saw_bk;
+        $_ = $am_file->getline;
+    }
+
+    $output_trailer .= $comment;
+
+    if (join (' ', @saved_cond_stack) ne join (' ', @cond_stack))
+    {
+        if (@cond_stack)
+        {
+            &am_error ("unterminated conditionals: @cond_stack");
+        }
+        else
+        {
+            # FIXME: better error message here.
+            &am_error ("conditionals not nested in include file");
+        }
+    }
+}
+
+      
 
 ################################################################
 
@@ -7101,6 +7445,27 @@ sub read_am_file ($)
             }
             &read_am_file ($path);
         }
+       elsif (/$SUBDIR_INCLUDE_PATTERN/o)
+       {
+           my $path = $1;
+           my $prepend_path = "";
+
+           if ($path =~ s/^\$\(top_srcdir\)\///)
+           {
+               # the same stack used, as all it does is let us add a
dependency for Makefile.am
+               push (@include_stack, "\$\(top_srcdir\)/$path");
+               &am_error ("attempt to translate a top_srcdir include
file: $path");
+           }
+           else
+           {
+               $path =~ s/\$\(srcdir\)\///;
+                push (@include_stack, "\$\(srcdir\)/$path");
+               $prepend_path = $path;
+               $prepend_path =~ s/[^\/]*$//;
+                $path = $relative_dir . "/" . $path;
+            }
+            &read_am_file_translate ($path, $prepend_path);
+       }
        else
         {
            # This isn't an error; it is probably a continued rule.
@@ -7376,7 +7741,22 @@ sub file_contents_internal ($$%)
              }
         }
 
-        # Handling the conditionals.
+# library files aren't allowed this directive. # Handle path translated
inclusion of other files.
+#      elsif (/$SUBDIR_INCLUDE_PATTERN/o)
+#       {
+#          if ($cond ne 'FALSE')
+#              {
+#                my $file = ($is_am ? "$libdir/am/" : '') . $1;
+#                # N-ary `.=' fails.
+#                my ($com, $vars, $rules)
+#                  = file_contents_internal ($is_am, $file,
%transform);
+#                $comment .= $com;
+#                $result_vars .= $vars;
+#                $result_rules .= $rules;
+#              }
+#        }
+
+       # Handling the conditionals.
         elsif (/$IF_PATTERN/o)
          {
            $cond = cond_stack_if ($1, $2, $file);



reply via email to

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