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.