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.
This commit is contained in:
commit
7687d557dc
@ -60,6 +60,12 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles")
|
|||||||
ENDIF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
|
ENDIF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
|
||||||
ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")
|
ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")
|
||||||
|
|
||||||
|
IF(CMAKE_GENERATOR MATCHES "Ninja")
|
||||||
|
SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
|
||||||
|
"Enable/Disable output of compile commands during generation."
|
||||||
|
)
|
||||||
|
MARK_AS_ADVANCED(CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||||
|
ENDIF(CMAKE_GENERATOR MATCHES "Ninja")
|
||||||
|
|
||||||
# GetDefaultWindowsPrefixBase
|
# GetDefaultWindowsPrefixBase
|
||||||
#
|
#
|
||||||
|
@ -2474,3 +2474,16 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target)
|
|||||||
cmSystemTools::RemoveFile(file.c_str());
|
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;
|
||||||
|
}
|
||||||
|
@ -280,6 +280,8 @@ public:
|
|||||||
/** Generate an <output>.rule file path for a given command output. */
|
/** Generate an <output>.rule file path for a given command output. */
|
||||||
virtual std::string GenerateRuleFile(std::string const& output) const;
|
virtual std::string GenerateRuleFile(std::string const& output) const;
|
||||||
|
|
||||||
|
static std::string EscapeJSON(const std::string& s);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<cmLocalGenerator*> GeneratorVector;
|
typedef std::vector<cmLocalGenerator*> GeneratorVector;
|
||||||
// for a project collect all its targets by following depend
|
// for a project collect all its targets by following depend
|
||||||
|
@ -341,6 +341,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator()
|
|||||||
: cmGlobalGenerator()
|
: cmGlobalGenerator()
|
||||||
, BuildFileStream(0)
|
, BuildFileStream(0)
|
||||||
, RulesFileStream(0)
|
, RulesFileStream(0)
|
||||||
|
, CompileCommandsStream(0)
|
||||||
, Rules()
|
, Rules()
|
||||||
, AllDependencies()
|
, AllDependencies()
|
||||||
{
|
{
|
||||||
@ -390,6 +391,7 @@ void cmGlobalNinjaGenerator::Generate()
|
|||||||
this->BuildFileStream->setstate(std::ios_base::failbit);
|
this->BuildFileStream->setstate(std::ios_base::failbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->CloseCompileCommandsStream();
|
||||||
this->CloseRulesFileStream();
|
this->CloseRulesFileStream();
|
||||||
this->CloseBuildFileStream();
|
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)
|
void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
|
||||||
{
|
{
|
||||||
os
|
os
|
||||||
|
@ -213,6 +213,9 @@ public:
|
|||||||
cmGeneratedFileStream* GetRulesFileStream() const
|
cmGeneratedFileStream* GetRulesFileStream() const
|
||||||
{ return this->RulesFileStream; }
|
{ return this->RulesFileStream; }
|
||||||
|
|
||||||
|
void AddCXXCompileCommand(const std::string &commandLine,
|
||||||
|
const std::string &sourceFile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a rule to the generated build system.
|
* Add a rule to the generated build system.
|
||||||
* Call WriteRule() behind the scene but perform some check before like:
|
* Call WriteRule() behind the scene but perform some check before like:
|
||||||
@ -254,6 +257,8 @@ private:
|
|||||||
void OpenBuildFileStream();
|
void OpenBuildFileStream();
|
||||||
void CloseBuildFileStream();
|
void CloseBuildFileStream();
|
||||||
|
|
||||||
|
void CloseCompileCommandsStream();
|
||||||
|
|
||||||
void OpenRulesFileStream();
|
void OpenRulesFileStream();
|
||||||
void CloseRulesFileStream();
|
void CloseRulesFileStream();
|
||||||
|
|
||||||
@ -311,6 +316,7 @@ private:
|
|||||||
/// The file containing the rule statements. (The action attached to each
|
/// The file containing the rule statements. (The action attached to each
|
||||||
/// edge of the compilation DAG).
|
/// edge of the compilation DAG).
|
||||||
cmGeneratedFileStream* RulesFileStream;
|
cmGeneratedFileStream* RulesFileStream;
|
||||||
|
cmGeneratedFileStream* CompileCommandsStream;
|
||||||
|
|
||||||
/// The type used to store the set of rules added to the generated build
|
/// The type used to store the set of rules added to the generated build
|
||||||
/// system.
|
/// system.
|
||||||
|
@ -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()
|
void cmGlobalUnixMakefileGenerator3::Generate()
|
||||||
{
|
{
|
||||||
// first do superclass method
|
// first do superclass method
|
||||||
@ -179,11 +167,14 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
|
|||||||
*this->CommandDatabase << "," << std::endl;
|
*this->CommandDatabase << "," << std::endl;
|
||||||
}
|
}
|
||||||
*this->CommandDatabase << "{" << std::endl
|
*this->CommandDatabase << "{" << std::endl
|
||||||
<< " \"directory\": \"" << EscapeJSON(workingDirectory) << "\","
|
<< " \"directory\": \""
|
||||||
|
<< cmGlobalGenerator::EscapeJSON(workingDirectory) << "\","
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " \"command\": \"" << EscapeJSON(compileCommand) << "\","
|
<< " \"command\": \"" <<
|
||||||
|
cmGlobalGenerator::EscapeJSON(compileCommand) << "\","
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " \"file\": \"" << EscapeJSON(sourceFile) << "\""
|
<< " \"file\": \"" <<
|
||||||
|
cmGlobalGenerator::EscapeJSON(sourceFile) << "\""
|
||||||
<< std::endl << "}";
|
<< std::endl << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +487,39 @@ cmNinjaTargetGenerator
|
|||||||
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||||
this->GetTargetPDB().c_str(), cmLocalGenerator::SHELL);
|
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(),
|
cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
|
||||||
comment,
|
comment,
|
||||||
rule,
|
rule,
|
||||||
|
@ -35,7 +35,7 @@ private:
|
|||||||
void ParseTranslationUnits()
|
void ParseTranslationUnits()
|
||||||
{
|
{
|
||||||
this->TranslationUnits = TranslationUnitsType();
|
this->TranslationUnits = TranslationUnitsType();
|
||||||
ExpectOrDie('[', "at start of compile command file");
|
ExpectOrDie('[', "at start of compile command file\n");
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ParseTranslationUnit();
|
ParseTranslationUnit();
|
||||||
|
@ -47,7 +47,7 @@ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in
|
|||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
IF(BUILD_TESTING)
|
IF(BUILD_TESTING)
|
||||||
IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles" OR ("${CMAKE_TEST_GENERATOR}" MATCHES Ninja AND NOT WIN32))
|
||||||
SET(TEST_CompileCommandOutput 1)
|
SET(TEST_CompileCommandOutput 1)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user