On Tue, Apr 22, 2014 at 5:06 PM, Nick Bowler <[email protected]> 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.