Index: /trunk/src/kWorker/Makefile.kmk
===================================================================
--- /trunk/src/kWorker/Makefile.kmk	(revision 2893)
+++ /trunk/src/kWorker/Makefile.kmk	(revision 2894)
@@ -33,5 +33,10 @@
 kWorker_DEFS.debug = K_STRICT
 kWorker_DEFS.release = NASSERT
-kWorker_SOURCES = kWorker.c
+kWorker_SOURCES = \
+	kWorker.c \
+       ../kmk/kmkbuiltin/kDepObj.c
+kWorker_INCS = \
+	../kmk/ \
+	../kmk/kmkbuiltin
 kWorker_LIBS = \
 	$(kStuff_1_TARGET) \
@@ -56,7 +61,9 @@
 	crc32.c \
 	md5.c \
-       kbuild_version.c
+       kbuild_version.c \
+       kDep.c
 kWorkerLib_SOURCES.win = \
 	nt_fullpath.c \
+	nt_fullpath_cached.c \
 	quoted_spawn.c \
        nt/nthlpcore.c \
Index: /trunk/src/kWorker/kWorker.c
===================================================================
--- /trunk/src/kWorker/kWorker.c	(revision 2893)
+++ /trunk/src/kWorker/kWorker.c	(revision 2894)
@@ -53,4 +53,6 @@
 #include "quote_argv.h"
 #include "md5.h"
+
+#include "../kmk/kmkbuiltin.h"
 
 
@@ -6894,18 +6896,45 @@
 
 /**
+ * Does the post command part of a job (optional).
+ *
+ * @returns The exit code of the job.
+ * @param   cPostCmdArgs        Number of post command arguments (includes cmd).
+ * @param   papszPostCmdArgs    The post command and its argument.
+ */
+static int kSubmitHandleJobPostCmd(KU32 cPostCmdArgs, const char **papszPostCmdArgs)
+{
+    const char *pszCmd = papszPostCmdArgs[0];
+
+    /* Allow the kmk builtin prefix. */
+    static const char s_szKmkBuiltinPrefix[] = "kmk_builtin_";
+    if (kHlpStrNComp(pszCmd, s_szKmkBuiltinPrefix, sizeof(s_szKmkBuiltinPrefix) - 1) == 0)
+        pszCmd += sizeof(s_szKmkBuiltinPrefix) - 1;
+
+    /* Command switch. */
+    if (kHlpStrComp(pszCmd, "kDepObj") == 0)
+        return kmk_builtin_kDepObj(cPostCmdArgs, (char **)papszPostCmdArgs, NULL);
+
+    return kwErrPrintfRc(42 + 5 , "Unknown post command: '%s'\n", pszCmd);
+}
+
+
+/**
  * Part 2 of the "JOB" command handler.
  *
  * @returns The exit code of the job.
- * @param   pszExecutable   The executable to execute.
- * @param   pszCwd          The current working directory of the job.
- * @param   cArgs           The number of arguments.
- * @param   papszArgs       The argument vector.
+ * @param   pszExecutable       The executable to execute.
+ * @param   pszCwd              The current working directory of the job.
+ * @param   cArgs               The number of arguments.
+ * @param   papszArgs           The argument vector.
  * @param   fWatcomBrainDamange Whether to apply watcom rules while quoting.
- * @param   cEnvVars        The number of environment variables.
- * @param   papszEnvVars    The enviornment vector.
+ * @param   cEnvVars            The number of environment variables.
+ * @param   papszEnvVars        The enviornment vector.
+ * @param   cPostCmdArgs        Number of post command arguments (includes cmd).
+ * @param   papszPostCmdArgs    The post command and its argument.
  */
 static int kSubmitHandleJobUnpacked(const char *pszExecutable, const char *pszCwd,
                                     KU32 cArgs, const char **papszArgs, KBOOL fWatcomBrainDamange,
-                                    KU32 cEnvVars, const char **papszEnvVars)
+                                    KU32 cEnvVars, const char **papszEnvVars,
+                                    KU32 cPostCmdArgs, const char **papszPostCmdArgs)
 {
     int rcExit;
@@ -6972,4 +7001,10 @@
                 break;
         }
+
+        /*
+         * Do the post command, if present.
+         */
+        if (cPostCmdArgs && rcExit == 0)
+            rcExit = kSubmitHandleJobPostCmd(cPostCmdArgs, papszPostCmdArgs);
     }
     else
@@ -7063,5 +7098,4 @@
                             if (papszEnvVars)
                             {
-                                KU32 i;
                                 for (i = 0; i < cEnvVars; i++)
                                 {
@@ -7078,19 +7112,58 @@
                                 }
                                 papszEnvVars[cEnvVars] = 0;
+
+                                /* Flags (currently just watcom argument brain damanage). */
                                 if (cbMsg >= sizeof(KU8))
                                 {
                                     KBOOL fWatcomBrainDamange = *pszMsg++;
                                     cbMsg--;
-                                    if (cbMsg == 0)
+
+                                    /* Post command argument count (can be zero). */
+                                    if (cbMsg >= sizeof(KU32))
                                     {
-                                        /*
-                                         * The next step.
-                                         */
-                                        rcExit = kSubmitHandleJobUnpacked(pszExecutable, pszCwd,
-                                                                          cArgs, papszArgs, fWatcomBrainDamange,
-                                                                          cEnvVars, papszEnvVars);
+                                        KU32 cPostCmdArgs;
+                                        kHlpMemCopy(&cPostCmdArgs, pszMsg, sizeof(cPostCmdArgs));
+                                        pszMsg += sizeof(cPostCmdArgs);
+                                        cbMsg  -= sizeof(cPostCmdArgs);
+
+                                        if (cPostCmdArgs >= 0 && cPostCmdArgs < 32)
+                                        {
+                                            char const *apszPostCmdArgs[32+1];
+                                            for (i = 0; i < cPostCmdArgs; i++)
+                                            {
+                                                apszPostCmdArgs[i] = pszMsg;
+                                                cbTmp = kHlpStrLen(pszMsg) + 1;
+                                                pszMsg += cbTmp;
+                                                if (   cbTmp < cbMsg
+                                                    || (cbTmp == cbMsg && i + 1 == cPostCmdArgs))
+                                                    cbMsg -= cbTmp;
+                                                else
+                                                {
+                                                    cbMsg = KSIZE_MAX;
+                                                    break;
+                                                }
+                                            }
+                                            if (cbMsg == 0)
+                                            {
+                                                apszPostCmdArgs[cPostCmdArgs] = NULL;
+
+                                                /*
+                                                 * The next step.
+                                                 */
+                                                rcExit = kSubmitHandleJobUnpacked(pszExecutable, pszCwd,
+                                                                                  cArgs, papszArgs, fWatcomBrainDamange,
+                                                                                  cEnvVars, papszEnvVars,
+                                                                                  cPostCmdArgs, apszPostCmdArgs);
+                                            }
+                                            else if (cbMsg == KSIZE_MAX)
+                                                kwErrPrintf("Detected bogus message unpacking post command and its arguments!\n");
+                                            else
+                                                kwErrPrintf("Message has %u bytes unknown trailing bytes\n", cbMsg);
+                                        }
+                                        else
+                                            kwErrPrintf("Bogus post command argument count: %u %#x\n", cPostCmdArgs, cPostCmdArgs);
                                     }
                                     else
-                                        kwErrPrintf("Message has %u bytes unknown trailing bytes\n", cbMsg);
+                                        kwErrPrintf("Detected bogus message looking for the post command argument count!\n");
                                 }
                                 else
@@ -7281,5 +7354,6 @@
         rcExit = kSubmitHandleJobUnpacked(argv[i], pszCwd,
                                           argc - i, &argv[i], fWatcomBrainDamange,
-                                          cEnvVars, environ);
+                                          cEnvVars, environ,
+                                          0, NULL);
         KW_LOG(("rcExit=%d\n", rcExit));
         kwSandboxCleanupLate(&g_Sandbox);
Index: /trunk/src/kmk/kmkbuiltin/kDepObj.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/kDepObj.c	(revision 2893)
+++ /trunk/src/kmk/kmkbuiltin/kDepObj.c	(revision 2894)
@@ -28,5 +28,4 @@
 *******************************************************************************/
 #define MSCFAKES_NO_WINDOWS_H
-#include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -36,7 +35,4 @@
 #include <ctype.h>
 #include <stdarg.h>
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
 #if !defined(_MSC_VER)
 # include <unistd.h>
@@ -54,6 +50,5 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/*#define DEBUG*/
-#ifdef DEBUG
+#if 0
 # define dprintf(a)             printf a
 # define dump(pb, cb, offBase)  depHexDump(pb,cb,offBase)
@@ -576,5 +571,5 @@
  * @param   cbSyms      Size of the symbol section.
  */
-int kDepObjCOFFParseCV8SymbolSection(const KU8 *pbSyms, KSIZE cbSyms)
+int kDepObjCOFFParseCV8SymbolSection(const KU8 *pbSyms, KU32 cbSyms)
 {
     char const *    pchStrTab  = NULL;
@@ -765,5 +760,5 @@
     int                         rc;
 
-    printf("COFF file!\n");
+    dprintf(("COFF file!\n"));
 
     for (iSHdr = 0; iSHdr < cSHdrs; iSHdr++)
@@ -784,5 +779,5 @@
                 return rc;
         }
-        printf("#%d: %.8s\n", iSHdr, paSHdrs[iSHdr].Name);
+        dprintf(("#%d: %.8s\n", iSHdr, paSHdrs[iSHdr].Name));
     }
     return rcRet;
Index: /trunk/src/kmk/kmkbuiltin/kSubmit.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/kSubmit.c	(revision 2893)
+++ /trunk/src/kmk/kmkbuiltin/kSubmit.c	(revision 2894)
@@ -574,8 +574,12 @@
  * @param   pszCwd              The current directory.
  * @param   fWatcomBrainDamage  The wcc/wcc386 workaround.
+ * @param   papszPostCmdArgs    The post command and it's arguments.
+ * @param   cPostCmdArgs        Number of post command argument, including the
+ *                              command.  Zero if no post command scheduled.
  * @param   pcbMsg              Where to return the message length.
  */
 static void *kSubmitComposeJobMessage(const char *pszExecutable, char **papszArgs, char **papszEnvVars,
-                                      const char *pszCwd, int fWatcomBrainDamage, uint32_t *pcbMsg)
+                                      const char *pszCwd, int fWatcomBrainDamage,
+                                      char **papszPostCmdArgs, uint32_t cPostCmdArgs, uint32_t *pcbMsg)
 {
     size_t   cbTmp;
@@ -613,4 +617,8 @@
     cbMsg += 1;
 
+    cbMsg += sizeof(cPostCmdArgs);
+    for (i = 0; i < cPostCmdArgs; i++)
+        cbMsg += strlen(papszPostCmdArgs[i]) + 1;
+
     /*
      * Compose the message.
@@ -618,4 +626,5 @@
     pbMsg = pbCursor = xmalloc(cbMsg);
 
+    /* header */
     memcpy(pbCursor, &cbMsg, sizeof(cbMsg));
     pbCursor += sizeof(cbMsg);
@@ -623,12 +632,15 @@
     pbCursor += sizeof("JOB");
 
+    /* executable. */
     cbTmp = strlen(pszExecutable) + 1;
     memcpy(pbCursor, pszExecutable, cbTmp);
     pbCursor += cbTmp;
 
+    /* cwd */
     cbTmp = strlen(pszCwd) + 1;
     memcpy(pbCursor, pszCwd, cbTmp);
     pbCursor += cbTmp;
 
+    /* argument */
     memcpy(pbCursor, &cArgs, sizeof(cArgs));
     pbCursor += sizeof(cArgs);
@@ -642,4 +654,5 @@
     assert(i == cArgs);
 
+    /* environment */
     memcpy(pbCursor, &cEnvVars, sizeof(cEnvVars));
     pbCursor += sizeof(cEnvVars);
@@ -652,9 +665,23 @@
     assert(i == cEnvVars);
 
+    /* flags */
     *pbCursor++ = fWatcomBrainDamage != 0;
 
+    /* post command */
+    memcpy(pbCursor, &cPostCmdArgs, sizeof(cPostCmdArgs));
+    pbCursor += sizeof(cPostCmdArgs);
+    for (i = 0; i < cPostCmdArgs; i++)
+    {
+        cbTmp = strlen(papszPostCmdArgs[i]) + 1;
+        memcpy(pbCursor, papszPostCmdArgs[i], cbTmp);
+        pbCursor += cbTmp;
+    }
+    assert(i == cPostCmdArgs);
+
     assert(pbCursor - pbMsg == (size_t)cbMsg);
 
-    /* done */
+    /*
+     * Done.
+     */
     *pcbMsg = cbMsg;
     return pbMsg;
@@ -1339,5 +1366,6 @@
             "usage: %s [-Z|--zap-env] [-E|--set <var=val>] [-U|--unset <var=val>]\n"
             "           [-C|--chdir <dir>] [--wcc-brain-damage]\n"
-            "           [-3|--32-bit] [-6|--64-bit] [-v] -- <program> [args]\n"
+            "           [-3|--32-bit] [-6|--64-bit] [-v]\n"
+            "           [-P|--post-cmd <cmd> [args]] -- <program> [args]\n"
             "   or: %s --help\n"
             "   or: %s --version\n"
@@ -1362,4 +1390,8 @@
             "  -v,--verbose\n"
             "    More verbose execution.\n"
+            "  -P|--post-cmd <cmd> ...\n"
+            "    For running a built-in command on the output, specifying the command\n"
+            "    and all it's parameters.  Currently supported commands:\n"
+            "        kDepObj\n"
             "  -V,--version\n"
             "    Show the version number.\n"
@@ -1383,4 +1415,6 @@
     const char     *pszExecutable       = NULL;
     const char     *pszCwd              = NULL;
+    int             iPostCmd            = argc;
+    int             cPostCmdArgs        = 0;
     unsigned        cBitsWorker         = g_cArchBits;
     int             fWatcomBrainDamage  = 0;
@@ -1457,4 +1491,6 @@
                 else if (strcmp(pszArg, "chdir") == 0)
                     chOpt = 'C';
+                else if (strcmp(pszArg, "post-cmd") == 0)
+                    chOpt = 'P';
                 else if (strcmp(pszArg, "32-bit") == 0)
                     chOpt = '3';
@@ -1489,5 +1525,5 @@
                         else
                         {
-                            errx(1, "Option -%c requires an value!", chOpt);
+                            errx(1, "Option -%c requires a value!", chOpt);
                             return usage(stderr, argv[0]);
                         }
@@ -1524,4 +1560,18 @@
                         return rcExit;
 
+                    case 'P':
+                        if (cPostCmdArgs > 0)
+                            return errx(1, "The -P option can only be used once!");
+                        if (*pszArg != '\0')
+                            return errx(1, "The cmd part of the -P needs to be a separate argument!");
+                        iPostCmd = ++iArg;
+                        if (iArg >= argc)
+                            return errx(1, "The -P option requires a command following it!");
+                        while (iArg < argc && strcmp(argv[iArg], "--") != 0)
+                            iArg++;
+                        cPostCmdArgs = iArg - iPostCmd;
+                        iArg--;
+                        break;
+
                     case '3':
                         cBitsWorker = 32;
@@ -1563,5 +1613,5 @@
         uint32_t        cbMsg;
         void           *pvMsg   = kSubmitComposeJobMessage(pszExecutable, &argv[iArg], papszEnv, szCwd,
-                                                           fWatcomBrainDamage, &cbMsg);
+                                                           fWatcomBrainDamage, &argv[iPostCmd], cPostCmdArgs, &cbMsg);
         PWORKERINSTANCE pWorker = kSubmitSelectWorkSpawnNewIfNecessary(cBitsWorker, cVerbosity);
         if (pWorker)
Index: /trunk/src/lib/quote_argv.c
===================================================================
--- /trunk/src/lib/quote_argv.c	(revision 2893)
+++ /trunk/src/lib/quote_argv.c	(revision 2894)
@@ -114,4 +114,6 @@
             || (   !fWatcomBrainDamage
                 && (pszProblem = (const char *)memchr(pszOrg, '=',  cchOrg)) != NULL)
+            || (   fWatcomBrainDamage
+                && (pszProblem = (const char *)memchr(pszOrg, '\\', cchOrg)) != NULL)
             )
         {
