Index: /trunk/src/kDepPre/kDepPre.c
===================================================================
--- /trunk/src/kDepPre/kDepPre.c	(revision 3314)
+++ /trunk/src/kDepPre/kDepPre.c	(revision 3315)
@@ -469,6 +469,5 @@
     {
         depOptimize(&This, fFixCase, 0 /* fQuiet */, NULL /*pszIgnoredExt*/);
-        fprintf(pOutput, "%s:", pszTarget);
-        depPrint(&This, pOutput);
+        depPrintTargetWithDeps(&This, pOutput, pszTarget, 1 /*fEscapeTarget*/);
         if (fStubs)
             depPrintStubs(&This, pOutput);
Index: /trunk/src/kObjCache/kObjCache.c
===================================================================
--- /trunk/src/kObjCache/kObjCache.c	(revision 3314)
+++ /trunk/src/kObjCache/kObjCache.c	(revision 3315)
@@ -1134,7 +1134,6 @@
         *psz++ = '/';
 
-    fprintf(pFile, "%s:", pszObjFileAbs);
+    depPrintTargetWithDeps(&pDepState->Core, pFile, pszObjFileAbs, 1 /*fEscapeTarget*/);
     free(pszObjFileAbs);
-    depPrint(&pDepState->Core, pFile);
     if (fGenStubs)
         depPrintStubs(&pDepState->Core, pFile);
Index: /trunk/src/kmk/kmkbuiltin/kDepIDB.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/kDepIDB.c	(revision 3314)
+++ /trunk/src/kmk/kmkbuiltin/kDepIDB.c	(revision 3315)
@@ -830,6 +830,5 @@
     {
         depOptimize(&This.Core, fFixCase, fQuiet, NULL /*pszIgnoredExt*/);
-        fprintf(pOutput, "%s:", pszTarget);
-        depPrint(&This.Core, pOutput);
+        depPrintTargetWithDeps(&This.Core, pOutput, pszTarget, 1 /*fEscapeTarget*/);
         if (fStubs)
             depPrintStubs(&This.Core, pOutput);
Index: /trunk/src/kmk/kmkbuiltin/kDepObj.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/kDepObj.c	(revision 3314)
+++ /trunk/src/kmk/kmkbuiltin/kDepObj.c	(revision 3315)
@@ -1188,6 +1188,5 @@
     {
         depOptimize(&This.Core, fFixCase, fQuiet, pszIgnoreExt);
-        fprintf(pOutput, "%s:", pszTarget);
-        depPrint(&This.Core, pOutput);
+        depPrintTargetWithDeps(&This.Core, pOutput, pszTarget, 1 /*fEscapeTarget*/);
         if (fStubs)
             depPrintStubs(&This.Core, pOutput);
Index: /trunk/src/lib/kDep.c
===================================================================
--- /trunk/src/lib/kDep.c	(revision 3314)
+++ /trunk/src/lib/kDep.c	(revision 3315)
@@ -326,4 +326,109 @@
 
 /**
+ * Write a filename that contains characters that needs escaping.
+ *
+ * @param   pOutput The output stream.
+ * @param   pszFile The filename.
+ * @param   cchFile The length of the filename.
+ * @param   fDep    Whether this is for a dependency file or a target file.
+ */
+int depNeedsEscaping(const char *pszFile, size_t cchFile, int fDependency)
+{
+    return memchr(pszFile, ' ',  cchFile) != NULL
+        || memchr(pszFile, '\t', cchFile) != NULL
+        || memchr(pszFile, '#',  cchFile) != NULL
+        || memchr(pszFile, '=',  cchFile) != NULL
+        || memchr(pszFile, ';',  cchFile) != NULL
+        || memchr(pszFile, '$',  cchFile) != NULL
+        || memchr(pszFile, fDependency ? '|' : '%',  cchFile) != NULL;
+}
+
+
+/**
+ * Write a filename that contains characters that needs escaping.
+ *
+ * @param   pOutput The output stream.
+ * @param   pszFile The filename.
+ * @param   cchFile The length of the filename.
+ * @param   fDep    Whether this is for a dependency file or a target file.
+ */
+void depEscapedWrite(FILE *pOutput, const char *pszFile, size_t cchFile, int fDepenency)
+{
+    size_t cchWritten = 0;
+    size_t off        = 0;
+    while (off < cchFile)
+    {
+        char const ch = pszFile[off];
+        switch (ch)
+        {
+            default:
+                off++;
+                break;
+
+            /*
+             * Escaped by slash, but any preceeding slashes must be escaped too.
+             * A couple of characters are only escaped on one side of the ':'.
+             */
+            case '%': /* target side only */
+            case '|': /* dependency side only */
+                if (ch != (fDepenency ? '|' : '%'))
+                {
+                    off++;
+                    break;
+                }
+                /* fall thru */
+            case ' ':
+            case '\t':
+            case '#':
+            case '=': /** @todo buggy GNU make handling */
+            case ';': /** @todo buggy GNU make handling */
+                if (cchWritten < off)
+                    fwrite(&pszFile[cchWritten], off - cchWritten, 1, pOutput);
+                if (off == 0 || pszFile[off - 1] != '\\')
+                {
+                    fputc('\\', pOutput);
+                    cchWritten = off; /* We write the escaped character with the next bunch. */
+                }
+                else
+                {
+                    size_t cchSlashes = 1;
+                    while (cchSlashes < off && pszFile[off - cchSlashes - 1] == '\\')
+                        cchSlashes++;
+                    fwrite(&pszFile[off - cchSlashes], cchSlashes, 1, pOutput);
+                    cchWritten = off - 1; /* Write a preceeding slash and the escaped character with the next bunch. */
+                }
+                off += 1;
+                break;
+
+            /*
+             * Escaped by doubling it.
+             * Implemented by including in the pending writeout job as well as in the next one.
+             */
+            case '$':
+                fwrite(&pszFile[cchWritten], off - cchWritten + 1, 1, pOutput);
+                cchWritten = off++; /* write it again the next time */
+                break;
+        }
+    }
+
+    /* Remainder: */
+    if (cchWritten < cchFile)
+        fwrite(&pszFile[cchWritten], cchFile - cchWritten, 1, pOutput);
+}
+
+
+/**
+ * Escapes all trailing trailing slashes in a filename that ends with such.
+ */
+static void depPrintTrailngSlashEscape(FILE *pOutput, const char *pszFilename, size_t cchFilename)
+{
+    size_t cchSlashes = 1;
+    while (cchSlashes < cchFilename && pszFilename[cchFilename - cchSlashes - 1] == '\\')
+        cchSlashes++;
+    fwrite(&pszFilename[cchFilename - cchSlashes], cchSlashes, 1, pOutput);
+}
+
+
+/**
  * Prints the dependency chain.
  *
@@ -331,24 +436,83 @@
  * @param   pOutput     Output stream.
  */
-void depPrint(PDEPGLOBALS pThis, FILE *pOutput)
-{
+void depPrintChain(PDEPGLOBALS pThis, FILE *pOutput)
+{
+    static char const g_szEntryText[]     = " \\\n\t";
+    static char const g_szTailText[]      = "\n\n";
+    static char const g_szTailSlashText[] = " \\\n\n";
+    PDEP              pDep;
+    for (pDep = pThis->pDeps; pDep; pDep = pDep->pNext)
+    {
+        fwrite(g_szEntryText, sizeof(g_szEntryText) - 1, 1, pOutput);
+        if (!pDep->fNeedsEscaping)
+            fwrite(pDep->szFilename, pDep->cchFilename, 1, pOutput);
+        else
+            depEscapedWrite(pOutput, pDep->szFilename, pDep->cchFilename, 1 /*fDependency*/);
+        if (pDep->fTrailingSlash)
+        {   /* Escape only if more dependencies.  If last, we must add a line continuation or it won't work. */
+            if (pDep->pNext)
+                depPrintTrailngSlashEscape(pOutput, pDep->szFilename, pDep->cchFilename);
+            else
+            {
+                fwrite(g_szTailSlashText, sizeof(g_szTailSlashText), 1, pOutput);
+                return;
+            }
+        }
+    }
+
+    fwrite(g_szTailText, sizeof(g_szTailText) - 1, 1, pOutput);
+}
+
+
+/**
+ * Prints the dependency chain with a preceeding target.
+ *
+ * @param   pThis           The 'dep' instance.
+ * @param   pOutput         Output stream.
+ * @param   pszTarget       The target filename.
+ * @param   fEscapeTarget   Whether to consider escaping the target.
+ */
+void depPrintTargetWithDeps(PDEPGLOBALS pThis, FILE *pOutput, const char *pszTarget, int fEscapeTarget)
+{
+    static char const g_szSeparator[] = ":";
+    size_t const cchTarget = strlen(pszTarget);
+    if (!fEscapeTarget || !depNeedsEscaping(pszTarget, cchTarget, 0 /*fDependency*/))
+        fwrite(pszTarget, cchTarget, 1, pOutput);
+    else
+        depEscapedWrite(pOutput, pszTarget, cchTarget, 0 /*fDependency*/);
+
+    if (cchTarget == 0 || pszTarget[cchTarget - 1] != '\\')
+    { /* likely */ }
+    else
+        depPrintTrailngSlashEscape(pOutput, pszTarget, cchTarget);
+    fwrite(g_szSeparator, sizeof(g_szSeparator) - 1, 1, pOutput);
+
+    depPrintChain(pThis, pOutput);
+}
+
+
+/**
+ * Prints empty dependency stubs for all dependencies.
+ *
+ * @param   pThis       The 'dep' instance.
+ * @param   pOutput     Output stream.
+ */
+void depPrintStubs(PDEPGLOBALS pThis, FILE *pOutput)
+{
+    static char g_szTailText[] = ":\n\n";
     PDEP pDep;
     for (pDep = pThis->pDeps; pDep; pDep = pDep->pNext)
-        fprintf(pOutput, " \\\n\t%s", pDep->szFilename);
-    fprintf(pOutput, "\n\n");
-}
-
-
-/**
- * Prints empty dependency stubs for all dependencies.
- *
- * @param   pThis       The 'dep' instance.
- * @param   pOutput     Output stream.
- */
-void depPrintStubs(PDEPGLOBALS pThis, FILE *pOutput)
-{
-    PDEP pDep;
-    for (pDep = pThis->pDeps; pDep; pDep = pDep->pNext)
-        fprintf(pOutput, "%s:\n\n", pDep->szFilename);
+    {
+        if (!pDep->fNeedsEscaping && memchr(pDep->szFilename, '%', pDep->cchFilename) == 0)
+            fwrite(pDep->szFilename, pDep->cchFilename, 1, pOutput);
+        else
+            depEscapedWrite(pOutput, pDep->szFilename, pDep->cchFilename, 0 /*fDependency*/);
+
+        if (pDep->cchFilename == 0 || !pDep->fTrailingSlash)
+        { /* likely */ }
+        else
+            depPrintTrailngSlashEscape(pOutput, pDep->szFilename, pDep->cchFilename);
+        fwrite(g_szTailText, sizeof(g_szTailText) - 1, 1, pOutput);
+    }
 }
 
@@ -415,4 +579,6 @@
     memcpy(pDep->szFilename, pszFilename, cchFilename);
     pDep->szFilename[cchFilename] = '\0';
+    pDep->fNeedsEscaping = depNeedsEscaping(pszFilename, cchFilename, 1 /*fDependency*/);
+    pDep->fTrailingSlash = cchFilename > 0 && pszFilename[cchFilename - 1] == '\\';
     pDep->uHash = uHash;
 
Index: /trunk/src/lib/kDep.h
===================================================================
--- /trunk/src/lib/kDep.h	(revision 3314)
+++ /trunk/src/lib/kDep.h	(revision 3315)
@@ -40,4 +40,8 @@
     /** The filename hash. */
     unsigned    uHash;
+    /** Set if needs escaping. */
+    char        fNeedsEscaping;
+    /** Set if filename ends with a slash and may require special processing. */
+    char        fTrailingSlash;
     /** The length of the filename. */
     size_t      cchFilename;
@@ -58,5 +62,8 @@
 extern PDEP depAdd(PDEPGLOBALS pThis, const char *pszFilename, size_t cchFilename);
 extern void depOptimize(PDEPGLOBALS pThis, int fFixCase, int fQuiet, const char *pszIgnoredExt);
-extern void depPrint(PDEPGLOBALS pThis, FILE *pOutput);
+extern int  depNeedsEscaping(const char *pszFile, size_t cchFile, int fDependency);
+extern void depEscapedWrite(FILE *pOutput, const char *pszFile, size_t cchFile, int fDepenency);
+extern void depPrintChain(PDEPGLOBALS pThis, FILE *pOutput);
+extern void depPrintTargetWithDeps(PDEPGLOBALS pThis, FILE *pOutput, const char *pszTarget, int fEscapeTarget);
 extern void depPrintStubs(PDEPGLOBALS pThis, FILE *pOutput);
 
