Make the CMAKE_EXPORT_COMPILE_COMMANDS option work with Ninja.
This commit is contained in:
parent
8778357898
commit
db839bec7d
|
@ -60,6 +60,12 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles")
|
|||
ENDIF(CMAKE_GENERATOR MATCHES "Unix 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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -487,6 +487,36 @@ 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();
|
||||
compileObjectVars.Source = sourceFileName.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,
|
||||
|
|
|
@ -47,7 +47,7 @@ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in
|
|||
|
||||
# Testing
|
||||
IF(BUILD_TESTING)
|
||||
IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles" OR "${CMAKE_TEST_GENERATOR}" MATCHES Ninja)
|
||||
SET(TEST_CompileCommandOutput 1)
|
||||
ENDIF()
|
||||
|
||||
|
|
Loading…
Reference in New Issue