cmExtraKateGenerator.cxx 9.9 KB

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