cmExtraKateGenerator.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2004-2009 Kitware, Inc.
  4. Copyright 2004 Alexander Neundorf ([email protected])
  5. Distributed under the OSI-approved BSD License (the "License");
  6. see accompanying file Copyright.txt for details.
  7. This software is distributed WITHOUT ANY WARRANTY; without even the
  8. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. See the License for more information.
  10. ============================================================================*/
  11. #include "cmExtraKateGenerator.h"
  12. #include "cmGlobalUnixMakefileGenerator3.h"
  13. #include "cmLocalUnixMakefileGenerator3.h"
  14. #include "cmMakefile.h"
  15. #include "cmake.h"
  16. #include "cmSourceFile.h"
  17. #include "cmGeneratedFileStream.h"
  18. #include "cmSystemTools.h"
  19. #include <cmsys/SystemTools.hxx>
  20. //----------------------------------------------------------------------------
  21. void cmExtraKateGenerator
  22. ::GetDocumentation(cmDocumentationEntry& entry, const std::string&) const
  23. {
  24. entry.Name = this->GetName();
  25. entry.Brief = "Generates Kate project files.";
  26. }
  27. cmExtraKateGenerator::cmExtraKateGenerator()
  28. :cmExternalMakefileProjectGenerator()
  29. {
  30. #if defined(_WIN32)
  31. this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
  32. this->SupportedGlobalGenerators.push_back("NMake Makefiles");
  33. // disable until somebody actually tests it:
  34. // this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
  35. #endif
  36. this->SupportedGlobalGenerators.push_back("Ninja");
  37. this->SupportedGlobalGenerators.push_back("Unix Makefiles");
  38. }
  39. void cmExtraKateGenerator::Generate()
  40. {
  41. cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
  42. const cmMakefile* mf = lg->GetMakefile();
  43. this->ProjectName = this->GenerateProjectName(lg->GetProjectName(),
  44. mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
  45. this->GetPathBasename(lg->GetBinaryDirectory()));
  46. this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");
  47. this->CreateKateProjectFile(lg);
  48. this->CreateDummyKateProjectFile(lg);
  49. }
  50. void cmExtraKateGenerator::CreateKateProjectFile(
  51. const cmLocalGenerator* lg) const
  52. {
  53. std::string filename = lg->GetBinaryDirectory();
  54. filename += "/.kateproject";
  55. cmGeneratedFileStream fout(filename.c_str());
  56. if (!fout)
  57. {
  58. return;
  59. }
  60. fout <<
  61. "{\n"
  62. "\t\"name\": \"" << this->ProjectName << "\",\n"
  63. "\t\"directory\": \"" << lg->GetSourceDirectory() << "\",\n"
  64. "\t\"files\": [ { " << this->GenerateFilesString(lg) << "} ],\n";
  65. this->WriteTargets(lg, fout);
  66. fout << "}\n";
  67. }
  68. void
  69. cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
  70. cmGeneratedFileStream& fout) const
  71. {
  72. cmMakefile const* mf = lg->GetMakefile();
  73. const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  74. const std::string makeArgs = mf->GetSafeDefinition(
  75. "CMAKE_KATE_MAKE_ARGUMENTS");
  76. const char* homeOutputDir = lg->GetBinaryDirectory();
  77. fout <<
  78. "\t\"build\": {\n"
  79. "\t\t\"directory\": \"" << lg->GetBinaryDirectory() << "\",\n"
  80. "\t\t\"default_target\": \"all\",\n"
  81. "\t\t\"clean_target\": \"clean\",\n";
  82. // build, clean and quick are for the build plugin kate <= 4.12:
  83. fout << "\t\t\"build\": \"" << make << " -C \\\"" << homeOutputDir
  84. << "\\\" " << makeArgs << " " << "all\",\n";
  85. fout << "\t\t\"clean\": \"" << make << " -C \\\"" << homeOutputDir
  86. << "\\\" " << makeArgs << " " << "clean\",\n";
  87. fout << "\t\t\"quick\": \"" << make << " -C \\\"" << homeOutputDir
  88. << "\\\" " << makeArgs << " " << "install\",\n";
  89. // this is for kate >= 4.13:
  90. fout <<
  91. "\t\t\"targets\":[\n";
  92. this->AppendTarget(fout, "all", make, makeArgs,
  93. homeOutputDir, homeOutputDir);
  94. this->AppendTarget(fout, "clean", make, makeArgs,
  95. homeOutputDir, homeOutputDir);
  96. // add all executable and library targets and some of the GLOBAL
  97. // and UTILITY targets
  98. for (std::vector<cmLocalGenerator*>::const_iterator
  99. it = this->GlobalGenerator->GetLocalGenerators().begin();
  100. it != this->GlobalGenerator->GetLocalGenerators().end();
  101. ++it)
  102. {
  103. const std::vector<cmGeneratorTarget*> targets =
  104. (*it)->GetGeneratorTargets();
  105. std::string currentDir = (*it)->GetCurrentBinaryDirectory();
  106. bool topLevel = (currentDir == (*it)->GetBinaryDirectory());
  107. for(std::vector<cmGeneratorTarget*>::const_iterator ti =
  108. targets.begin(); ti!=targets.end(); ++ti)
  109. {
  110. std::string targetName = (*ti)->GetName();
  111. switch((*ti)->GetType())
  112. {
  113. case cmState::GLOBAL_TARGET:
  114. {
  115. bool insertTarget = false;
  116. // Only add the global targets from CMAKE_BINARY_DIR,
  117. // not from the subdirs
  118. if (topLevel)
  119. {
  120. insertTarget = true;
  121. // only add the "edit_cache" target if it's not ccmake, because
  122. // this will not work within the IDE
  123. if (targetName == "edit_cache")
  124. {
  125. const char* editCommand = (*it)->GetMakefile()->GetDefinition
  126. ("CMAKE_EDIT_COMMAND");
  127. if (editCommand == 0)
  128. {
  129. insertTarget = false;
  130. }
  131. else if (strstr(editCommand, "ccmake")!=NULL)
  132. {
  133. insertTarget = false;
  134. }
  135. }
  136. }
  137. if (insertTarget)
  138. {
  139. this->AppendTarget(fout, targetName, make, makeArgs,
  140. currentDir, homeOutputDir);
  141. }
  142. }
  143. break;
  144. case cmState::UTILITY:
  145. // Add all utility targets, except the Nightly/Continuous/
  146. // Experimental-"sub"targets as e.g. NightlyStart
  147. if (((targetName.find("Nightly")==0) &&(targetName!="Nightly"))
  148. || ((targetName.find("Continuous")==0)
  149. &&(targetName!="Continuous"))
  150. || ((targetName.find("Experimental")==0)
  151. && (targetName!="Experimental")))
  152. {
  153. break;
  154. }
  155. this->AppendTarget(fout, targetName, make, makeArgs,
  156. currentDir, homeOutputDir);
  157. break;
  158. case cmState::EXECUTABLE:
  159. case cmState::STATIC_LIBRARY:
  160. case cmState::SHARED_LIBRARY:
  161. case cmState::MODULE_LIBRARY:
  162. case cmState::OBJECT_LIBRARY:
  163. {
  164. this->AppendTarget(fout, targetName, make, makeArgs,
  165. currentDir, homeOutputDir);
  166. std::string fastTarget = targetName;
  167. fastTarget += "/fast";
  168. this->AppendTarget(fout, fastTarget, make, makeArgs,
  169. currentDir, homeOutputDir);
  170. }
  171. break;
  172. default:
  173. break;
  174. }
  175. }
  176. //insert rules for compiling, preprocessing and assembling individual files
  177. std::vector<std::string> objectFileTargets;
  178. (*it)->GetIndividualFileTargets(objectFileTargets);
  179. for(std::vector<std::string>::const_iterator fit=objectFileTargets.begin();
  180. fit != objectFileTargets.end();
  181. ++fit)
  182. {
  183. this->AppendTarget(fout, *fit, make, makeArgs, currentDir,homeOutputDir);
  184. }
  185. }
  186. fout <<
  187. "\t] }\n";
  188. }
  189. void
  190. cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
  191. const std::string& target,
  192. const std::string& make,
  193. const std::string& makeArgs,
  194. const std::string& path,
  195. const char* homeOutputDir
  196. ) const
  197. {
  198. static char JsonSep = ' ';
  199. fout <<
  200. "\t\t\t" << JsonSep << "{\"name\":\"" << target << "\", "
  201. "\"build_cmd\":\"" << make
  202. << " -C \\\"" << (this->UseNinja ? homeOutputDir : path.c_str())
  203. << "\\\" " << makeArgs << " "
  204. << target << "\"}\n";
  205. JsonSep = ',';
  206. }
  207. void
  208. cmExtraKateGenerator::CreateDummyKateProjectFile(
  209. const cmLocalGenerator* lg) const
  210. {
  211. std::string filename = lg->GetBinaryDirectory();
  212. filename += "/";
  213. filename += this->ProjectName;
  214. filename += ".kateproject";
  215. cmGeneratedFileStream fout(filename.c_str());
  216. if (!fout)
  217. {
  218. return;
  219. }
  220. fout << "#Generated by " << cmSystemTools::GetCMakeCommand()
  221. << ", do not edit.\n";
  222. }
  223. std::string
  224. cmExtraKateGenerator::GenerateFilesString(const cmLocalGenerator* lg) const
  225. {
  226. std::string s = lg->GetSourceDirectory();
  227. s += "/.git";
  228. if(cmSystemTools::FileExists(s.c_str()))
  229. {
  230. return std::string("\"git\": 1 ");
  231. }
  232. s = lg->GetSourceDirectory();
  233. s += "/.svn";
  234. if(cmSystemTools::FileExists(s.c_str()))
  235. {
  236. return std::string("\"svn\": 1 ");
  237. }
  238. s = lg->GetSourceDirectory();
  239. s += "/";
  240. std::set<std::string> files;
  241. std::string tmp;
  242. const std::vector<cmLocalGenerator *>& lgs =
  243. this->GlobalGenerator->GetLocalGenerators();
  244. for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin();
  245. it!=lgs.end(); it++)
  246. {
  247. cmMakefile* makefile=(*it)->GetMakefile();
  248. const std::vector<std::string>& listFiles=makefile->GetListFiles();
  249. for (std::vector<std::string>::const_iterator lt=listFiles.begin();
  250. lt!=listFiles.end(); lt++)
  251. {
  252. tmp=*lt;
  253. {
  254. files.insert(tmp);
  255. }
  256. }
  257. const std::vector<cmSourceFile*>& sources = makefile->GetSourceFiles();
  258. for (std::vector<cmSourceFile*>::const_iterator sfIt = sources.begin();
  259. sfIt != sources.end(); sfIt++)
  260. {
  261. cmSourceFile* sf = *sfIt;
  262. if (sf->GetPropertyAsBool("GENERATED"))
  263. {
  264. continue;
  265. }
  266. tmp = sf->GetFullPath();
  267. files.insert(tmp);
  268. }
  269. }
  270. const char* sep = "";
  271. tmp = "\"list\": [";
  272. for(std::set<std::string>::const_iterator it = files.begin();
  273. it != files.end(); ++it)
  274. {
  275. tmp += sep;
  276. tmp += " \"";
  277. tmp += *it;
  278. tmp += "\"";
  279. sep = ",";
  280. }
  281. tmp += "] ";
  282. return tmp;
  283. }
  284. std::string cmExtraKateGenerator::GenerateProjectName(const std::string& name,
  285. const std::string& type,
  286. const std::string& path) const
  287. {
  288. return name + (type.empty() ? "" : "-") + type + "@" + path;
  289. }
  290. std::string cmExtraKateGenerator::GetPathBasename(const std::string& path)const
  291. {
  292. std::string outputBasename = path;
  293. while (!outputBasename.empty() &&
  294. (outputBasename[outputBasename.size() - 1] == '/' ||
  295. outputBasename[outputBasename.size() - 1] == '\\'))
  296. {
  297. outputBasename.resize(outputBasename.size() - 1);
  298. }
  299. std::string::size_type loc = outputBasename.find_last_of("/\\");
  300. if (loc != std::string::npos)
  301. {
  302. outputBasename = outputBasename.substr(loc + 1);
  303. }
  304. return outputBasename;
  305. }