=== modified file 'Source/cmGlobalNinjaGenerator.cxx'
--- old/Source/cmGlobalNinjaGenerator.cxx	2012-05-24 17:38:13 +0000
+++ new/Source/cmGlobalNinjaGenerator.cxx	2012-06-02 22:41:28 +0000
@@ -173,6 +173,8 @@
       i != variables.end();
       ++i)
     cmGlobalNinjaGenerator::WriteVariable(os, i->first, i->second, "", 1);
+
+  os << "\n";
 }
 
 void cmGlobalNinjaGenerator::WritePhonyBuild(std::ostream& os,
@@ -200,6 +202,7 @@
                 "$DESC",
                 "Rule for running custom commands.",
                 /*depfile*/ "",
+                /*rspfile*/ "",
                 /*restat*/ true);
 }
 
@@ -233,6 +236,7 @@
                                        const std::string& description,
                                        const std::string& comment,
                                        const std::string& depfile,
+                                       const std::string& rspfile,
                                        bool restat,
                                        bool generator)
 {
@@ -277,6 +281,14 @@
     os << "description = " << description << "\n";
     }
 
+  if(!rspfile.empty())
+    {
+      cmGlobalNinjaGenerator::Indent(os, 1);
+      os << "rspfile = " << rspfile << "\n";
+      cmGlobalNinjaGenerator::Indent(os, 1);
+      os << "rspfile_content = $in" << "\n";
+    }
+
   if(restat)
     {
     cmGlobalNinjaGenerator::Indent(os, 1);
@@ -481,6 +493,7 @@
                                      const std::string& description,
                                      const std::string& comment,
                                      const std::string& depfile,
+                                     const std::string& rspfile,
                                      bool restat,
                                      bool generator)
 {
@@ -495,6 +508,7 @@
                                     description,
                                     comment,
                                     depfile,
+                                    rspfile,
                                     restat,
                                     generator);
 }
@@ -799,6 +813,7 @@
             "Re-running CMake...",
             "Rule for re-running cmake.",
             /*depfile=*/ "",
+            /*rspfile=*/ "",
             /*restat=*/ false,
             /*generator=*/ true);
 
@@ -830,12 +845,21 @@
 
 void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
 {
+  cmLocalGenerator *lg = this->LocalGenerators[0];
+  cmMakefile* mfRoot = lg->GetMakefile();
+
+  std::ostringstream cmd;
+  cmd << lg->ConvertToOutputFormat(
+    mfRoot->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"),
+    cmLocalGenerator::SHELL) << " -t clean";
+
   WriteRule(*this->RulesFileStream,
             "CLEAN",
-            "ninja -t clean",
+            cmd.str(),
             "Cleaning all built files...",
             "Rule for cleaning all built files.",
             /*depfile=*/ "",
+            /*rspfile=*/ "",
             /*restat=*/ false,
             /*generator=*/ false);
   WriteBuild(os,
@@ -850,12 +874,21 @@
 
 void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
 {
+  cmLocalGenerator *lg = this->LocalGenerators[0];
+  cmMakefile* mfRoot = lg->GetMakefile();
+
+  std::ostringstream cmd;
+  cmd << lg->ConvertToOutputFormat(
+    mfRoot->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"),
+    cmLocalGenerator::SHELL) << " -t targets";
+
   WriteRule(*this->RulesFileStream,
             "HELP",
-            "ninja -t targets",
+            cmd.str(),
             "All primary targets available:",
             "Rule for printing all primary targets available.",
             /*depfile=*/ "",
+            /*rspfile=*/ "",
             /*restat=*/ false,
             /*generator=*/ false);
   WriteBuild(os,

=== modified file 'Source/cmGlobalNinjaGenerator.h'
--- old/Source/cmGlobalNinjaGenerator.h	2012-05-24 17:38:13 +0000
+++ new/Source/cmGlobalNinjaGenerator.h	2012-06-02 18:30:10 +0000
@@ -113,6 +113,7 @@
                         const std::string& description,
                         const std::string& comment = "",
                         const std::string& depfile = "",
+                        const std::string& rspfile = ""					,
                         bool restat = false,
                         bool generator = false);
 
@@ -223,6 +224,7 @@
                const std::string& description,
                const std::string& comment = "",
                const std::string& depfile = "",
+               const std::string& rspfile = "",
                bool restat = false,
                bool generator = false);
 

=== modified file 'Source/cmLocalNinjaGenerator.cxx'
--- old/Source/cmLocalNinjaGenerator.cxx	2012-04-03 19:59:48 +0000
+++ new/Source/cmLocalNinjaGenerator.cxx	2012-06-02 18:30:10 +0000
@@ -275,16 +275,16 @@
     return ":";
 #endif
 
-  // TODO: This will work only on Unix platforms. I don't
-  // want to use a link.txt file because I will lose the benefit of the
-  // $in variables. A discussion about dealing with multiple commands in
-  // a rule is started here:
-  // groups.google.com/group/ninja-build/browse_thread/thread/d515f23a78986008
   std::ostringstream cmd;
   for (std::vector<std::string>::const_iterator li = cmdLines.begin();
        li != cmdLines.end(); ++li) {
-    if (li != cmdLines.begin())
+    if (li != cmdLines.begin()) {
       cmd << " && ";
+#ifdef _WIN32
+    } else if (cmdLines.size() > 1) {
+      cmd << "cmd.exe /c ";
+#endif
+    }
     cmd << *li;
   }
   return cmd.str();

=== modified file 'Source/cmNinjaNormalTargetGenerator.cxx'
--- old/Source/cmNinjaNormalTargetGenerator.cxx	2012-05-24 17:38:13 +0000
+++ new/Source/cmNinjaNormalTargetGenerator.cxx	2012-06-02 22:27:05 +0000
@@ -94,8 +94,7 @@
     this->WriteLinkStatement();
     }
 
-  this->GetBuildFileStream() << "\n";
-  this->GetRulesFileStream() << "\n";
+  this->GetBuildFileStream() << "\n\n";
 }
 
 void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
@@ -149,12 +148,40 @@
   cmTarget::TargetType targetType = this->GetTarget()->GetType();
   std::string ruleName = this->LanguageLinkerRule();
 
+  // CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS:BOOL=TRUE
+  // CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS:BOOL=TRUE
+  // Select whether to use a response file for objects.
+  std::string rspfile;
+  const std::string cmakeLinkVar = std::string("CMAKE_") + this->TargetLinkLanguage;
+  bool useResponseFile = GetMakefile()->IsOn(
+                  (cmakeLinkVar + "_USE_RESPONSE_FILE_FOR_OBJECTS").c_str());
+
   if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
     cmLocalGenerator::RuleVariables vars;
     vars.RuleLauncher = "RULE_LAUNCH_LINK";
     vars.CMTarget = this->GetTarget();
     vars.Language = this->TargetLinkLanguage;
-    vars.Objects = "$in";
+
+    std::string responseFlag;
+    // FIXME: unix ar does not understand respose files! ck
+    bool hasAr = GetMakefile()->IsSet("CMAKE_AR");
+    if (!useResponseFile || (hasAr && (targetType == cmTarget::STATIC_LIBRARY))) {
+      vars.Objects = "$in";
+    } else {
+      // handle response file
+      // CMAKE_CXX_RESPONSE_FILE_LINK_FLAG:STRING=-Wl,@
+      // CMAKE_C_RESPONSE_FILE_LINK_FLAG:STRING=-Wl,@
+      const char * flag = GetMakefile()->GetDefinition(
+                     (cmakeLinkVar + "_RESPONSE_FILE_LINK_FLAG").c_str());
+      if(flag) {
+        responseFlag = flag;
+      } else {
+        responseFlag = "@";
+      }
+      rspfile = "$out.rsp";
+      responseFlag += rspfile;
+      vars.Objects = responseFlag.c_str();
+    }
     std::string objdir =
       this->GetLocalGenerator()->GetHomeRelativeOutputPath();
     objdir += objdir.empty() ? "" : "/";
@@ -201,7 +228,7 @@
       vars.LanguageCompileFlags = langFlags.c_str();
     }
 
-    // Rule for linking library.
+    // Rule for linking library/executable.
     std::vector<std::string> linkCmds = this->ComputeLinkCmd();
     for(std::vector<std::string>::iterator i = linkCmds.begin();
         i != linkCmds.end();
@@ -214,7 +241,7 @@
     std::string linkCmd =
       this->GetLocalGenerator()->BuildCommandLine(linkCmds);
 
-    // Write the linker rule.
+    // Write the linker rule with response file if needed.
     std::ostringstream comment;
     comment << "Rule for linking " << this->TargetLinkLanguage << " "
             << this->GetVisibleTypeName() << ".";
@@ -224,7 +251,9 @@
     this->GetGlobalGenerator()->AddRule(ruleName,
                                         linkCmd,
                                         description.str(),
-                                        comment.str());
+                                        comment.str(),
+                                        /*depfile*/ "",
+                                        rspfile);
   }
 
   if (this->TargetNameOut != this->TargetNameReal) {

