summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorDavid Cole <david.cole@kitware.com>2012-06-05 18:21:36 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2012-06-05 18:21:36 (GMT)
commit7687d557dc9a04c56ca9d9e943ff8e21ac8eb028 (patch)
treea9e51af78cba10b79fa1a04cdc92f82e0dfad47d /Source
parent80abbeb3f2fe1cd245633e6ac52caa329f37ae52 (diff)
parent3545645c1b01f609496a4fc41e20419dedbbd98d (diff)
downloadCMake-7687d557dc9a04c56ca9d9e943ff8e21ac8eb028.zip
CMake-7687d557dc9a04c56ca9d9e943ff8e21ac8eb028.tar.gz
CMake-7687d557dc9a04c56ca9d9e943ff8e21ac8eb028.tar.bz2
Merge topic 'Ninja-EXPORT_COMPILE_COMMANDS'
3545645 Exclude the CompileCommandOutput test on WIN32. fbaddf4 Escape the source file to be compiled if required. db839be Make the CMAKE_EXPORT_COMPILE_COMMANDS option work with Ninja. 8778357 Add newline to the output. 2c04bc0 Move the EscapeJSON method to a sharable location.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalGenerator.cxx13
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx42
-rw-r--r--Source/cmGlobalNinjaGenerator.h6
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx21
-rw-r--r--Source/cmNinjaTargetGenerator.cxx33
6 files changed, 102 insertions, 15 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index b06cdb4..f883041 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -2474,3 +2474,16 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target)
cmSystemTools::RemoveFile(file.c_str());
}
}
+
+//----------------------------------------------------------------------------
+// static
+std::string cmGlobalGenerator::EscapeJSON(const std::string& s) {
+ std::string result;
+ for (std::string::size_type i = 0; i < s.size(); ++i) {
+ if (s[i] == '"' || s[i] == '\\') {
+ result += '\\';
+ }
+ result += s[i];
+ }
+ return result;
+}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 5254b89..8535edc 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -280,6 +280,8 @@ public:
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
+ static std::string EscapeJSON(const std::string& s);
+
protected:
typedef std::vector<cmLocalGenerator*> GeneratorVector;
// for a project collect all its targets by following depend
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 328706c..0e89fab 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -341,6 +341,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator()
: cmGlobalGenerator()
, BuildFileStream(0)
, RulesFileStream(0)
+ , CompileCommandsStream(0)
, Rules()
, AllDependencies()
{
@@ -390,6 +391,7 @@ void cmGlobalNinjaGenerator::Generate()
this->BuildFileStream->setstate(std::ios_base::failbit);
}
+ this->CloseCompileCommandsStream();
this->CloseRulesFileStream();
this->CloseBuildFileStream();
}
@@ -623,6 +625,46 @@ void cmGlobalNinjaGenerator::CloseRulesFileStream()
}
}
+void cmGlobalNinjaGenerator::AddCXXCompileCommand(
+ const std::string &commandLine,
+ const std::string &sourceFile)
+{
+ // Compute Ninja's build file path.
+ std::string buildFileDir =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ if (!this->CompileCommandsStream)
+ {
+ std::string buildFilePath = buildFileDir + "/compile_commands.json";
+
+ // Get a stream where to generate things.
+ this->CompileCommandsStream =
+ new cmGeneratedFileStream(buildFilePath.c_str());
+ *this->CompileCommandsStream << "[";
+ } else {
+ *this->CompileCommandsStream << "," << std::endl;
+ }
+
+ *this->CompileCommandsStream << "\n{\n"
+ << " \"directory\": \""
+ << cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n"
+ << " \"command\": \""
+ << cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n"
+ << " \"file\": \""
+ << cmGlobalGenerator::EscapeJSON(sourceFile) << "\"\n"
+ << "}";
+}
+
+void cmGlobalNinjaGenerator::CloseCompileCommandsStream()
+{
+ if (this->CompileCommandsStream)
+ {
+ *this->CompileCommandsStream << "\n]";
+ delete this->CompileCommandsStream;
+ this->CompileCommandsStream = 0;
+ }
+
+}
+
void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
{
os
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index e652972..7b6b9b7 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -213,6 +213,9 @@ public:
cmGeneratedFileStream* GetRulesFileStream() const
{ return this->RulesFileStream; }
+ void AddCXXCompileCommand(const std::string &commandLine,
+ const std::string &sourceFile);
+
/**
* Add a rule to the generated build system.
* Call WriteRule() behind the scene but perform some check before like:
@@ -254,6 +257,8 @@ private:
void OpenBuildFileStream();
void CloseBuildFileStream();
+ void CloseCompileCommandsStream();
+
void OpenRulesFileStream();
void CloseRulesFileStream();
@@ -311,6 +316,7 @@ private:
/// The file containing the rule statements. (The action attached to each
/// edge of the compilation DAG).
cmGeneratedFileStream* RulesFileStream;
+ cmGeneratedFileStream* CompileCommandsStream;
/// The type used to store the set of rules added to the generated build
/// system.
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index e63de9c..ebd8219 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -103,18 +103,6 @@ cmGlobalUnixMakefileGenerator3
}
}
-//----------------------------------------------------------------------------
-std::string EscapeJSON(const std::string& s) {
- std::string result;
- for (std::string::size_type i = 0; i < s.size(); ++i) {
- if (s[i] == '"' || s[i] == '\\') {
- result += '\\';
- }
- result += s[i];
- }
- return result;
-}
-
void cmGlobalUnixMakefileGenerator3::Generate()
{
// first do superclass method
@@ -179,11 +167,14 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
*this->CommandDatabase << "," << std::endl;
}
*this->CommandDatabase << "{" << std::endl
- << " \"directory\": \"" << EscapeJSON(workingDirectory) << "\","
+ << " \"directory\": \""
+ << cmGlobalGenerator::EscapeJSON(workingDirectory) << "\","
<< std::endl
- << " \"command\": \"" << EscapeJSON(compileCommand) << "\","
+ << " \"command\": \"" <<
+ cmGlobalGenerator::EscapeJSON(compileCommand) << "\","
<< std::endl
- << " \"file\": \"" << EscapeJSON(sourceFile) << "\""
+ << " \"file\": \"" <<
+ cmGlobalGenerator::EscapeJSON(sourceFile) << "\""
<< std::endl << "}";
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 80007f1..e419a4d 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -487,6 +487,39 @@ cmNinjaTargetGenerator
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->GetTargetPDB().c_str(), cmLocalGenerator::SHELL);
+ if(this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
+ {
+ cmLocalGenerator::RuleVariables compileObjectVars;
+ std::string lang = language;
+ compileObjectVars.Language = lang.c_str();
+ std::string escapedSourceFileName =
+ this->LocalGenerator->ConvertToOutputFormat(
+ sourceFileName.c_str(), cmLocalGenerator::SHELL);
+ compileObjectVars.Source = escapedSourceFileName.c_str();
+ compileObjectVars.Object = objectFileName.c_str();
+ compileObjectVars.Flags = vars["FLAGS"].c_str();
+ compileObjectVars.Defines = vars["DEFINES"].c_str();
+
+ // Rule for compiling object file.
+ std::string compileCmdVar = "CMAKE_";
+ compileCmdVar += language;
+ compileCmdVar += "_COMPILE_OBJECT";
+ std::string compileCmd =
+ this->GetMakefile()->GetRequiredDefinition(compileCmdVar.c_str());
+ std::vector<std::string> compileCmds;
+ cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+
+ for (std::vector<std::string>::iterator i = compileCmds.begin();
+ i != compileCmds.end(); ++i)
+ this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
+
+ std::string cmdLine =
+ this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+
+ this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
+ sourceFileName);
+ }
+
cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
comment,
rule,