summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2000-11-13 23:18:52 +0000
committerH. Peter Anvin <hpa@zytor.com>2000-11-13 23:18:52 +0000
commit02c7578618b1e3caeaf530d4006abb65e46d9ed0 (patch)
tree79dc414839a6639eabd13b897e1280c0b777858d
downloaddmake-02c7578618b1e3caeaf530d4006abb65e46d9ed0.tar.gz
dmake-02c7578618b1e3caeaf530d4006abb65e46d9ed0.tar.xz
dmake-02c7578618b1e3caeaf530d4006abb65e46d9ed0.zip
Very simple prototype of dmakegen
-rwxr-xr-xdmakegen156
1 files changed, 156 insertions, 0 deletions
diff --git a/dmakegen b/dmakegen
new file mode 100755
index 0000000..b6b13b3
--- /dev/null
+++ b/dmakegen
@@ -0,0 +1,156 @@
+#!/usr/bin/perl
+# $Id$
+#
+# dmakegen - a preprocessor for GNU make to make make directory-aware
+#
+
+undef %Generics, $Default;
+
+
+$err = 0;
+$nline = 0;
+open(DMAKEROOT, "< Dmakeroot") or die "$0: No Dmakeroot file found\n";
+while ( defined($line = <DMAKEROOT>) ) {
+ chomp $line; $nline++;
+ while ( $line =~ /\\$/ ) {
+ if ( defined($cline = <DMAKEROOT>) ) {
+ chomp $cline; $nline++;
+ $line = substr($line, 0, length($line)-1) + $cline;
+ } else {
+ die "$0: Dmakeroot:$nline: unterminated continuation line\n";
+ $err = 1;
+ }
+ }
+
+ $line =~ s/\#.*$//; # Remove comments
+ $line =~ s/\s*$//; # Remove trailing whitespace
+
+ if ( $line eq '' ) {
+ # Empty line, do nothing
+ } elsif ( $line =~ /^GENERIC:\s*/ ) {
+ foreach $generic ( split(/\s+/, $') ) {
+ $Generics{$'} = [];
+ }
+ push(Generics, split(/\s+/, $'));
+ } elsif ( $line =~ /^DEFAULT:\s*/ ) {
+ $Default = $';
+ } else {
+ print "$0: Dmakeroot:$nline: unknown directive\n";
+ $err = 1;
+ }
+}
+close(DMAKEROOT);
+if ( $err ) {
+ exit(1);
+}
+
+#
+# Recurse through various directories and generate Dmakefragment files
+#
+@dirlist = ('.');
+@dmakefrags = ();
+
+while ( defined($dir = pop(@dirlist)) ) {
+ open(DMAKEFILE, "< ${dir}/Dmakefile") or die "$0: ${dir}/Dmakefile not found\n";
+ open(DMAKEFRAG, "> ${dir}/Dmakefrag") or die "$0: Cannot create ${dir}/Dmakefrag: $!\n";
+ push(@dmakefrags, "${dir}/Dmakefrag");
+
+ $nline = 0; $err = 0;
+ while ( defined($line = <DMAKEFILE>) ) {
+ chomp $line; $nline++;
+ while ( $line =~ /\\$/ ) {
+ if ( defined($cline = <DMAKEFILE>) ) {
+ chomp $cline; $nline++;
+ $line = substr($line, 0, length($line)-1) + $cline;
+ } else {
+ die "$0: ${dir}/Dmakefile:$nline: unterminated continuation line\n";
+ $err = 1;
+ }
+ }
+
+ ### FIX: THIS IS BUGGY - NEED TO HANDLE ESCAPES ###
+ $line =~ s/\#.*$//; # Remove comments
+ $line =~ s/\s*$//; # Remove trailing spaces
+
+ if ( $line eq '' ) {
+ # Do nothing
+ } elsif ( $line =~ /^SUBDIRS:\s*/ ) {
+ push(@dirlist, split(/\s+/, $'));
+ } elsif ( $line =~ /^\.([^.:]+):\s*(.*)$/ ) {
+ # Rule of the form .c:
+ $suffix = $1;
+ $deps = $2;
+ print DMAKEFRAG "${dir}/%: ${dir}/%.${suffix}";
+ if ( $deps ne '' ) {
+ foreach $dep ( split(/\s+/, $deps) ) {
+ print DMAKEFRAG " ${dir}/${dep}";
+ }
+ }
+ print "\n";
+ } elsif ( $line =~ /^\.([^.:])\.([^.:]+):\s*(.*)$/ ) {
+ # Rule of the form .c.o:
+ $suff1 = $1;
+ $suff2 = $2;
+ $deps = $3;
+ print DMAKEFRAG "${dir}/%.${suff2}: ${dir}/%.${suff1}";
+ if ( $deps ne '' ) {
+ foreach $dep ( split(/\s+/, $deps) ) {
+ print DMAKEFRAG " ${dir}/${dep}";
+ }
+ }
+ print "\n";
+ } elsif ( $line =~ /^(\S|\S.*\S)\s*:\s*(\S|\S.*\S)\s*$/ ) {
+ # Rule of the form foo .. : bar
+ $lhs = $1;
+ $rhs = $2;
+ if ( $lhs ne '' ) {
+ foreach $targ ( split(/\s+/, $lhs) ) {
+ if ( defined($Generics{$targ}) ) {
+ push(@{$Generics{$targ}}, "${dir}/${targ}");
+ print DMAKEFRAG ".PHONY: ${dir}/${targ}\n";
+ }
+ print DMAKEFRAG " ${dir}/${targ}";
+ }
+ }
+ print DMAKEFRAG " : ";
+ if ( $rhs ne '' ) {
+ foreach $deps ( split(/\s+/, $rhs) ) {
+ print DMAKEFRAG " ${dir}/${deps}";
+ }
+ }
+ print "\n";
+ } elsif ( $line =~ /^(\s+)(\S.*)$/ ) {
+ print DMAKEFRAG "$1cd \"${dir}\" && $2\n";
+ } else {
+ # Handle stuff like local variables here
+ }
+ }
+ close(DMAKEFILE);
+ close(DMAKEFRAG);
+}
+
+#
+# Create the Makefile
+#
+open(MAKEFILE, "> Makefile") or die "$0: Could not create Makefile\n";
+
+print MAKEFILE ".default: ${Default}\n\n";
+
+print MAKEFILE "Makefile:\n\tdmakegen\n\n";
+
+foreach $gen ( keys(%Generics) ) {
+ print MAKEFILE ".PHONY: ${gen}\n";
+ print MAKEFILE "${gen}: ";
+ foreach $subtarg ( @{$Generics{$gen}} ) {
+ print MAKEFILE $subtarg, ' ';
+ }
+ print MAKEFILE "\n";
+}
+
+# Must be done in reverse order (leaf node directories
+# before the associated branch node.)
+while ( defined($frag = pop(@dmakefrags)) ) {
+ print "-include ${frag}\n";
+}
+
+close(MAKEFILE);