Throw away "./" in findfile so that the Mac makefile has valid paths.
[u/mdw/putty] / mkfiles.pl
index bbdcf4a..d595e53 100755 (executable)
@@ -7,6 +7,12 @@
 # files to compute #include dependencies. Finally, writes out the
 # various target Makefiles.
 
+# PuTTY specifics which could still do with removing:
+#  - Mac makefile is not portabilised at all. Include directories
+#    are hardwired, and also the libraries are fixed. This is
+#    mainly because I was too scared to go anywhere near it.
+#  - sbcsgen.pl is still run at startup.
+
 use FileHandle;
 use Cwd;
 
@@ -23,7 +29,7 @@ open IN, "Recipe" or do {
 # dependency analysis.
 eval 'chdir "charset"; require "sbcsgen.pl"; chdir ".."';
 
-@incdirs = ("", "charset/", "unix/", "mac/");
+@srcdirs = ("./");
 
 $divert = undef; # ref to scalar in which text is currently being put
 $help = ""; # list of newline-free lines of help text
@@ -43,7 +49,9 @@ while (<IN>) {
   if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = \$help; next; }
   if ($_[0] eq "!end") { $divert = undef; next; }
   if ($_[0] eq "!name") { $project_name = $_[1]; next; }
+  if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }
   if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
+  if ($_[0] eq "!specialobj" and &mfval($_[1])) { $specialobj{$_[1]}->{$_[2]} = 1; next;}
   if ($_[0] eq "!begin") {
       if (&mfval($_[1])) {
          $divert = \$makefile_extra{$_[1]};
@@ -210,13 +218,31 @@ sub mfval($) {
 
 # Utility routines while writing out the Makefiles.
 
+sub dirpfx {
+    my ($path) = shift @_;
+    my ($sep) = shift @_;
+    my $ret = "", $i;
+
+    while (($i = index $path, $sep) >= 0 ||
+          ($j = index $path, "/") >= 0) {
+        if ($i >= 0 and ($j < 0 or $i < $j)) {
+           $path = substr $path, ($i + length $sep);
+       } else {
+           $path = substr $path, ($j + 1);
+       }
+       $ret .= "..$sep";
+    }
+    return $ret;
+}
+
 sub findfile {
   my ($name) = @_;
   my $dir, $i, $outdir = "";
   unless (defined $findfilecache{$name}) {
     $i = 0;
-    foreach $dir (@incdirs) {
+    foreach $dir (@srcdirs) {
       $outdir = $dir, $i++ if -f "$dir$name";
+      $outdir=~s/^\.\///;
     }
     die "multiple instances of source file $name\n" if $i > 1;
     $findfilecache{$name} = $outdir . $name;
@@ -260,12 +286,13 @@ sub splitline {
 }
 
 sub deps {
-  my ($otmpl, $rtmpl, $prefix, $dirsep, $depchar, $splitchar) = @_;
+  my ($otmpl, $rtmpl, $prefix, $dirsep, $mftyp, $depchar, $splitchar) = @_;
   my ($i, $x, $y);
   my @deps, @ret;
   @ret = ();
   $depchar ||= ':';
   foreach $i (sort keys %depends) {
+    next if $specialobj{$mftyp}->{$i};
     if ($i =~ /^(.*)\.(res|rsrc)/) {
       next if !defined $rtmpl;
       $y = $1;
@@ -321,6 +348,7 @@ sub manpages {
 # Now we're ready to output the actual Makefiles.
 
 if (defined $makefiles{'cygwin'}) {
+    $dirpfx = &dirpfx($makefiles{'cygwin'}, "/");
 
     ##-- CygWin makefile
     open OUT, ">$makefiles{'cygwin'}"; select OUT;
@@ -345,18 +373,14 @@ if (defined $makefiles{'cygwin'}) {
     "# RCINC = --include-dir c:\\cygwin\\include\\\n".
     "\n".
     &splitline("CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".
-      " -D_NO_OLDNAMES -DNO_MULTIMON -I.")."\n".
+      " -D_NO_OLDNAMES -DNO_MULTIMON " .
+              (join " ", map {"-I$dirpfx$_"} @srcdirs)) .
+              "\n".
     "LDFLAGS = -mno-cygwin -s\n".
     &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1".
       " --define WINVER=0x0400 --define MINGW32_FIX=1")."\n".
     "\n".
     ".SUFFIXES:\n".
-    "\n".
-    "%.o: %.c\n".
-    "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
-    "\n".
-    "%.res.o: %.rc\n".
-    "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n".
     "\n";
     print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
     print "\n\n";
@@ -370,9 +394,14 @@ if (defined $makefiles{'cygwin'}) {
                        "-Wl,-Map,$prog.map " .
                        $objstr . " $libstr", 69), "\n\n";
     }
-    foreach $d (&deps("X.o", "X.res.o", "", "/")) {
+    foreach $d (&deps("X.o", "X.res.o", $dirpfx, "/", "cygwin")) {
       print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
         "\n";
+      if ($d->{obj} =~ /\.res\.o$/) {
+         print "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) ".$d->{deps}->[0]." ".$d->{obj}."\n\n";
+      } else {
+         print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c ".$d->{deps}->[0]."\n\n";
+      }
     }
     print "\n";
     print $makefile_extra{'cygwin'};
@@ -385,6 +414,8 @@ if (defined $makefiles{'cygwin'}) {
 
 ##-- Borland makefile
 if (defined $makefiles{'borland'}) {
+    $dirpfx = &dirpfx($makefiles{'borland'}, "\\");
+
     %stdlibs = (  # Borland provides many Win32 API libraries intrinsically
       "advapi32" => 1,
       "comctl32" => 1,
@@ -421,7 +452,9 @@ if (defined $makefiles{'borland'}) {
     "\n".
     ".c.obj:\n".
     &splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT) \$(FWHACK)".
-      " \$(XFLAGS) \$(CFLAGS) /c \$*.c",69)."\n".
+              " \$(XFLAGS) \$(CFLAGS) ".
+              (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+              " /c \$*.c",69)."\n".
     ".rc.res:\n".
     &splitline("\tbrcc32 \$(FWHACK) \$(RCFL) -i \$(BCB)\\include -r".
       " -DNO_WINRESRC_H -DWIN32 -D_WIN32 -DWINVER=0x0401 \$*.rc",69)."\n".
@@ -463,7 +496,7 @@ if (defined $makefiles{'borland'}) {
       print "\techo " . &objects($p, undef, "X.res", undef) . " >> $prog.rsp\n";
       print "\n";
     }
-    foreach $d (&deps("X.obj", "X.res", "", "\\")) {
+    foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\", "borland")) {
       print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
         "\n";
     }
@@ -484,6 +517,8 @@ if (defined $makefiles{'borland'}) {
 }
 
 if (defined $makefiles{'vc'}) {
+    $dirpfx = &dirpfx($makefiles{'vc'}, "\\");
+
     ##-- Visual C++ makefile
     open OUT, ">$makefiles{'vc'}"; select OUT;
     print
@@ -498,13 +533,11 @@ if (defined $makefiles{'vc'}) {
       "MAKEFILE = Makefile.vc\n".
       "\n".
       "# C compilation flags\n".
-      "CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401\n".
+      "CFLAGS = /nologo /W3 /O1 " .
+      (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+      " /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401\n".
       "LFLAGS = /incremental:no /fixed\n".
       "\n".
-      ".c.obj:\n".
-      "\tcl \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) /c \$*.c\n".
-      ".rc.res:\n".
-      "\trc \$(FWHACK) \$(RCFL) -r -DWIN32 -D_WIN32 -DWINVER=0x0400 \$*.rc\n".
       "\n";
     print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
     print "\n\n";
@@ -533,9 +566,14 @@ if (defined $makefiles{'vc'}) {
        }
        print "\n";
     }
-    foreach $d (&deps("X.obj", "X.res", "", "\\")) {
+    foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\", "vc")) {
        print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
          "\n";
+        if ($d->{obj} =~ /.obj$/) {
+           print "\tcl \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) /c ".$d->{deps}->[0],"\n\n";
+       } else {
+           print "\trc \$(FWHACK) \$(RCFL) -r -DWIN32 -D_WIN32 -DWINVER=0x0400 ".$d->{deps}->[0],"\n\n";
+       }
     }
     print "\n";
     print $makefile_extra{'vc'};
@@ -561,6 +599,7 @@ if (defined $makefiles{'vc'}) {
 }
 
 if (defined $makefiles{'vcproj'}) {
+    $dirpfx = &dirpfx($makefiles{'vcproj'}, "\\");
 
     $orig_dir = cwd;
 
@@ -577,7 +616,7 @@ if (defined $makefiles{'vcproj'}) {
     mkdir $makefiles{'vcproj'}
         if(! -d $makefiles{'vcproj'});
     chdir $makefiles{'vcproj'};
-    @deps = &deps("X.obj", "X.res", "", "\\");
+    @deps = &deps("X.obj", "X.res", $dirpfx, "\\", "vcproj");
     %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
     # Create the project files
     # Get names of all Windows projects (GUI and console)
@@ -712,8 +751,12 @@ if (defined $makefiles{'vcproj'}) {
        "# PROP Intermediate_Dir \"Release\"\r\n".
        "# PROP Ignore_Export_Lib 0\r\n".
        "# PROP Target_Dir \"\"\r\n".
-       "# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
-       "# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
+       "# ADD BASE CPP /nologo /W3 /GX /O2 ".
+         (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
+         " /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
+       "# ADD CPP /nologo /W3 /GX /O2 ".
+         (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
+         " /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
        "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
        "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
        "# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
@@ -739,8 +782,12 @@ if (defined $makefiles{'vcproj'}) {
        "# PROP Intermediate_Dir \"Debug\"\r\n".
        "# PROP Ignore_Export_Lib 0\r\n".
        "# PROP Target_Dir \"\"\r\n".
-       "# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
-       "# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
+       "# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od ".
+         (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
+         " /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
+       "# ADD CPP /nologo /W3 /Gm /GX /ZI /Od ".
+         (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
+         " /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
        "# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
        "# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
        "# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
@@ -816,6 +863,7 @@ if (defined $makefiles{'vcproj'}) {
 }
 
 if (defined $makefiles{'gtk'}) {
+    $dirpfx = &dirpfx($makefiles{'gtk'}, "/");
 
     ##-- X/GTK/Unix makefile
     open OUT, ">$makefiles{'gtk'}"; select OUT;
@@ -832,7 +880,9 @@ if (defined $makefiles{'gtk'}) {
     "# TOOLPATH = /opt/gcc/bin\n".
     "CC = \$(TOOLPATH)cc\n".
     "\n".
-    &splitline("CFLAGS = -O2 -Wall -Werror -g -I. -I.. -I../charset `gtk-config --cflags`")."\n".
+    &splitline("CFLAGS = -O2 -Wall -Werror -g " .
+              (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+              " `gtk-config --cflags`")."\n".
     "XLDFLAGS = `gtk-config --libs`\n".
     "ULDFLAGS =#\n".
     "INSTALL=install\n",
@@ -846,8 +896,6 @@ if (defined $makefiles{'gtk'}) {
     "\n".
     ".SUFFIXES:\n".
     "\n".
-    "%.o:\n".
-    "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
     "\n";
     print &splitline("all:" . join "", map { " $_" } &progrealnames("XU"));
     print "\n\n";
@@ -859,9 +907,10 @@ if (defined $makefiles{'gtk'}) {
       print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
                        $objstr . " $libstr", 69), "\n\n";
     }
-    foreach $d (&deps("X.o", undef, "../", "/")) {
+    foreach $d (&deps("X.o", undef, $dirpfx, "/", "gtk")) {
       print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
           "\n";
+      print &splitline("\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c $d->{deps}->[0]\n");
     }
     print "\n";
     print $makefile_extra{'gtk'};
@@ -978,14 +1027,14 @@ if (defined $makefiles{'mpw'}) {
       }
 
     }
-    foreach $d (&deps("", "X.rsrc", "::", ":")) {
+    foreach $d (&deps("", "X.rsrc", "::", ":", "mpw")) {
       next unless $d->{obj};
       print &splitline(sprintf("%s \xc4 %s", $d->{obj}, join " ", @{$d->{deps}}),
                   undef, "\xb6"), "\n";
       print "\tRez ", $d->{deps}->[0], " -o {Targ} {ROptions}\n\n";
     }
     foreach $arch (qw(68K CFM68K)) {
-        foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
+        foreach $d (&deps("X.\L$arch\E.o", "", "::", ":", "mpw")) {
         next unless $d->{obj};
        print &splitline(sprintf("%s \xc4 %s", $d->{obj},
                                 join " ", @{$d->{deps}}),
@@ -995,7 +1044,7 @@ if (defined $makefiles{'mpw'}) {
          }
     }
     foreach $arch (qw(PPC Carbon)) {
-        foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
+        foreach $d (&deps("X.\L$arch\E.o", "", "::", ":", "mpw")) {
         next unless $d->{obj};
        print &splitline(sprintf("%s \xc4 %s", $d->{obj},
                                 join " ", @{$d->{deps}}),
@@ -1011,6 +1060,8 @@ if (defined $makefiles{'mpw'}) {
 }
 
 if (defined $makefiles{'lcc'}) {
+    $dirpfx = &dirpfx($makefiles{'lcc'}, "\\");
+
     ##-- lcc makefile
     open OUT, ">$makefiles{'lcc'}"; select OUT;
     print
@@ -1027,15 +1078,11 @@ if (defined $makefiles{'lcc'}) {
     "MAKEFILE = Makefile.lcc\n".
     "\n".
     "# C compilation flags\n".
-    "CFLAGS = -D_WINDOWS\n".
+    "CFLAGS = -D_WINDOWS " .
+      (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+      "\n".
     "\n".
     "# Get include directory for resource compiler\n".
-    "\n".
-    ".c.obj:\n".
-    &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK)".
-      " \$(XFLAGS) \$(CFLAGS)  \$*.c",69)."\n".
-    ".rc.res:\n".
-    &splitline("\tlrc \$(FWHACK) \$(RCFL) -r \$*.rc",69)."\n".
     "\n";
     print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
     print "\n\n";
@@ -1050,9 +1097,15 @@ if (defined $makefiles{'lcc'}) {
       print "\n\n";
     }
 
-    foreach $d (&deps("X.obj", "X.res", "", "\\")) {
+    foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\", "lcc")) {
       print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
         "\n";
+      if ($d->{obj} =~ /\.obj$/) {
+         print &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK)".
+                          " \$(XFLAGS) \$(CFLAGS) ".$d->{deps}->[0],69)."\n";
+      } else {
+         print &splitline("\tlrc \$(FWHACK) \$(RCFL) -r ".$d->{deps}->[0],69)."\n";
+      }
     }
     print "\n";
     print $makefile_extra{'lcc'};