cmLocalKdevelopGenerator.cxx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. Copyright (c) 2004 Alexander Neundorf, [email protected]. All rights reserved.
  9. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  10. This software is distributed WITHOUT ANY WARRANTY; without even
  11. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE. See the above copyright notices for more information.
  13. =========================================================================*/
  14. #include "cmGlobalGenerator.h"
  15. #include "cmLocalKdevelopGenerator.h"
  16. #include "cmMakefile.h"
  17. #include "cmSystemTools.h"
  18. #include "cmSourceFile.h"
  19. #include "cmMakeDepend.h"
  20. #include "cmCacheManager.h"
  21. #include "cmGeneratedFileStream.h"
  22. #include <cmsys/RegularExpression.hxx>
  23. #include <iostream>
  24. cmLocalKdevelopGenerator::cmLocalKdevelopGenerator()
  25. :cmLocalUnixMakefileGenerator()
  26. {
  27. }
  28. cmLocalKdevelopGenerator::~cmLocalKdevelopGenerator()
  29. {
  30. }
  31. #include <stdio.h>
  32. #include <string>
  33. #include <vector>
  34. void cmLocalKdevelopGenerator::Generate(bool fromTheTop)
  35. {
  36. cmLocalUnixMakefileGenerator::Generate(fromTheTop);
  37. bool containsTargets=false;
  38. std::string executable;
  39. cmTargets& targets=m_Makefile->GetTargets();
  40. for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++)
  41. {
  42. switch (ti->second.GetType())
  43. {
  44. case cmTarget::EXECUTABLE:
  45. executable=ti->first;
  46. case cmTarget::STATIC_LIBRARY:
  47. case cmTarget::SHARED_LIBRARY:
  48. case cmTarget::MODULE_LIBRARY:
  49. case cmTarget::UTILITY:
  50. containsTargets=true;
  51. break;
  52. case cmTarget::INSTALL_FILES:
  53. case cmTarget::INSTALL_PROGRAMS:
  54. default:
  55. break;
  56. }
  57. }
  58. if (containsTargets)
  59. {
  60. std::string projectFileDir=m_Makefile->GetStartOutputDirectory();
  61. std::string filelistDir=m_Makefile->GetDefinition("PROJECT_SOURCE_DIR");
  62. //build the project name by taking the subdir
  63. std::string projectName=m_Makefile->GetProjectName();
  64. projectName+=m_Makefile->GetStartOutputDirectory();
  65. cmSystemTools::ReplaceString(projectName, filelistDir.c_str(), "");
  66. cmSystemTools::ReplaceString(projectName, "/", "_");
  67. std::string cmakeFilePattern("*/CMakeLists.txt;*.cmake;");
  68. if (!this->CreateFilelistFile(filelistDir, projectName, cmakeFilePattern))
  69. {
  70. return;
  71. }
  72. this->CreateProjectFile(filelistDir, projectName, executable, cmakeFilePattern);
  73. }
  74. }
  75. void cmLocalKdevelopGenerator::CreateProjectFile(const std::string& dir,
  76. const std::string& projectname,
  77. const std::string& executable,
  78. const std::string& cmakeFilePattern)
  79. {
  80. std::string filename=m_Makefile->GetStartOutputDirectory();
  81. filename+="/";
  82. filename+=projectname+".kdevelop";
  83. if (cmSystemTools::FileExists(filename.c_str()))
  84. {
  85. this->MergeProjectFiles(dir, filename, executable, cmakeFilePattern);
  86. }
  87. else
  88. {
  89. this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern);
  90. }
  91. }
  92. void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir,
  93. const std::string& filename,
  94. const std::string& executable,
  95. const std::string& cmakeFilePattern)
  96. {
  97. std::ifstream oldProjectFile(filename.c_str());
  98. if (!oldProjectFile)
  99. {
  100. this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern);
  101. return;
  102. }
  103. std::string tmp;
  104. std::vector<std::string> lines;
  105. while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp))
  106. {
  107. lines.push_back(tmp);
  108. }
  109. oldProjectFile.close();
  110. cmGeneratedFileStream tempFile(filename.c_str());
  111. tempFile.SetAlwaysCopy(true);
  112. std::ostream& fout = tempFile.GetStream();
  113. if(!fout)
  114. {
  115. cmSystemTools::Error("Error can not open for write: ", filename.c_str());
  116. return;
  117. }
  118. for (std::vector<std::string>::const_iterator it=lines.begin();
  119. it!=lines.end(); it++)
  120. {
  121. const char* line=(*it).c_str();
  122. if ((strstr(line, "<projectdirectory>")!=0)
  123. || (strstr(line, "<projectmanagement>")!=0)
  124. || (strstr(line, "<absoluteprojectpath>")!=0)
  125. || (strstr(line, "<buildtool>")!=0)
  126. || (strstr(line, "<builddir>")!=0))
  127. {
  128. continue;
  129. }
  130. fout<<*it<<"\n";
  131. if (strstr(line, "<general>"))
  132. {
  133. fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
  134. fout<<" <projectdirectory>"<<dir.c_str()<<"</projectdirectory>\n"; //this one is important
  135. fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
  136. }
  137. if (strstr(line, "<build>"))
  138. {
  139. fout<<" <buildtool>make</buildtool>\n"; //this one is important
  140. fout<<" <builddir>"<<m_Makefile->GetStartOutputDirectory()<<"</builddir>\n"; //and this one
  141. }
  142. }
  143. }
  144. void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, const std::string& filename,
  145. const std::string& executable, const std::string& cmakeFilePattern)
  146. {
  147. cmGeneratedFileStream tempFile(filename.c_str());
  148. tempFile.SetAlwaysCopy(true);
  149. std::ostream& fout = tempFile.GetStream();
  150. if(!fout)
  151. {
  152. cmSystemTools::Error("Error can not open for write: ", filename.c_str());
  153. return;
  154. }
  155. fout<<"<?xml version = '1.0'?>\n";
  156. fout<<"<kdevelop>\n";
  157. fout<<" <general>\n";
  158. fout<<" <author></author>\n";
  159. fout<<" <email></email>\n";
  160. fout<<" <version>$VERSION$</version>\n";
  161. fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
  162. fout<<" <primarylanguage>C++</primarylanguage>\n";
  163. fout<<" <ignoreparts/>\n";
  164. fout<<" <projectdirectory>"<<dir.c_str()<<"</projectdirectory>\n"; //this one is important
  165. fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
  166. fout<<" <secondaryLanguages>\n";
  167. fout<<" <language>C</language>\n";
  168. fout<<" </secondaryLanguages>\n";
  169. fout<<" </general>\n";
  170. fout<<" <kdevcustomproject>\n";
  171. fout<<" <run>\n";
  172. fout<<" <mainprogram>"<<m_Makefile->GetStartOutputDirectory()<<"/"<<executable.c_str()<<"</mainprogram>\n";
  173. fout<<" <directoryradio>custom</directoryradio>\n";
  174. fout<<" <customdirectory>/</customdirectory>\n";
  175. fout<<" <programargs></programargs>\n";
  176. fout<<" <terminal>false</terminal>\n";
  177. fout<<" <autocompile>true</autocompile>\n";
  178. fout<<" <envvars/>\n";
  179. fout<<" </run>\n";
  180. fout<<" <build>\n";
  181. fout<<" <buildtool>make</buildtool>\n"; //this one is important
  182. fout<<" <builddir>"<<m_Makefile->GetStartOutputDirectory()<<"</builddir>\n"; //and this one
  183. fout<<" </build>\n";
  184. fout<<" <make>\n";
  185. fout<<" <abortonerror>false</abortonerror>\n";
  186. fout<<" <numberofjobs>1</numberofjobs>\n";
  187. fout<<" <dontact>false</dontact>\n";
  188. fout<<" <makebin></makebin>\n";
  189. fout<<" <selectedenvironment>default</selectedenvironment>\n";
  190. fout<<" <environments>\n";
  191. fout<<" <default/>\n";
  192. fout<<" </environments>\n";
  193. fout<<" </make>\n";
  194. fout<<" </kdevcustomproject>\n";
  195. fout<<" <kdevfileCreate>\n";
  196. fout<<" <filetypes/>\n";
  197. fout<<" <useglobaltypes>\n";
  198. fout<<" <type ext=\"ui\" />\n";
  199. fout<<" <type ext=\"cpp\" />\n";
  200. fout<<" <type ext=\"h\" />\n";
  201. fout<<" </useglobaltypes>\n";
  202. fout<<" </kdevfilecreate>\n";
  203. fout<<" <kdevdoctreeview>\n";
  204. fout<<" <projectdoc>\n";
  205. fout<<" <userdocDir>html/</userdocDir>\n";
  206. fout<<" <apidocDir>html/</apidocDir>\n";
  207. fout<<" </projectdoc>\n";
  208. fout<<" <ignoreqt_xml/>\n";
  209. fout<<" <ignoredoxygen/>\n";
  210. fout<<" <ignorekdocs/>\n";
  211. fout<<" <ignoretocs/>\n";
  212. fout<<" <ignoredevhelp/>\n";
  213. fout<<" </kdevdoctreeview>\n";
  214. fout<<" <cppsupportpart>\n";
  215. fout<<" <filetemplates>\n";
  216. fout<<" <interfacesuffix>.h</interfacesuffix>\n";
  217. fout<<" <implementationsuffix>.cpp</implementationsuffix>\n";
  218. fout<<" </filetemplates>\n";
  219. fout<<" </cppsupportpart>\n";
  220. fout<<" <kdevcppsupport>\n";
  221. fout<<" <codecompletion>\n";
  222. fout<<" <includeGlobalFunctions>true</includeGlobalFunctions>\n";
  223. fout<<" <includeTypes>true</includeTypes>\n";
  224. fout<<" <includeEnums>true</includeEnums>\n";
  225. fout<<" <includeTypedefs>false</includeTypedefs>\n";
  226. fout<<" <automaticCodeCompletion>true</automaticCodeCompletion>\n";
  227. fout<<" <automaticArgumentsHint>true</automaticArgumentsHint>\n";
  228. fout<<" <automaticHeaderCompletion>true</automaticHeaderCompletion>\n";
  229. fout<<" <codeCompletionDelay>250</codeCompletionDelay>\n";
  230. fout<<" <argumentsHintDelay>400</argumentsHintDelay>\n";
  231. fout<<" <headerCompletionDelay>250</headerCompletionDelay>\n";
  232. fout<<" </codecompletion>\n";
  233. fout<<" <references/>\n";
  234. fout<<" </kdevcppsupport>\n";
  235. fout<<" <kdevfileview>\n";
  236. fout<<" <groups>\n";
  237. fout<<" <group pattern=\""<<cmakeFilePattern.c_str()<<"\" name=\"CMake\" />\n";
  238. fout<<" <group pattern=\"*.h;*.hxx\" name=\"Header\" />\n";
  239. fout<<" <group pattern=\"*.cpp;*.c;*.C;*.cxx\" name=\"Sources\" />\n";
  240. fout<<" <group pattern=\"*.ui\" name=\"Qt Designer files\" />\n";
  241. fout<<" <hidenonprojectfiles>true</hidenonprojectfiles>\n";
  242. fout<<" </groups>\n";
  243. fout<<" <tree>\n";
  244. fout<<" <hidepatterns>*.o,*.lo,CVS,*~,cmake*</hidepatterns>\n";
  245. fout<<" <hidenonprojectfiles>true</hidenonprojectfiles>\n";
  246. fout<<" </tree>\n";
  247. fout<<" </kdevfileview>\n";
  248. fout<<"</kdevelop>\n";
  249. }
  250. bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir,
  251. const std::string& projectname,
  252. std::string& cmakeFilePattern)
  253. {
  254. std::string filelistDir=_dir+"/";
  255. std::string filename=filelistDir+projectname+".kdevelop.filelist";
  256. std::set<cmStdString> files;
  257. //get all cmake files
  258. std::string tmp;
  259. const std::vector<std::string>& listFiles=m_Makefile->GetListFiles();
  260. for (std::vector<std::string>::const_iterator it=listFiles.begin(); it!=listFiles.end(); it++)
  261. {
  262. tmp=*it;
  263. cmSystemTools::ReplaceString(tmp, filelistDir.c_str(), "");
  264. if (tmp[0]!='/')
  265. {
  266. files.insert(tmp);
  267. tmp=cmSystemTools::GetFilenameName(tmp);
  268. //add all files which dont match the default */CMakeLists.txt;*cmake; to the file pattern
  269. if ((tmp!="CMakeLists.txt")
  270. && (strstr(tmp.c_str(), ".cmake")==0))
  271. {
  272. cmakeFilePattern+="*/"+tmp+";";
  273. }
  274. }
  275. }
  276. //get all sources
  277. cmTargets& targets=m_Makefile->GetTargets();
  278. for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++)
  279. {
  280. const std::vector<std::string>& sources=ti->second.GetSourceLists();
  281. for (std::vector<std::string>::const_iterator it=sources.begin(); it!=sources.end(); it++)
  282. {
  283. tmp=*it;
  284. if (tmp[0]!='/') //no absolute path
  285. {
  286. tmp=std::string(m_Makefile->GetDefinition("CMAKE_CURRENT_SOURCE_DIR"))+"/"+tmp;
  287. }
  288. tmp=cmSystemTools::CollapseFullPath(tmp.c_str());
  289. cmSystemTools::ReplaceString(tmp, filelistDir.c_str(), "");
  290. if (tmp[0]=='/')
  291. {
  292. std::string errorMessage("In order to get working KDevelop project files, you have to call "
  293. "PROJECT() in a directory which is a parent directory of all source files. The source file ");
  294. errorMessage+=tmp+" is not located beneath your current project directory "+filelistDir+" .";
  295. cmSystemTools::Error(errorMessage.c_str());
  296. return false;
  297. }
  298. files.insert(tmp);
  299. }
  300. }
  301. //check if the output file already exists and read it
  302. //insert all files which exist into the set of files
  303. std::ifstream oldFilelist(filename.c_str());
  304. if (oldFilelist)
  305. {
  306. while (cmSystemTools::GetLineFromStream(oldFilelist, tmp))
  307. {
  308. if (tmp[0]=='/')
  309. {
  310. continue;
  311. }
  312. std::string completePath=filelistDir+tmp;
  313. if (cmSystemTools::FileExists(completePath.c_str()))
  314. {
  315. files.insert(tmp);
  316. }
  317. }
  318. oldFilelist.close();
  319. }
  320. cmGeneratedFileStream tempFile(filename.c_str());
  321. tempFile.SetAlwaysCopy(true);
  322. std::ostream& fout = tempFile.GetStream();
  323. if(!fout)
  324. {
  325. cmSystemTools::Error("Error can not open for write: ", filename.c_str());
  326. return false;
  327. }
  328. for (std::set<cmStdString>::const_iterator it=files.begin(); it!=files.end(); it++)
  329. {
  330. fout<<*it<<"\n";
  331. }
  332. return true;
  333. }