#!/usr/bin/perl exit if !defined $ARGV[0]; @lines = get_makefile($ARGV[0]); @lines = get_useful(@lines); while (@includes = grep(/^include /, @lines)) { @lines = grep(!/^include /, @lines); get_vars(@lines); foreach (@includes) { chomp; s/^include //; $file = expand($_); @lines = (@lines, get_useful(get_makefile($file))); } } get_vars(@lines); @targets = get_targets(@lines); @targets = sort(@targets); foreach (@targets) { print "$_\n"; } sub get_makefile { my $file = shift(@_); open FILE, $file; my @lines = ; close FILE; return @lines; } sub get_useful { my $line = ""; my @retarr; foreach (@_) { s/\#.*//; $line .= $_ if (!/^[\#[:space:]]/); if (!/\\$/) { $line =~ s/\\\n//g; @retarr = (@retarr, $line); $line = ""; } } $line =~ s/\\\n//g; @retarr = (@retarr, $line); return @retarr; } sub get_vars { foreach (@_) { next if (!/=/); /([^[:space:]]*)[[:space:]]*:?=[[:space:]]*(.*)/; $vars{$1} = $2; } } sub get_targets { my @targets; foreach (@_) { next if (/=/); next if (!/:/); /([^:]*):(.*)/; @targets = (@targets, split(' ', expand($1))); } return @targets; } sub expand { my $line = shift @_; return $line if (!($line =~ /\$/)); my @bits = split('\$', $line); my $skip = 0; my $ret = shift @bits; foreach (@bits) { if ($skip) { $ret .= "\$$_"; $skip = 0; next; } if ($_ eq "") { $ret .= "\$"; $skip = 1; next; } if (/^\(/) { /^\((.*)\)(.*)/; $exp = $1; $rest = $2; } else { /^\{(.*)\}(.*)/; $exp = $1; $rest = $2; } if (!defined $exp) { $ret .= "\$$_"; next; } if (defined $vars{$exp}) { if ($vars{$exp} =~ /\$\(shell/) { $cmd = $vars{$exp}; $cmd =~ s/^\$\(shell //; $cmd =~ s/\)$//; $val = `$cmd`; chomp($val); $ret .= "$val$rest"; } else { $ret .= "$vars{$exp}$rest"; } } else { $ret .= "\$$_"; } } return $line if ($ret eq $line); return expand($ret); }