diff -ur make-3.82/file.c make-wch/file.c
--- make-3.82/file.c	2010-07-12 21:20:39.000000000 -0400
+++ make-wch/file.c	2010-08-19 23:28:20.162660391 -0400
@@ -1021,6 +1021,129 @@
   hash_print_stats (&files, stdout);
 }
 
+/* Dump the dependency graph to a Graphviz file (on stdout)  */
+
+void
+print_graph_prereqs (const char *filename, const struct dep *deps)
+{
+  const struct dep *ood = 0;
+
+  /* Print all normal dependencies; note any order-only deps.  */
+  for (; deps != 0; deps = deps->next)
+    if (! deps->ignore_mtime)
+      printf ("  \"%s\" -> \"%s\";\n", filename, dep_name (deps));
+
+  /* Print order-only deps, if we have any.  */
+  if (ood)
+    {
+      for (ood = ood->next; ood != 0; ood = ood->next)
+        if (ood->ignore_mtime)
+          printf ("    %s -> %s [style=dotted];\n", filename, dep_name (ood));
+          /* XXX: we need to distinguish these some how.
+           * Is dotting them the right way? */
+    }
+}
+
+static void
+print_graph_file (const void *item)
+{
+  const struct file *f = item;
+
+  int built_in_special_target=(
+       (0==strcmp(f->name,".PHONY"))
+    || (0==strcmp(f->name,".SUFFIXES"))
+    || (0==strcmp(f->name,".DEFAULT"))
+    || (0==strcmp(f->name,".PRECIOUS"))
+    || (0==strcmp(f->name,".INTERMEDIATE"))
+    || (0==strcmp(f->name,".SECONDARY"))
+    || (0==strcmp(f->name,".SECONDEXPANSION"))
+    || (0==strcmp(f->name,".DELETE_ON_ERROR"))
+    || (0==strcmp(f->name,".IGNORE"))
+    || (0==strcmp(f->name,".LOW_RESOLUTION_TIME"))
+    || (0==strcmp(f->name,".SILENT"))
+    || (0==strcmp(f->name,".EXPORT_ALL_VARIABLES"))
+    || (0==strcmp(f->name,".NOTPARALLEL"))
+    || (0==strcmp(f->name,".ONESHELL"))
+    || (0==strcmp(f->name,".POSIX"))
+    );
+  if ((f->is_target) && (!built_in_special_target))
+    {
+      printf ("  \"%s\" [", f->name);
+      /* XXX some of these should be attached to the nodes in some way;
+       * though I'm not sure what style changes should be made for which ones.
+       *  ~ LukeShu
+      if (f->double_colon)   puts (_("// Double-colon rule."));
+      if (f->precious)       puts (_("// Precious file (prerequisite of .PRECIOUS)."));
+    */if (f->phony)          puts (_(" color=blue "));/*
+      if (f->cmd_target)     puts (_("// Command line target."));
+      if (f->dontcare)       puts (_("// A default, MAKEFILES, or -include/sinclude makefile."));
+      if (f->tried_implicit) puts (_("// Implicit rule search has been done."));
+      else                   puts (_("// Implicit rule search has not been done."));
+      if (f->stem != 0)    printf (_("// Implicit/static pattern stem: `%s'\n"), f->stem);
+      if (f->intermediate)   puts (_("// File is an intermediate prerequisite."));
+      if (f->also_make != 0)
+        {
+          const struct dep *d;
+          fputs (_("#  Also makes:"), stdout);
+          for (d = f->also_make; d != 0; d = d->next)
+          printf (" %s\n", dep_name (d));
+        }
+           if (f->last_mtime == UNKNOWN_MTIME)     puts (_("// Modification time never checked."));
+      else if (f->last_mtime == NONEXISTENT_MTIME) puts (_("// File does not exist."));
+      else if (f->last_mtime == OLD_MTIME)         puts (_("// File is very old."));
+      else
+        {
+          char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
+          file_timestamp_sprintf (buf, f->last_mtime);
+          printf (_("// Last modified %s\n"), buf);
+        }
+      if (f->updated) puts (_("// File has been updated."));
+      else            puts (_("// File has not been updated."));
+      switch (f->command_state)
+        {
+        case cs_running:      puts (_("// Update: Running (THIS IS A BUG).")); break;
+        case cs_deps_running: puts (_("// Update: Dependencies running (THIS IS A BUG).")); break;
+        case cs_not_started:
+        case cs_finished:
+          switch (f->update_status)
+	    {
+	    case -1: break;
+	    case 0:  puts (_("// Update: Successfully")); break;
+	    case 1:  assert (question_flag);
+	             puts (_("// Update: Needs to be (-q is set)")); break;
+	    case 2:  puts (_("// Update: Failed")); break;
+	    default: puts (_("// Update: Invalid `update_status' value));
+	            fflush (stdout);
+	            fflush (stderr);
+	            abort ();
+	    }
+          break;
+        default: puts (_("// Update: Invalid `command_state' value"));
+                 fflush (stdout);
+                 fflush (stderr);
+                 abort ();
+        }
+      if (f->variables != 0) print_file_variables (f);
+      if (f->cmds != 0) print_commands (f->cmds);
+      */
+      puts("];");
+      print_graph_prereqs (f->name, f->deps);
+    }
+  
+  if (f->prev)
+    print_graph_file ((const void *) f->prev);
+}
+
+void
+print_graph (void)
+{
+  printf ("%sgraph make%i {\n",
+          (makelevel==0)?"di":"sub",
+          getpid());
+  hash_map (&files, print_graph_file);
+  puts ("}");
+}
+
 /* Verify the integrity of the data base of files.  */
 
 #define VERIFY_CACHED(_p,_n) \
diff -ur make-3.82/filedef.h make-wch/filedef.h
--- make-3.82/filedef.h	2010-07-12 21:20:39.000000000 -0400
+++ make-wch/filedef.h	2010-08-19 21:09:34.314660209 -0400
@@ -116,6 +116,7 @@
 char *build_target_list (char *old_list);
 void print_prereqs (const struct dep *deps);
 void print_file_data_base (void);
+void print_graph (void);
 
 #if FILE_TIMESTAMP_HI_RES
 # define FILE_TIMESTAMP_STAT_MODTIME(fname, st) \
diff -ur make-3.82/main.c make-wch/main.c
--- make-3.82/main.c	2010-07-19 03:10:53.000000000 -0400
+++ make-wch/main.c	2010-08-21 22:32:56.818417305 -0400
@@ -175,6 +175,11 @@
 
 int print_data_base_flag = 0;
 
+/* Nonzero means don't remake anything, just print the dependency graph
+   that results from reading the makefile (-g).  */
+
+int print_graph_flag = 0;
+
 /* Nonzero means don't remake anything; just return a nonzero status
    if the specified targets are not up to date (-q).  */
 
@@ -321,6 +326,9 @@
   -f FILE, --file=FILE, --makefile=FILE\n\
                               Read FILE as a makefile.\n"),
     N_("\
+  -g, --graph                 Print make's internal dependency graph\n\
+                              in Graphviz format, without remaking makefiles.\n"),
+    N_("\
   -h, --help                  Print this message and exit.\n"),
     N_("\
   -i, --ignore-errors         Ignore errors from recipes.\n"),
@@ -385,6 +393,7 @@
 #endif
     { 'e', flag, &env_overrides, 1, 1, 0, 0, 0, "environment-overrides", },
     { 'f', filename, &makefiles, 0, 0, 0, 0, 0, "file" },
+    { 'g', flag, &print_graph_flag, 1, 1, 0, 0, 0, "graph" },
     { 'h', flag, &print_usage_flag, 0, 0, 0, 0, 0, "help" },
     { 'i', flag, &ignore_errors_flag, 1, 1, 0, 0, 0, "ignore-errors" },
     { 'I', filename, &include_directories, 1, 1, 0, 0, 0,
@@ -1946,7 +1955,10 @@
       define_makeflags (1, 1);
 
       rebuilding_makefiles = 1;
-      status = update_goal_chain (read_makefiles);
+      if (print_graph_flag)
+        status = -1;
+      else
+        status = update_goal_chain (read_makefiles);
       rebuilding_makefiles = 0;
 
       switch (status)
@@ -2278,33 +2290,37 @@
 
   {
     int status;
+    if (print_graph_flag)
+      status=0;
+    else
+      {
+        switch (update_goal_chain (goals))
+        {
+          case -1:
+            /* Nothing happened.  */
+          case 0:
+            /* Updated successfully.  */
+            status = makefile_status;
+            break;
+          case 1:
+            /* We are under -q and would run some commands.  */
+            status = MAKE_TROUBLE;
+            break;
+          case 2:
+            /* Updating failed.  POSIX.2 specifies exit status >1 for this;
+               but in VMS, there is only success and failure.  */
+            status = MAKE_FAILURE;
+            break;
+          default:
+            abort ();
+        }
 
-    switch (update_goal_chain (goals))
-    {
-      case -1:
-        /* Nothing happened.  */
-      case 0:
-        /* Updated successfully.  */
-        status = makefile_status;
-        break;
-      case 1:
-        /* We are under -q and would run some commands.  */
-        status = MAKE_TROUBLE;
-        break;
-      case 2:
-        /* Updating failed.  POSIX.2 specifies exit status >1 for this;
-           but in VMS, there is only success and failure.  */
-        status = MAKE_FAILURE;
-        break;
-      default:
-        abort ();
-    }
-
-    /* If we detected some clock skew, generate one last warning */
-    if (clock_skew_detected)
-      error (NILF,
-             _("warning:  Clock skew detected.  Your build may be incomplete."));
-
+        /* If we detected some clock skew, generate one last warning */
+        if (clock_skew_detected)
+          error (NILF,
+                 _("warning:  Clock skew detected.  Your build may be incomplete."));
+      }
+      
     /* Exit.  */
     die (status);
   }
@@ -3042,7 +3058,7 @@
 {
   static int printed_version = 0;
 
-  char *precede = print_data_base_flag ? "# " : "";
+  char *precede = (print_data_base_flag||print_graph_flag) ? "# " : "";
 
   if (printed_version)
     /* Do it only once.  */
@@ -3188,6 +3204,10 @@
       if (print_data_base_flag)
 	print_data_base ();
 
+
+      if (print_graph_flag)
+        print_graph ();
+
       verify_file_data_base ();
 
       clean_jobserver (status);