diff options
Diffstat (limited to 'Source/cmGlobalNinjaGenerator.cxx')
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 131 |
1 files changed, 101 insertions, 30 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 0e89fab..c3989c0 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -43,12 +43,13 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os, std::string replace = comment; std::string::size_type lpos = 0; std::string::size_type rpos; + os << "\n#############################################\n"; while((rpos = replace.find('\n', lpos)) != std::string::npos) { os << "# " << replace.substr(lpos, rpos - lpos) << "\n"; lpos = rpos + 1; } - os << "# " << replace.substr(lpos) << "\n"; + os << "# " << replace.substr(lpos) << "\n\n"; } static bool IsIdentChar(char c) @@ -66,7 +67,7 @@ std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string &ident, if (std::find_if(ident.begin(), ident.end(), std::not1(std::ptr_fun(IsIdentChar))) != ident.end()) { static unsigned VarNum = 0; - std::ostringstream names; + cmOStringStream names; names << "ident" << VarNum++; vars << names.str() << " = " << ident << "\n"; return "$" + names.str(); @@ -89,7 +90,10 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) { std::string result = path; #ifdef _WIN32 - cmSystemTools::ReplaceString(result, "/", "\\"); + if(UsingMinGW) + cmSystemTools::ReplaceString(result, "\\", "/"); + else + cmSystemTools::ReplaceString(result, "/", "\\"); #endif return EncodeLiteral(result); } @@ -101,7 +105,8 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, const cmNinjaDeps& orderOnlyDeps, - const cmNinjaVars& variables) + const cmNinjaVars& variables, + int cmdLineLimit) { // Make sure there is a rule. if(rule.empty()) @@ -123,50 +128,60 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, cmGlobalNinjaGenerator::WriteComment(os, comment); - std::ostringstream builds; + cmOStringStream arguments; // TODO: Better formatting for when there are multiple input/output files. - // Write outputs files. - builds << "build"; - for(cmNinjaDeps::const_iterator i = outputs.begin(); - i != outputs.end(); - ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); - builds << ":"; - - // Write the rule. - builds << " " << rule; - // Write explicit dependencies. for(cmNinjaDeps::const_iterator i = explicitDeps.begin(); i != explicitDeps.end(); ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); + arguments << " " << EncodeIdent(EncodePath(*i), os); // Write implicit dependencies. if(!implicitDeps.empty()) { - builds << " |"; + arguments << " |"; for(cmNinjaDeps::const_iterator i = implicitDeps.begin(); i != implicitDeps.end(); ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); + arguments << " " << EncodeIdent(EncodePath(*i), os); } // Write order-only dependencies. if(!orderOnlyDeps.empty()) { - builds << " ||"; + arguments << " ||"; for(cmNinjaDeps::const_iterator i = orderOnlyDeps.begin(); i != orderOnlyDeps.end(); ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); + arguments << " " << EncodeIdent(EncodePath(*i), os); } - builds << "\n"; + arguments << "\n"; + + + cmOStringStream builds; + + // Write outputs files. + builds << "build"; + for(cmNinjaDeps::const_iterator i = outputs.begin(); + i != outputs.end(); + ++i) + builds << " " << EncodeIdent(EncodePath(*i), os); + builds << ":"; + - os << builds.str(); + // Write the rule. + builds << " " << rule; + + // check if a response file rule should be used + const std::string args = arguments.str(); + if (cmdLineLimit > 0 && + (args.size() + + builds.str().size()) > (size_t)cmdLineLimit) + builds << "_RSPFILE"; + + os << builds.str() << args; // Write the variables bound to this build statement. for(cmNinjaVars::const_iterator i = variables.begin(); @@ -200,6 +215,7 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() "$DESC", "Rule for running custom commands.", /*depfile*/ "", + /*rspfile*/ "", /*restat*/ true); } @@ -211,10 +227,17 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, const cmNinjaDeps& deps, const cmNinjaDeps& orderOnlyDeps) { + std::string cmd = command; +#ifdef _WIN32 + if (cmd.empty()) + // TODO Shouldn't an empty command be handled by ninja? + cmd = "cmd.exe /c"; +#endif + this->AddCustomCommandRule(); cmNinjaVars vars; - vars["COMMAND"] = command; + vars["COMMAND"] = cmd; vars["DESC"] = EncodeLiteral(description); cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, @@ -233,6 +256,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& rspfile, bool restat, bool generator) { @@ -277,6 +301,14 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, 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); @@ -288,6 +320,8 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, cmGlobalNinjaGenerator::Indent(os, 1); os << "generator = 1\n"; } + + os << "\n"; } void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os, @@ -350,6 +384,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake"; } + //---------------------------------------------------------------------------- // Virtual public methods. @@ -404,16 +439,19 @@ void cmGlobalNinjaGenerator cmMakefile *mf, bool optional) { - this->cmGlobalGenerator::EnableLanguage(languages, mf, optional); std::string path; for(std::vector<std::string>::const_iterator l = languages.begin(); l != languages.end(); ++l) { + std::vector<std::string> language; + language.push_back(*l); + if(*l == "NONE") { + this->cmGlobalGenerator::EnableLanguage(language, mf, optional); continue; } - if(*l == "Fortran") + else if(*l == "Fortran") { std::string message = "The \""; message += this->GetName(); @@ -422,10 +460,25 @@ void cmGlobalNinjaGenerator message += "\" yet."; cmSystemTools::Error(message.c_str()); } + else if(*l == "RC") + { + // check if mingw is used + if(mf->IsOn("CMAKE_COMPILER_IS_MINGW")) + { + UsingMinGW = true; + std::string rc = cmSystemTools::FindProgram("windres"); + if(rc.empty()) + rc = "windres.exe";; + mf->AddDefinition("CMAKE_RC_COMPILER", rc.c_str()); + } + } + this->cmGlobalGenerator::EnableLanguage(language, mf, optional); this->ResolveLanguageCompiler(*l, mf, optional); } } +bool cmGlobalNinjaGenerator::UsingMinGW = false; + // Implemented by: // cmGlobalUnixMakefileGenerator3 // cmGlobalVisualStudio10Generator @@ -483,12 +536,15 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& rspfile, bool restat, bool generator) { // Do not add the same rule twice. if (this->HasRule(name)) + { return; + } this->Rules.insert(name); cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, @@ -497,6 +553,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, description, comment, depfile, + rspfile, restat, generator); } @@ -767,7 +824,7 @@ void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias, // Insert the alias into the map. If the alias was already present in the // map and referred to another target, mark it as ambiguous. std::pair<TargetAliasMap::iterator, bool> newAlias = - TargetAliases.insert(make_pair(alias, target)); + TargetAliases.insert(std::make_pair(alias, target)); if (newAlias.second && newAlias.first->second != target) newAlias.first->second = 0; } @@ -825,7 +882,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmLocalGenerator *lg = this->LocalGenerators[0]; cmMakefile* mfRoot = lg->GetMakefile(); - std::ostringstream cmd; + cmOStringStream cmd; cmd << lg->ConvertToOutputFormat( mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), cmLocalGenerator::SHELL) @@ -841,6 +898,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) "Re-running CMake...", "Rule for re-running cmake.", /*depfile=*/ "", + /*rspfile=*/ "", /*restat=*/ false, /*generator=*/ true); @@ -870,14 +928,26 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmNinjaDeps()); } +std::string cmGlobalNinjaGenerator::ninjaCmd() const +{ + cmLocalGenerator* lgen = this->LocalGenerators[0]; + if (lgen) { + return lgen->ConvertToOutputFormat( + lgen->GetMakefile()->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"), + cmLocalGenerator::SHELL); + } + return "ninja"; +} + void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) { WriteRule(*this->RulesFileStream, "CLEAN", - "ninja -t clean", + (ninjaCmd() + " -t clean").c_str(), "Cleaning all built files...", "Rule for cleaning all built files.", /*depfile=*/ "", + /*rspfile=*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, @@ -894,10 +964,11 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) { WriteRule(*this->RulesFileStream, "HELP", - "ninja -t targets", + (ninjaCmd() + " -t tagets").c_str(), "All primary targets available:", "Rule for printing all primary targets available.", /*depfile=*/ "", + /*rspfile=*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, |