cmake/Source/cmExtraKateGenerator.cxx

317 lines
10 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2014-08-03 19:52:23 +02:00
#include "cmExtraKateGenerator.h"
2016-07-09 11:21:54 +02:00
#include "cmGeneratedFileStream.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
2014-08-03 19:52:23 +02:00
#include "cmMakefile.h"
#include "cmSourceFile.h"
2017-04-14 19:02:05 +02:00
#include "cmStateTypes.h"
2014-08-03 19:52:23 +02:00
#include "cmSystemTools.h"
2016-10-30 18:24:19 +01:00
#include <ostream>
#include <set>
#include <string.h>
#include <vector>
2014-08-03 19:52:23 +02:00
2016-10-30 18:24:19 +01:00
cmExtraKateGenerator::cmExtraKateGenerator()
: cmExternalMakefileProjectGenerator()
2014-08-03 19:52:23 +02:00
{
}
2016-10-30 18:24:19 +01:00
cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory()
2014-08-03 19:52:23 +02:00
{
2016-10-30 18:24:19 +01:00
static cmExternalMakefileProjectGeneratorSimpleFactory<cmExtraKateGenerator>
factory("Kate", "Generates Kate project files.");
if (factory.GetSupportedGlobalGenerators().empty()) {
2014-08-03 19:52:23 +02:00
#if defined(_WIN32)
2016-10-30 18:24:19 +01:00
factory.AddSupportedGlobalGenerator("MinGW Makefiles");
factory.AddSupportedGlobalGenerator("NMake Makefiles");
2014-08-03 19:52:23 +02:00
// disable until somebody actually tests it:
2016-10-30 18:24:19 +01:00
// factory.AddSupportedGlobalGenerator("MSYS Makefiles");
2014-08-03 19:52:23 +02:00
#endif
2016-10-30 18:24:19 +01:00
factory.AddSupportedGlobalGenerator("Ninja");
factory.AddSupportedGlobalGenerator("Unix Makefiles");
}
return &factory;
2014-08-03 19:52:23 +02:00
}
void cmExtraKateGenerator::Generate()
{
2016-03-13 13:35:51 +01:00
cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
2016-07-09 11:21:54 +02:00
this->ProjectName = this->GenerateProjectName(
lg->GetProjectName(), mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
this->GetPathBasename(lg->GetBinaryDirectory()));
2015-04-27 22:25:09 +02:00
this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");
2014-08-03 19:52:23 +02:00
2016-03-13 13:35:51 +01:00
this->CreateKateProjectFile(lg);
this->CreateDummyKateProjectFile(lg);
2014-08-03 19:52:23 +02:00
}
2016-03-13 13:35:51 +01:00
void cmExtraKateGenerator::CreateKateProjectFile(
2016-07-09 11:21:54 +02:00
const cmLocalGenerator* lg) const
2014-08-03 19:52:23 +02:00
{
2016-03-13 13:35:51 +01:00
std::string filename = lg->GetBinaryDirectory();
2014-08-03 19:52:23 +02:00
filename += "/.kateproject";
cmGeneratedFileStream fout(filename.c_str());
2016-07-09 11:21:54 +02:00
if (!fout) {
2014-08-03 19:52:23 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
/* clang-format off */
2014-08-03 19:52:23 +02:00
fout <<
"{\n"
"\t\"name\": \"" << this->ProjectName << "\",\n"
2016-03-13 13:35:51 +01:00
"\t\"directory\": \"" << lg->GetSourceDirectory() << "\",\n"
"\t\"files\": [ { " << this->GenerateFilesString(lg) << "} ],\n";
2016-07-09 11:21:54 +02:00
/* clang-format on */
2016-03-13 13:35:51 +01:00
this->WriteTargets(lg, fout);
2014-08-03 19:52:23 +02:00
fout << "}\n";
}
2016-07-09 11:21:54 +02:00
void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
cmGeneratedFileStream& fout) const
2014-08-03 19:52:23 +02:00
{
2016-03-13 13:35:51 +01:00
cmMakefile const* mf = lg->GetMakefile();
2014-08-03 19:52:23 +02:00
const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
2016-07-09 11:21:54 +02:00
const std::string makeArgs =
mf->GetSafeDefinition("CMAKE_KATE_MAKE_ARGUMENTS");
2016-03-13 13:35:51 +01:00
const char* homeOutputDir = lg->GetBinaryDirectory();
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
/* clang-format off */
2014-08-03 19:52:23 +02:00
fout <<
"\t\"build\": {\n"
2016-03-13 13:35:51 +01:00
"\t\t\"directory\": \"" << lg->GetBinaryDirectory() << "\",\n"
2014-08-03 19:52:23 +02:00
"\t\t\"default_target\": \"all\",\n"
"\t\t\"clean_target\": \"clean\",\n";
2016-07-09 11:21:54 +02:00
/* clang-format on */
2014-08-03 19:52:23 +02:00
// build, clean and quick are for the build plugin kate <= 4.12:
2016-07-09 11:21:54 +02:00
fout << "\t\t\"build\": \"" << make << " -C \\\"" << homeOutputDir << "\\\" "
<< makeArgs << " "
<< "all\",\n";
fout << "\t\t\"clean\": \"" << make << " -C \\\"" << homeOutputDir << "\\\" "
<< makeArgs << " "
<< "clean\",\n";
fout << "\t\t\"quick\": \"" << make << " -C \\\"" << homeOutputDir << "\\\" "
<< makeArgs << " "
<< "install\",\n";
2014-08-03 19:52:23 +02:00
// this is for kate >= 4.13:
2016-07-09 11:21:54 +02:00
fout << "\t\t\"targets\":[\n";
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
this->AppendTarget(fout, "all", make, makeArgs, homeOutputDir,
homeOutputDir);
this->AppendTarget(fout, "clean", make, makeArgs, homeOutputDir,
homeOutputDir);
2014-08-03 19:52:23 +02:00
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
2016-07-09 11:21:54 +02:00
for (std::vector<cmLocalGenerator*>::const_iterator it =
this->GlobalGenerator->GetLocalGenerators().begin();
it != this->GlobalGenerator->GetLocalGenerators().end(); ++it) {
2016-03-13 13:35:51 +01:00
const std::vector<cmGeneratorTarget*> targets =
2016-07-09 11:21:54 +02:00
(*it)->GetGeneratorTargets();
2016-03-13 13:35:51 +01:00
std::string currentDir = (*it)->GetCurrentBinaryDirectory();
bool topLevel = (currentDir == (*it)->GetBinaryDirectory());
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
for (std::vector<cmGeneratorTarget*>::const_iterator ti = targets.begin();
ti != targets.end(); ++ti) {
2016-03-13 13:35:51 +01:00
std::string targetName = (*ti)->GetName();
2016-07-09 11:21:54 +02:00
switch ((*ti)->GetType()) {
2017-04-14 19:02:05 +02:00
case cmStateEnums::GLOBAL_TARGET: {
2014-08-03 19:52:23 +02:00
bool insertTarget = false;
// Only add the global targets from CMAKE_BINARY_DIR,
// not from the subdirs
2016-07-09 11:21:54 +02:00
if (topLevel) {
2014-08-03 19:52:23 +02:00
insertTarget = true;
// only add the "edit_cache" target if it's not ccmake, because
// this will not work within the IDE
2016-07-09 11:21:54 +02:00
if (targetName == "edit_cache") {
const char* editCommand =
(*it)->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND");
2016-10-30 18:24:19 +01:00
if (editCommand == CM_NULLPTR) {
2014-08-03 19:52:23 +02:00
insertTarget = false;
2016-10-30 18:24:19 +01:00
} else if (strstr(editCommand, "ccmake") != CM_NULLPTR) {
2014-08-03 19:52:23 +02:00
insertTarget = false;
}
}
2016-07-09 11:21:54 +02:00
}
if (insertTarget) {
this->AppendTarget(fout, targetName, make, makeArgs, currentDir,
homeOutputDir);
}
} break;
2017-04-14 19:02:05 +02:00
case cmStateEnums::UTILITY:
2014-08-03 19:52:23 +02:00
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
2016-07-09 11:21:54 +02:00
if (((targetName.find("Nightly") == 0) &&
(targetName != "Nightly")) ||
((targetName.find("Continuous") == 0) &&
(targetName != "Continuous")) ||
((targetName.find("Experimental") == 0) &&
(targetName != "Experimental"))) {
break;
}
this->AppendTarget(fout, targetName, make, makeArgs, currentDir,
homeOutputDir);
2014-08-03 19:52:23 +02:00
break;
2017-04-14 19:02:05 +02:00
case cmStateEnums::EXECUTABLE:
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY: {
2016-07-09 11:21:54 +02:00
this->AppendTarget(fout, targetName, make, makeArgs, currentDir,
homeOutputDir);
2016-03-13 13:35:51 +01:00
std::string fastTarget = targetName;
2014-08-03 19:52:23 +02:00
fastTarget += "/fast";
2016-07-09 11:21:54 +02:00
this->AppendTarget(fout, fastTarget, make, makeArgs, currentDir,
homeOutputDir);
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
} break;
2014-08-03 19:52:23 +02:00
default:
break;
}
}
2016-07-09 11:21:54 +02:00
// insert rules for compiling, preprocessing and assembling individual
// files
2014-08-03 19:52:23 +02:00
std::vector<std::string> objectFileTargets;
(*it)->GetIndividualFileTargets(objectFileTargets);
2016-07-09 11:21:54 +02:00
for (std::vector<std::string>::const_iterator fit =
objectFileTargets.begin();
fit != objectFileTargets.end(); ++fit) {
this->AppendTarget(fout, *fit, make, makeArgs, currentDir,
homeOutputDir);
}
2014-08-03 19:52:23 +02:00
}
2016-07-09 11:21:54 +02:00
fout << "\t] }\n";
2014-08-03 19:52:23 +02:00
}
2016-07-09 11:21:54 +02:00
void cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
const std::string& target,
const std::string& make,
const std::string& makeArgs,
const std::string& path,
const char* homeOutputDir) const
2014-08-03 19:52:23 +02:00
{
static char JsonSep = ' ';
2016-07-09 11:21:54 +02:00
fout << "\t\t\t" << JsonSep << "{\"name\":\"" << target << "\", "
"\"build_cmd\":\""
<< make << " -C \\\"" << (this->UseNinja ? homeOutputDir : path.c_str())
<< "\\\" " << makeArgs << " " << target << "\"}\n";
2014-08-03 19:52:23 +02:00
JsonSep = ',';
}
2016-07-09 11:21:54 +02:00
void cmExtraKateGenerator::CreateDummyKateProjectFile(
const cmLocalGenerator* lg) const
2014-08-03 19:52:23 +02:00
{
2016-03-13 13:35:51 +01:00
std::string filename = lg->GetBinaryDirectory();
2014-08-03 19:52:23 +02:00
filename += "/";
filename += this->ProjectName;
filename += ".kateproject";
cmGeneratedFileStream fout(filename.c_str());
2016-07-09 11:21:54 +02:00
if (!fout) {
2014-08-03 19:52:23 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
2015-08-17 11:37:30 +02:00
fout << "#Generated by " << cmSystemTools::GetCMakeCommand()
2014-08-03 19:52:23 +02:00
<< ", do not edit.\n";
}
2016-07-09 11:21:54 +02:00
std::string cmExtraKateGenerator::GenerateFilesString(
const cmLocalGenerator* lg) const
2014-08-03 19:52:23 +02:00
{
2016-03-13 13:35:51 +01:00
std::string s = lg->GetSourceDirectory();
2014-08-03 19:52:23 +02:00
s += "/.git";
2016-07-09 11:21:54 +02:00
if (cmSystemTools::FileExists(s.c_str())) {
2014-08-03 19:52:23 +02:00
return std::string("\"git\": 1 ");
}
2016-03-13 13:35:51 +01:00
s = lg->GetSourceDirectory();
2014-08-03 19:52:23 +02:00
s += "/.svn";
2016-07-09 11:21:54 +02:00
if (cmSystemTools::FileExists(s.c_str())) {
2014-08-03 19:52:23 +02:00
return std::string("\"svn\": 1 ");
}
2016-03-13 13:35:51 +01:00
s = lg->GetSourceDirectory();
2014-08-03 19:52:23 +02:00
s += "/";
std::set<std::string> files;
std::string tmp;
2016-07-09 11:21:54 +02:00
const std::vector<cmLocalGenerator*>& lgs =
this->GlobalGenerator->GetLocalGenerators();
for (std::vector<cmLocalGenerator*>::const_iterator it = lgs.begin();
it != lgs.end(); it++) {
cmMakefile* makefile = (*it)->GetMakefile();
const std::vector<std::string>& listFiles = makefile->GetListFiles();
for (std::vector<std::string>::const_iterator lt = listFiles.begin();
lt != listFiles.end(); lt++) {
tmp = *lt;
2014-08-03 19:52:23 +02:00
{
files.insert(tmp);
}
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
const std::vector<cmSourceFile*>& sources = makefile->GetSourceFiles();
for (std::vector<cmSourceFile*>::const_iterator sfIt = sources.begin();
2016-07-09 11:21:54 +02:00
sfIt != sources.end(); sfIt++) {
2014-08-03 19:52:23 +02:00
cmSourceFile* sf = *sfIt;
2016-07-09 11:21:54 +02:00
if (sf->GetPropertyAsBool("GENERATED")) {
2014-08-03 19:52:23 +02:00
continue;
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
tmp = sf->GetFullPath();
files.insert(tmp);
}
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
const char* sep = "";
tmp = "\"list\": [";
2016-07-09 11:21:54 +02:00
for (std::set<std::string>::const_iterator it = files.begin();
it != files.end(); ++it) {
2014-08-03 19:52:23 +02:00
tmp += sep;
tmp += " \"";
tmp += *it;
tmp += "\"";
sep = ",";
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
tmp += "] ";
return tmp;
}
2016-07-09 11:21:54 +02:00
std::string cmExtraKateGenerator::GenerateProjectName(
const std::string& name, const std::string& type,
const std::string& path) const
2014-08-03 19:52:23 +02:00
{
return name + (type.empty() ? "" : "-") + type + "@" + path;
}
2016-07-09 11:21:54 +02:00
std::string cmExtraKateGenerator::GetPathBasename(
const std::string& path) const
2014-08-03 19:52:23 +02:00
{
std::string outputBasename = path;
2015-04-27 22:25:09 +02:00
while (!outputBasename.empty() &&
2014-08-03 19:52:23 +02:00
(outputBasename[outputBasename.size() - 1] == '/' ||
2016-07-09 11:21:54 +02:00
outputBasename[outputBasename.size() - 1] == '\\')) {
2014-08-03 19:52:23 +02:00
outputBasename.resize(outputBasename.size() - 1);
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
std::string::size_type loc = outputBasename.find_last_of("/\\");
2016-07-09 11:21:54 +02:00
if (loc != std::string::npos) {
2014-08-03 19:52:23 +02:00
outputBasename = outputBasename.substr(loc + 1);
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
return outputBasename;
}