On Tue, Apr 22, 2014 at 5:06 PM, Nick Bowler <nbow...@elliptictech.com> wrote:
> On 2014-04-22 16:15 +0100, Gavin Smith wrote:
>> Is support for setting variables with names of source directories
>> after automake is run (with configure scripts, or on the command line
>> when make is run) is needed? If not, could variables in the paths of
>> source files ("$(testd)") above could be expanded when automake is
>> run?
>>
>> So Makefile currently has lines like
>>
>> include $(testd)/test-imgloader.Po
>>
>> and this would become
>>
>> include ctests/test-imgloader.Po
>>
>> with no opportunity to change the value of testd. Then config.status
>> could read the name of the file from Makefile and create it properly.
>
> Even if the value depended on configure-time substitutions (@VAR@-
> style) I think there would be no problem here (maybe other problems
> though) because the depfiles creation step happens afterwards.
>
> Make-time substitutions for this sort of thing would be exceptionally
> weird and I can't imagine it actually working properly in current
> versions of Automake.
>
> If config.status knew how to perform the variable substitutions
> I think there would be no problem.  This may be too tricky to
> implement in portable shell.  However, the same substitutions
> could be done by postprocessing Makefile.in so I don't see why
> it could not be done at Automake-time.

Here's my attempt at a fix. I couldn't find anything to expand
variables defined in the Automake::Variable module so I've written
code to expand these, with a maximum level of expansion in case of
cyclic definitions. One complication is that variables can be defined
conditionally, so I tried to check that they weren't. The error
messages here leave something to be desired - there may be some way of
continuing instead of having a fatal error, and the messages don't say
what source files are affected - it is not obvious how to get this
information.
diff --git a/bin/automake.in b/bin/automake.in
index f19cac7..9198724 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -1208,10 +1208,48 @@ sub handle_languages ()
 		$output_rules .= (subst ('AMDEP_TRUE')
 				  . subst ('am__include')
 				  . ' '
-				  . subst ('am__quote')
-				  . $iter
-				  . subst ('am__quote')
-				  . "\n");
+				  . subst ('am__quote'));
+
+		# Expand any variables used to specify the source file.
+		my $i = 0;
+		while (my @vars = scan_variable_expansions ($iter)) {
+		  # The code in m4/depout.m4 depends on DEPDIR
+		  # being unexpanded.
+		  if (@vars == 1) {
+		    last if ("DEPDIR" eq $vars[0]);
+		  }
+
+		  # Don't repeat indefinitely if a variable is defined
+		  # in terms of itself.
+		  $i++;
+		  if ($i == 10) {
+		   fatal "Source file specified with too deep"
+		   	. "a level of of variable expansion";
+		  }
+		  foreach my $varname (@vars) {
+		      # The code in m4/depout.m4 depends on DEPDIR
+		      # being unexpanded.
+		      next if $varname eq "DEPDIR";
+		      my $var = var $varname;
+		      my ($vardef, $varval);
+
+		      if ($var) {
+			$vardef = $var->def (new Automake::Condition);
+			# Check that the variable is defined unconditionally.
+			if (! $vardef) {
+			    fatal "Variable '$varname' defined conditionally"
+			    . " in specification of source file.\n";
+			}
+		      }
+
+		      $varval = $vardef->value;
+		      $iter =~ s/\$\($varname\)/$varval/g;
+		      $iter =~ s/\${$varname}/$varval/g;
+		  }
+		}
+			
+		$output_rules .= $iter;
+		$output_rules .= (subst ('am__quote') . "\n");
 	    }
 
 	    # Compute the set of directories to remove in distclean-depend.

Reply via email to