<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 27, 2015 at 11:14 AM, Paul Robinson <span dir="ltr"><<a href="mailto:paul_robinson@playstation.sony.com" target="_blank">paul_robinson@playstation.sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: probinson<br>
Date: Mon Apr 27 13:14:32 2015<br>
New Revision: 235903<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=235903&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=235903&view=rev</a><br>
Log:<br>
Support generating NMake/Jom-style depfiles.<br>
<br>
NMake is a Make-like builder that comes with Microsoft Visual Studio.<br>
Jom (<a href="https://wiki.qt.io/Jom" target="_blank">https://wiki.qt.io/Jom</a>) is an NMake-compatible build tool.<br>
Dependency files for NMake/Jom need to use double-quotes to wrap<br>
filespecs containing special characters, instead of the backslash<br>
escapes that GNU Make wants.<br>
<br>
Adds the -MV option, which specifies to use double-quotes as needed<br>
instead of backslash escapes when writing the dependency file.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D9260" target="_blank">http://reviews.llvm.org/D9260</a><br>
<br>
Modified:<br>
    cfe/trunk/docs/UsersManual.rst<br>
    cfe/trunk/include/clang/Driver/Options.td<br>
    cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
    cfe/trunk/lib/Frontend/DependencyFile.cpp<br>
    cfe/trunk/test/Frontend/dependency-gen-escaping.c<br>
<br>
Modified: cfe/trunk/docs/UsersManual.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/docs/UsersManual.rst (original)<br>
+++ cfe/trunk/docs/UsersManual.rst Mon Apr 27 13:14:32 2015<br>
@@ -589,6 +589,25 @@ Current limitations<br>
    translated from debug annotations. That translation can be lossy,<br>
    which results in some remarks having no location information.<br>
<br>
+Other Options<br>
+-------------<br>
+Clang options that that don't fit neatly into other categories.<br>
+<br>
+.. option:: -MV<br>
+<br>
+  When emitting a dependency file, use formatting conventions appropriate<br>
+  for NMake or Jom. Ignored unless another option causes Clang to emit a<br>
+  dependency file.<br>
+<br>
+When Clang emits a dependency file (e.g., you supplied the -M option)<br>
+most filenames can be written to the file without any special formatting.<br>
+Different Make tools will treat different sets of characters as "special"<br>
+and use different conventions for telling the Make tool that the character<br>
+is actually part of the filename. Normally Clang uses backslash to "escape"<br>
+a special character, which is the convention used by GNU Make. The -MV<br>
+option tells Clang to put double-quotes around the entire filename, which<br>
+is the convention used by NMake and Jom.<br>
+<br>
<br>
 Language and Target-Independent Features<br>
 ========================================<br>
<br>
Modified: cfe/trunk/include/clang/Driver/Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Driver/Options.td (original)<br>
+++ cfe/trunk/include/clang/Driver/Options.td Mon Apr 27 13:14:32 2015<br>
@@ -250,6 +250,8 @@ def MQ : JoinedOrSeparate<["-"], "MQ">,<br>
     HelpText<"Specify name of main file output to quote in depfile">;<br>
 def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,<br>
     HelpText<"Specify name of main file output in depfile">;<br>
+def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,<br>
+    HelpText<"Use NMake/Jom format for the depfile">;<br>
 def Mach : Flag<["-"], "Mach">;<br>
 def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;<br>
 def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;<br>
<br>
Modified: cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h (original)<br>
+++ cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h Mon Apr 27 13:14:32 2015<br>
@@ -15,6 +15,9 @@<br>
<br>
 namespace clang {<br>
<br>
+/// DependencyOutputFormat - Format for the compiler dependency file.<br>
+enum class DependencyOutputFormat { Make, NMake };<br>
+<br>
 /// DependencyOutputOptions - Options for controlling the compiler dependency<br>
 /// file generation.<br>
 class DependencyOutputOptions {<br>
@@ -27,7 +30,10 @@ public:<br>
   unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list<br>
   unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.<br>
   unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.<br>
-<br>
+<br>
+  /// The format for the dependency file.<br>
+  DependencyOutputFormat OutputFormat;<br>
+<br>
   /// The file to write dependency output to.<br>
   std::string OutputFile;<br>
<br>
@@ -55,6 +61,7 @@ public:<br>
     AddMissingHeaderDeps = 0;<br>
     PrintShowIncludes = 0;<br>
     IncludeModuleFiles = 0;<br>
+    OutputFormat = DependencyOutputFormat::Make;<br>
   }<br>
 };<br>
<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Mon Apr 27 13:14:32 2015<br>
@@ -338,6 +338,7 @@ void Clang::AddPreprocessingOptions(Comp<br>
   }<br>
<br>
   Args.AddLastArg(CmdArgs, options::OPT_MP);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_MV);<br>
<br>
   // Convert all -MQ <target> args to -MT <quoted target><br>
   for (arg_iterator it = Args.filtered_begin(options::OPT_MT,<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Mon Apr 27 13:14:32 2015<br>
@@ -661,6 +661,8 @@ static void ParseDependencyOutputArgs(De<br>
   Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);<br>
   Opts.ModuleDependencyOutputDir =<br>
       Args.getLastArgValue(OPT_module_dependency_dir);<br>
+  if (Args.hasArg(OPT_MV))<br>
+    Opts.OutputFormat = DependencyOutputFormat::NMake;<br>
 }<br>
<br>
 bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,<br>
<br>
Modified: cfe/trunk/lib/Frontend/DependencyFile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DependencyFile.cpp?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DependencyFile.cpp?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/DependencyFile.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/DependencyFile.cpp Mon Apr 27 13:14:32 2015<br>
@@ -150,6 +150,8 @@ class DFGImpl : public PPCallbacks {<br>
   bool AddMissingHeaderDeps;<br>
   bool SeenMissingHeader;<br>
   bool IncludeModuleFiles;<br>
+  DependencyOutputFormat OutputFormat;<br>
+<br>
 private:<br>
   bool FileMatchesDepCriteria(const char *Filename,<br>
                               SrcMgr::CharacteristicKind FileType);<br>
@@ -162,7 +164,8 @@ public:<br>
       PhonyTarget(Opts.UsePhonyTargets),<br>
       AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),<br>
       SeenMissingHeader(false),<br>
-      IncludeModuleFiles(Opts.IncludeModuleFiles) {}<br>
+      IncludeModuleFiles(Opts.IncludeModuleFiles),<br>
+      OutputFormat(Opts.OutputFormat) {}<br>
<br>
   void FileChanged(SourceLocation Loc, FileChangeReason Reason,<br>
                    SrcMgr::CharacteristicKind FileType,<br>
@@ -290,8 +293,23 @@ void DFGImpl::AddFilename(StringRef File<br>
 }<br>
<br>
 /// PrintFilename - GCC escapes spaces, # and $, but apparently not ' or " or<br>
-/// other scary characters.<br>
-static void PrintFilename(raw_ostream &OS, StringRef Filename) {<br>
+/// other scary characters. NMake/Jom has a different set of scary characters,<br>
+/// but wraps filespecs in double-quotes to avoid misinterpreting them;<br>
+/// <a href="https://msdn.microsoft.com/en-us/library/dd9y37ha.aspx" target="_blank">https://msdn.microsoft.com/en-us/library/dd9y37ha.aspx</a> for NMake info,<br>
+/// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx" target="_blank">https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx</a><br>
+/// for Windows file-naming info.<br>
+static void PrintFilename(raw_ostream &OS, StringRef Filename,<br>
+                          DependencyOutputFormat OutputFormat) {<br>
+  if (OutputFormat == DependencyOutputFormat::NMake) {<br>
+    // Add quotes if needed. These are the characters listed as "special" to<br>
+    // NMake, that are legal in a Windows filespec, and that could cause<br>
+    // misinterpretation of the dependency string.<br>
+    if (Filename.find_first_of(" #${}^!") != StringRef::npos)<br>
+      OS << '\"' << Filename << '\"';<br>
+    else<br>
+      OS << Filename;<br>
+    return;<br>
+  }<br>
   for (unsigned i = 0, e = Filename.size(); i != e; ++i) {<br>
     if (Filename[i] == ' ' || Filename[i] == '#')<br>
       OS << '\\';<br>
@@ -354,7 +372,7 @@ void DFGImpl::OutputDependencyFile() {<br>
       Columns = 2;<br>
     }<br>
     OS << ' ';<br>
-    PrintFilename(OS, *I);<br>
+    PrintFilename(OS, *I, OutputFormat);<br>
     Columns += N + 1;<br>
   }<br>
   OS << '\n';<br>
@@ -365,7 +383,7 @@ void DFGImpl::OutputDependencyFile() {<br>
     for (std::vector<std::string>::iterator I = Files.begin() + 1,<br>
            E = Files.end(); I != E; ++I) {<br>
       OS << '\n';<br>
-      PrintFilename(OS, *I);<br>
+      PrintFilename(OS, *I, OutputFormat);<br>
       OS << ":\n";<br>
     }<br>
   }<br>
<br>
Modified: cfe/trunk/test/Frontend/dependency-gen-escaping.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/dependency-gen-escaping.c?rev=235903&r1=235902&r2=235903&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/dependency-gen-escaping.c?rev=235903&r1=235902&r2=235903&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Frontend/dependency-gen-escaping.c (original)<br>
+++ cfe/trunk/test/Frontend/dependency-gen-escaping.c Mon Apr 27 13:14:32 2015<br>
@@ -4,13 +4,22 @@<br>
 // RUN: echo > '%t.dir/    .h'<br>
 // RUN: echo > '%t.dir/$$.h'<br>
 // RUN: echo > '%t.dir/##.h'<br>
+// RUN: echo > '%t.dir/normal.h'<br>
 // RUN: cd %t.dir<br>
 // RUN: %clang -MD -MF - %s -fsyntax-only -I. | FileCheck -strict-whitespace %s<br>
+// RUN: %clang -MD -MF - -MV %s -fsyntax-only -I. | FileCheck -strict-whitespace %s --check-prefix=QUOTE<br>
<br>
 // CHECK: \ \ \ \ .h<br>
 // CHECK: $$$$.h<br>
 // CHECK: \#\#.h<br>
+// QUOTE: "    .h"<br>
+// QUOTE: "$$.h"<br>
+// QUOTE: "##.h"<br>
+// QUOTE-NOT: "<br>
+// QUOTE: normal.h<br>
+// QUOTE-NOT: "<br>
<br>
 #include "    .h"<br>
 #include "$$.h"<br>
 #include "##.h"<br>
+#include "normal.h"<br></blockquote><div><br></div><div>Did you mean to update this to --check-prefix=NMAKE or something like that when you changed from a `bool Quote` to using the enum?</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>