X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?p=subdirmk.git;a=blobdiff_plain;f=build-aux%2Fsubdirmk-setup;h=f7216219700d2e5fe82416ba19ecb4a1430ebc49;hp=9f3c8c62a43ae7858af834a8595db26e7c245d38;hb=1d0151d4f66912805d9b6d79527c587ab881f5aa;hpb=2f80e8623b4712dbe0f46963f7aed08ec4645473 diff --git a/build-aux/subdirmk-setup b/build-aux/subdirmk-setup index 9f3c8c6..f721621 100644 --- a/build-aux/subdirmk-setup +++ b/build-aux/subdirmk-setup @@ -8,25 +8,151 @@ use strict; -our @allsubdirs = @ARGV; +our $root = [ '.', [ ] ]; +# each node is [ 'relative subdir name', \@children ] -sub write_makefile () { - start_output_file("Makefile"); - print O <[0] eq $d } @{ $node->[1] }; + if (!$c) { + $c = [ $d, [ ] ]; + push @{ $node->[1] }, $c; + } + $node = $c; + } + } +} + +sub write_makefile ($$) { + my ($dir_prefix,$depth) = @_; + start_output_file("${dir_prefix}Makefile"); + my $cd = $depth ? join('/', ('..',) x $depth) : '.'; + o <) { + for (;;) { + unless (s{^(.*?)(\\)?(?=$esc)}{}) { o $_; last; } + o $1; + if ($2) { o $esclit; next; } + s{^$esc}{} or die "$_ ?"; + if (s{^$esc}{}) { o "$esclit$esclit" } + elsif (m{^TARGETS(?:_[0-9a-zA-Z_]+)?(?=\W)}{}) { + my $t = $2 // 'all'; + o target_varname($varname_prefix, $t); + $targets->{$t}=1; + } + elsif (m{^(?=$caps_re)}) { o "${var_prefix}_" } + elsif (m{^(?=$lc_re)}) { o $dir_prefix } + elsif (s{^_}{}) { o "${var_prefix}_" } + elsif (s{^/}{}) { o $dir_prefix } + elsif (s{^=_}{}) { o $var_prefix } + elsif (s{^=/}{}) { o $dir_name } + elsif (s{^\^}{}) { o "\$(top_srcdir)${dir_suffix}" } + elsif (s{^\}}{}) { o "\$(abs_top_srcdir)${dir_suffix}" } + elsif (s{^(?:[ \t]+([~^]))?(?=[ \t]){}}{}) { + my $prefix = + !$1 ? $dir_prefix : + $1 eq '~' ? '$(abs_top_srcdir)'.$dir_suffix : + $1 eq '~' ? '$(abs_top_srcdir)'.$dir_suffix : + die; + my $after=''; + if (m{([ \t])$esc}) { ($_,$after) = ($`, $1.$'); } + s{(?<=[ \t])(?=\S)(?!\\\s*$)}{$prefix}g; + o $_; + $_ = $after; + } elsif (s{^![ \t]+}{}) { + o $_; + $_ = ''; + } elsif (s{^!(\pPosixWord+|\pPosixPunct+)[ \t]*}{}) { + $esclit = $1; + $esc = $esclit; + $esc =~ s/\W/\\$&/g; + } else { + die "bad escape $esclit$_ "; + } + } + } +} + +sub target_varname ($$) { + my ($var_prefix, $target) = @_; + return $vprefix.'TARGETS'.($target eq 'all' ? '' : "_$target"); +} + +sub process_subtree ($$) { + # => list of descendants (in form SUBDIR/) + # recursive, children first + my ($node, $path); + + my $dir_prefix = join '', map { "$_/" } @$path; + my $dir_suffix = join '', map { "/$_" } @$path; + my $dir_name = join '/', @$path ? @$path : '.'; + my $var_prefix = map { "${_}_" } @$path ? @$path : qw(TOP); + + write_makefile($subdir, scalar @$path); + + my %targets = qw(all 1); + my @child_subdirs; + foreach my $child (@{ $node->[1] }) { + my @childpath = (@$path, $child->[0]); + push @child_subdirs, join '/', @childpath; + $targets{$_}++ foreach + process_subtree($child, [ ]); + } + start_output_file("$subdir/Subdir.mk.tmp"); + + filter_subdir_mk($dir_prefix, $dir_suffix, $dir_name, + $var_prefix, \%targets); + + my @targets = sort keys %targets; + foreach my $target (@targets) { + my $target_varname = target_varname($var_prefix, target); + print O <