X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?p=subdirmk.git;a=blobdiff_plain;f=generate;h=0f9dd2d75ba289af83b4072812c13d92c2185b2f;hp=e1efc06a95bf11186df3f92c2d10cabf5d5552d4;hb=172acdebcae01e79278788880ee148f16395dc47;hpb=cf7f7e9dfdb0241d091655bca63edcdae5b81c03 diff --git a/generate b/generate index e1efc06..0f9dd2d 100755 --- a/generate +++ b/generate @@ -6,11 +6,11 @@ # # $(srcdir)/subdirmk/generate [--srcdir=SRCDIR] [--] SUBDIR... # -# generates in each subdirectory from in each subdirectory -# Subdir.mk.tmp Subdir.sd.mk -# Makefile and included files -# and in toplevel and in toplevel -# main.mk.tmp Perdir.sd.mk +# generates in each subdirectory +# Subdir.mk.tmp +# Makefile +# and in toplevel +# main.mk.tmp use strict; use POSIX; @@ -78,6 +78,10 @@ sub o { print O @_ or die "error writing $writing_output.tmp: $!\n"; } +sub od { # maybe $-doubled + o @_; +} + sub start_output_file ($) { close_any_output_file(); ($writing_output) = @_; @@ -114,11 +118,26 @@ Makefile run-main.mk: END } -sub process_input_mk ($$$$$$$$$); -sub process_input_mk ($$$$$$$$$) { - my ($dir_prefix, $dir_suffix, $dir_name, - $var_prefix, $var_prefix_name, $targets, - $f, $esclitr, $enoent_ok) = @_; +our ($dir_prefix, $dir_suffix, $dir_name, + $var_prefix, $var_prefix_name); + +sub dir_prefix ($) { + my ($path) = @_; + join '', map { "$_/" } @$path; +} + +sub set_dir_vars ($) { + my ($path) = @_; + $dir_prefix = dir_prefix($path); + $dir_suffix = join '', map { "/$_" } @$path; + $dir_name = join '/', @$path ? @$path : '.'; + $var_prefix_name = join '_', @$path ? @$path : qw(TOP); + $var_prefix = "${var_prefix_name}_"; +} + +sub process_input_mk ($$$$); +sub process_input_mk ($$$$) { + my ($targets, $f, $esclitr, $enoent_ok) = @_; my $caps_re = qr{[A-Z]}; my $lc_re = qr{[a-z]}; @@ -155,37 +174,37 @@ sub process_input_mk ($$$$$$$$$) { $buffering_output=''; } elsif (m#^\s*$esc\:([a-z][-0-9a-z_]*)#) { die "unknown directive $1"; + } elsif (s{^\s*${esc}TARGETS(?:_([0-9a-zA-Z_]+))?(?=\W)}{}) { + my $t = $1 // 'all'; + od target_varname($var_prefix, $t); + $targets->{$t} //= [ ]; } for (;;) { - unless (s{^(.*?)$esc}{}) { o $_; last; } - o $1; - if (s{^\\$esc}{}) { o "$$esclitr" } - elsif (s{^\\\$}{}) { o '$' } - elsif (s{^$esc}{}) { o "$$esclitr$$esclitr" } - elsif (s{^TARGETS(?:_([0-9a-zA-Z_]+))?(?=\W)}{}) { - my $t = $1 // 'all'; - o target_varname($var_prefix, $t); - $targets->{$t} //= [ ]; - } - elsif (m{^(?=$caps_re)}) { o $var_prefix } - elsif (s{^\$([A-Za-z]\w+)}{}) { o "\$(${var_prefix}$1)" } - elsif (s{^([~^]?)(?=$lc_re)}{}) { o $pfxmap{$1} } - elsif (s{^_}{}) { o $var_prefix } - elsif (s{^=}{}) { o $var_prefix_name } - elsif (s{^([~^]?)/}{}) { o $pfxmap{$1} } - elsif (s{^\.}{}) { o $dir_name } - elsif (s{^([~^])\.}{}) { o $srcdirmap{$1} } + unless (s{^(.*?)$esc}{}) { od $_; last; } + od $1; + if (s{^\\$esc}{}) { od "$$esclitr" } + elsif (s{^\\\$}{}) { od '$' } + elsif (s{^\\\s+$}{}) { } + elsif (s{^$esc}{}) { od "$$esclitr$$esclitr" } + elsif (m{^(?=$caps_re)}) { od $var_prefix } + elsif (s{^\$([A-Za-z]\w+)}{}) { od "\$(${var_prefix}$1)" } + elsif (s{^([~^]?)(?=$lc_re)}{}) { od $pfxmap{$1} } + elsif (s{^_}{}) { od $var_prefix } + elsif (s{^=}{}) { od $var_prefix_name } + elsif (s{^([~^]?)/}{}) { od $pfxmap{$1} } + elsif (s{^\.}{}) { od $dir_name } + elsif (s{^([~^])\.}{}) { od $srcdirmap{$1} } elsif (s{^([~^]?)(?=[ \t])}{}) { my $prefix = $pfxmap{$1} // die; my $after=''; if (m{([ \t])$esc}) { ($_,$after) = ($`, $1.$'); } s{(?<=[ \t])(?=\S)(?!\\\s*$)}{$prefix}g; - o $_; + od $_; $_ = $after; } elsif (s{^\#}{}) { $_ = ''; } elsif (s{^![ \t]+}{}) { - o $_; + od $_; $_ = ''; } else { die "bad escape $$esclitr$_ "; @@ -196,10 +215,8 @@ sub process_input_mk ($$$$$$$$$) { $buffering_output=undef; if (m#^(-?)include\s+(\S+)\s+$#) { my $subf = "$srcdir/$2"; - process_input_mk($dir_prefix, $dir_suffix, $dir_name, - $var_prefix, $var_prefix_name, $targets, - $subf, $esclitr, $1); - o "\n"; + process_input_mk($targets, $subf, $esclitr, $1); + od "\n"; } else { die "internal error buffering directive $_ "; } @@ -209,9 +226,8 @@ sub process_input_mk ($$$$$$$$$) { close $input or die "close $f: $!\n"; } -sub filter_subdir_mk ($$$$$$) { - my ($dir_prefix, $dir_suffix, $dir_name, - $var_prefix, $var_prefix_name, $targets) = @_; +sub filter_subdir_mk ($) { + my ($targets) = @_; #use Data::Dumper; #print STDERR "filter @_\n"; @@ -220,28 +236,25 @@ sub filter_subdir_mk ($$$$$$) { my $pi = sub { my ($f, $enoentok) = @_; - process_input_mk($dir_prefix, $dir_suffix, $dir_name, - $var_prefix, $var_prefix_name, $targets, - "${srcdir}/$f", \$esclit, $enoentok); + process_input_mk($targets, "${srcdir}/$f", \$esclit, $enoentok); }; + $pi->("Prefix.sd.mk", 1); $pi->("${dir_prefix}Subdir.sd.mk", 0); - $pi->("Perdir.sd.mk", 1); + $pi->("Suffix.sd.mk", 1); } sub process_subtree ($$); sub process_subtree ($$) { - # => list of descendants (in form SUBDIR/) + # => list of targets (in form SUBDIR/) # recursive, children first my ($node, $path) = @_; #use Data::Dumper; #print STDERR Dumper(\@_); - my $dir_prefix = join '', map { "$_/" } @$path; - my $dir_suffix = join '', map { "/$_" } @$path; - my $dir_name = join '/', @$path ? @$path : '.'; - my $var_prefix_name = join '_', @$path ? @$path : qw(TOP); - my $var_prefix = "${var_prefix_name}_"; + my $dir_prefix = dir_prefix($path); + # ^ this is the only var which we need before we come back from + # the recursion. push @output_makefiles, "${dir_prefix}Subdir.mk"; write_makefile($dir_prefix, scalar @$path); @@ -254,11 +267,12 @@ sub process_subtree ($$) { push @{ $targets{$_} }, $child_subdir foreach process_subtree($child, \@childpath); } + + set_dir_vars($path); start_output_file("${dir_prefix}Subdir.mk.tmp"); if ($node->[2]) { - filter_subdir_mk($dir_prefix, $dir_suffix, $dir_name, - $var_prefix, $var_prefix_name, \%targets); + filter_subdir_mk(\%targets); } else { my $sdmk = "${dir_prefix}Subdir.sd.mk"; if (stat $sdmk) { @@ -289,8 +303,22 @@ sub process_subtree ($$) { return @targets; } +sub process_final ($) { + my ($otargets) = @_; + set_dir_vars([]); + push @output_makefiles, "Final.mk"; + start_output_file("Final.mk.tmp"); + my %ntargets; + my $esclit='&'; + process_input_mk(\%ntargets, "${srcdir}/Final.sd.mk", \$esclit, 1); + delete $ntargets{$_} foreach @$otargets; + my @ntargets = sort keys %ntargets; + die "late new targets @ntargets" if @ntargets; +} + sub process_tree() { - process_subtree($root, [ ]); + my @targets = process_subtree($root, [ ]); + process_final(\@targets); start_output_file("main.mk.tmp"); foreach my $v (qw(top_srcdir abs_top_srcdir)) { o "$v=\@$v@\n";