#! /usr/bin/perl -w # $Id$ # Copyright (C) 2005, 2006 Ralf Corsépius, Ulm, Germany # # Permission to use, copy, modify, and distribute this software # is freely granted, provided that this notice is preserved. # Helper script to generate pre/tmpinstall rules for RTEMS Makefile.am. # # Usage: ampolish3 Makefile.am > preinstall.am # # Reads a Makefile.am from stdin and writes corresponding # pre/tmpinstall rules to stdout. sub replace($); sub print_dirstamp($$$); # Predefined directory mappings: # # final-installation directory => temp installation directory my %dirmap = ( '$(includedir)' => '$(PROJECT_INCLUDE)', '$(libdir)' => '$(PROJECT_LIB)', '$(project_libdir)' => '$(PROJECT_LIB)', '$(project_includedir)' => '$(PROJECT_INCLUDE)' ); # Conventions on automake primaries: # # *_HEADERS -> preinstall # noinst*_HEADERS -> noinst # noinst_*_LIBRARIES -> noinst # project_*_LIBRARIES -> tmpinstall # *_LIBRARIES -> ignore (no preinstallation) # dist_project_*_DATA -> preinstall (bsp_specs,linkcmds) # project_*_DATA -> tmpinstall (*.o, *.a) # dist_*_DATA -> ignore (no preinstallation) # *SCRIPTS -> ignore (no preinstallation) # noinst_*_PROGRAMS -> noinst # project_*_PROGRAMS -> tmpinstall # *_PROGRAMS -> ignore (no preinstallation) ## 1st pass: read in file my @buffer1 = () ; my %seen = (); my %predefs = (); { my $mode = 0 ; my $line = ''; while ( <> ) { if ( $mode == 0 ) { if ( /^([a-zA-Z0-9_]+\s*[\+]?[:=].*)\\$/o ) { $line = "$1" ; $mode = 1; } else { push @buffer1, $_ ; } } elsif ( $mode == 1 ) { if ( /^(.*)\\$/o ) { $line .= $1; } else { $line .= $_ ; push @buffer1, $line ; $line = ''; $mode = 0 ; } } } } #foreach my $l ( @buffer1 ) { print STDERR "1:<$l>"; } # Filter out all Makefile code not relevant here my @buffer2 = (); foreach my $l ( @buffer1 ) { if ( $l=~ /^\t.*$/o ) { #ignore: Production of a make rule. } elsif ( $l =~ /^\s*([a-zA-Z0-9_]*dir)\s*\=\s*(.*)\s*$/o ) { # dirs push @buffer2, "$l"; $dirmap{"\$\($1\)"} = replace($2); } elsif ( $l =~ /^\s*noinst_(.*)\s*[\+]?\=(.*)$/o ) { #ignore: noinst_* are not relevant here. } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_|)([a-zA-Z0-9_]+)_(HEADERS|LIBRARIES|DATA|SCRIPTS|PROGRAMS)\s*([\+]?\=)\s*(.*)/o ) { if ( ( "$5" eq '=' ) ) { my $v = $dirmap{"\$\($3dir\)"}; if ( $v =~ /\$\(PROJECT_[^\)]+\)$/ ) { $predefs{"$v"} = 1; } } foreach my $f ( split(' ',$6) ) { push @buffer2, "$1$2$3_$4 +=$f\n"; } } elsif ( $l =~ /^\s*(if|else|endif)\s*.*$/o ) { # conditionals push @buffer2, "$l"; } # Check if Makefile.am already contains CLEANFILES or DISTCLEANFILES if ( $l =~ /^\s*(CLEANFILES|DISTCLEANFILES|SUBDIRS)\s*\=.*$/o ) { $predefs{"$1"} = 1; } } if ( $predefs{"\$(PROJECT_INCLUDE)"} ){ unshift @buffer2, "includedir = \$(includedir)\n"; } if ( $predefs{"\$(PROJECT_LIB)"} ){ unshift @buffer2, "libdir = \$(libdir)\n"; } # foreach my $l ( @buffer2 ) { print STDERR "2:<$l>"; } my @buffer3 = (); foreach my $l ( @buffer2 ) { if ( $l =~ /^\s*([a-zA-Z0-9_]*dir)\s*\=\s*(.*)\s*$/o ) { # dirs my $v = $dirmap{"\$\($1\)"}; print_dirstamp(\@buffer3,$v,"PREINSTALL_DIRS"); $seen{"PREINSTALL_DIRS"} = 1; } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_|)([a-zA-Z0-9_]+)_HEADERS\s*\+\=(.*)/o ) { # preinstall my $v = $dirmap{"\$\($3dir\)"}; my $f = $4; my $x ; my $i = rindex($f,'/'); if ($i < 0) { $x="$f"; } else { $x = substr($f,$i+1); } push @buffer3, "$v/$x: $f $v/\$(dirstamp)\n", "\t\$(INSTALL_DATA) \$< $v/$x\n", "PREINSTALL_FILES += $v/$x\n\n"; $seen{"PREINSTALL_FILES"} = 1; } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_)([a-zA-Z0-9_]+)_LIBRARIES\s*\+\=(.*)/o ) { # tmpinstall my $v = $dirmap{"\$\($3dir\)"}; my $f = $4; my $x ; my $i = rindex($f,'/'); if ($i < 0) { $x="$f"; } else { $x = substr($f,$i+1); } push @buffer3, "$v/$x: $f $v/\$(dirstamp)\n", "\t\$(INSTALL_DATA) \$< $v/$x\n", "TMPINSTALL_FILES += $v/$x\n\n"; $seen{"TMPINSTALL_FILES"} = 1; } elsif ( $l =~ /^\s*(nodist_|dist_|)([a-zA-Z0-9_]+)_LIBRARIES\s*\+\=(.*)/o ) { # ignore } elsif ( $l =~ /^\s*(dist_)(project_)([a-zA-Z0-9_]+)_DATA\s*\+\=(.*)/o ) { # preinstall my $v = $dirmap{"\$\($3dir\)"}; my $f = $4; my $x ; my $i = rindex($f,'/'); if ($i < 0) { $x="$f"; } else { $x = substr($f,$i+1); } push @buffer3, "$v/$x: $f $v/\$(dirstamp)\n", "\t\$(INSTALL_DATA) \$< $v/$x\n", "PREINSTALL_FILES += $v/$x\n\n"; $seen{"PREINSTALL_FILES"} = 1; } elsif ( $l =~ /^\s*(nodist_|)(project_)([a-zA-Z0-9_]+)_DATA\s*\+\=(.*)/o ) { # tmpinstall my $v = $dirmap{"\$\($3dir\)"}; my $f = $4; my $x ; my $i = rindex($f,'/'); if ($i < 0) { $x="$f"; } else { $x = substr($f,$i+1); } push @buffer3, "$v/$x: $f $v/\$(dirstamp)\n", "\t\$(INSTALL_DATA) \$< $v/$x\n", "TMPINSTALL_FILES += $v/$x\n\n"; $seen{"TMPINSTALL_FILES"} = 1; } elsif ( $l =~ /^\s*(dist_|)([a-zA-Z0-9_]+)_DATA\s*\+\=(.*)/o ) { # ignore } elsif ( $l =~ /^\s*(nodist_|dist_|)([a-zA-Z0-9_]+)_SCRIPTS\s*\+\=(.*)/o ) { # ignore } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_)([a-zA-Z0-9_]+)_PROGRAMS\s*\+\=(.*)/o ) { # tmpinstall my $v = $dirmap{"\$\($3dir\)"}; my $f = $4; my $x ; my $i = rindex($f,'/'); if ($i < 0) { $x="$f"; } else { $x = substr($f,$i+1); } push @buffer3, "$v/$x: $f $v/\$(dirstamp)\n", "\t\$(INSTALL_PROGRAM) \$< $v/$x\n", "TMPINSTALL_FILES += $v/$x\n\n"; $seen{"TMPINSTALL_FILES"} = 1; } elsif ( $l =~ /^\s*(nodist_|dist_|)([a-zA-Z0-9_]+)_PROGRAMS\s*\+\=(.*)/o ) { # ignore } elsif ( $l =~ /^\s*(if|else|endif)\s*.*$/o ) { # conditionals push @buffer3, "$l"; } } # foreach my $l ( @buffer3 ) { print STDERR "3:<$l>"; } my $output; $output .= "## Automatically generated by ampolish3 - Do not edit\n\n"; $output .= "if AMPOLISH3\n"; $output .= "\$(srcdir)/preinstall.am: Makefile.am\n"; $output .= "\t\$(AMPOLISH3) \$(srcdir)/Makefile.am > \$(srcdir)/preinstall.am\n"; $output .= "endif\n\n"; foreach my $k ( keys %seen ) { if ( $k =~ /PREINSTALL_FILES/o ) { $output .= "all-am: \$(PREINSTALL_FILES)\n\n"; $output .= "$k =\n"; $output .= "CLEANFILES "; if ( $predefs{"CLEANFILES"} ) { $output .= "+"; } $output .= "= \$($k)\n"; $predefs{"CLEANFILES"} = 1; } elsif ( $k =~ /TMPINSTALL_FILES/o ) { $output .= "all-local: \$(TMPINSTALL_FILES)\n\n"; $output .= "$k =\n"; $output .= "CLEANFILES "; if ( $predefs{"CLEANFILES"} ) { $output .= "+"; } $output .= "= \$($k)\n"; $predefs{"CLEANFILES"} = 1; } elsif ( $k =~ /.*DIRS/o ) { $output .= "$k =\n"; $output .= "DISTCLEANFILES "; if ( $predefs{"DISTCLEANFILES"} ) { $output .= "+"; } $output .= "= \$($k)\n"; $predefs{"DISTCLEANFILES"} = 1; } $output .= "\n"; } # Pretty printing $output .= join ( '', @buffer3 ); $output =~ s/\nelse\n+endif/\nendif/g; $output =~ s/\n\n+endif/\nendif/g; $output =~ s/\nif [a-zA-Z0-9_!]+\n+endif//g; print STDOUT $output; exit 0; sub replace($) { my ($v) = @_; foreach my $i ( keys %dirmap ) { $v =~ s/\Q$i/$dirmap{$i}/g; } return $v; } sub print_dirstamp($$$) { my ($obuf,$file,$inst) = @_ ; push @{$obuf}, "$file/\$(dirstamp):\n\t\@\$\(mkdir_p\) $file\n" ; push @{$obuf}, "\t\@: \> $file/\$(dirstamp)\n" ; push @{$obuf}, "$inst += $file/\$(dirstamp)\n\n" ; }