cmGlobalKdevelopGenerator.cxx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  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 "cmGlobalKdevelopGenerator.h"
  12. #include "cmGeneratedFileStream.h"
  13. #include "cmGeneratorTarget.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmLocalGenerator.h"
  16. #include "cmMakefile.h"
  17. #include "cmSourceFile.h"
  18. #include "cmState.h"
  19. #include "cmSystemTools.h"
  20. #include "cmTarget.h"
  21. #include "cmXMLWriter.h"
  22. #include "cmake.h"
  23. #include <cmsys/Directory.hxx>
  24. #include <cmsys/FStream.hxx>
  25. #include <map>
  26. #include <set>
  27. #include <string.h>
  28. #include <utility>
  29. cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
  30. : cmExternalMakefileProjectGenerator()
  31. {
  32. }
  33. cmExternalMakefileProjectGeneratorFactory*
  34. cmGlobalKdevelopGenerator::GetFactory()
  35. {
  36. static cmExternalMakefileProjectGeneratorSimpleFactory<
  37. cmGlobalKdevelopGenerator>
  38. factory("KDevelop3", "Generates KDevelop 3 project files.");
  39. if (factory.GetSupportedGlobalGenerators().empty()) {
  40. factory.AddSupportedGlobalGenerator("Unix Makefiles");
  41. #ifdef CMAKE_USE_NINJA
  42. factory.AddSupportedGlobalGenerator("Ninja");
  43. #endif
  44. factory.Aliases.push_back("KDevelop3");
  45. }
  46. return &factory;
  47. }
  48. void cmGlobalKdevelopGenerator::Generate()
  49. {
  50. // for each sub project in the project create
  51. // a kdevelop project
  52. for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
  53. it = this->GlobalGenerator->GetProjectMap().begin();
  54. it != this->GlobalGenerator->GetProjectMap().end(); ++it) {
  55. std::string outputDir = it->second[0]->GetCurrentBinaryDirectory();
  56. std::string projectDir = it->second[0]->GetSourceDirectory();
  57. std::string projectName = it->second[0]->GetProjectName();
  58. std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
  59. std::string fileToOpen;
  60. const std::vector<cmLocalGenerator*>& lgs = it->second;
  61. // create the project.kdevelop.filelist file
  62. if (!this->CreateFilelistFile(lgs, outputDir, projectDir, projectName,
  63. cmakeFilePattern, fileToOpen)) {
  64. cmSystemTools::Error("Can not create filelist file");
  65. return;
  66. }
  67. // try to find the name of an executable so we have something to
  68. // run from kdevelop for now just pick the first executable found
  69. std::string executable;
  70. for (std::vector<cmLocalGenerator*>::const_iterator lg = lgs.begin();
  71. lg != lgs.end(); lg++) {
  72. std::vector<cmGeneratorTarget*> const& targets =
  73. (*lg)->GetGeneratorTargets();
  74. for (std::vector<cmGeneratorTarget*>::const_iterator ti =
  75. targets.begin();
  76. ti != targets.end(); ti++) {
  77. if ((*ti)->GetType() == cmState::EXECUTABLE) {
  78. executable = (*ti)->GetLocation("");
  79. break;
  80. }
  81. }
  82. if (!executable.empty()) {
  83. break;
  84. }
  85. }
  86. // now create a project file
  87. this->CreateProjectFile(outputDir, projectDir, projectName, executable,
  88. cmakeFilePattern, fileToOpen);
  89. }
  90. }
  91. bool cmGlobalKdevelopGenerator::CreateFilelistFile(
  92. const std::vector<cmLocalGenerator*>& lgs, const std::string& outputDir,
  93. const std::string& projectDirIn, const std::string& projectname,
  94. std::string& cmakeFilePattern, std::string& fileToOpen)
  95. {
  96. std::string projectDir = projectDirIn + "/";
  97. std::string filename = outputDir + "/" + projectname + ".kdevelop.filelist";
  98. std::set<std::string> files;
  99. std::string tmp;
  100. std::vector<std::string> hdrExts =
  101. this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
  102. for (std::vector<cmLocalGenerator*>::const_iterator it = lgs.begin();
  103. it != lgs.end(); it++) {
  104. cmMakefile* makefile = (*it)->GetMakefile();
  105. const std::vector<std::string>& listFiles = makefile->GetListFiles();
  106. for (std::vector<std::string>::const_iterator lt = listFiles.begin();
  107. lt != listFiles.end(); lt++) {
  108. tmp = *lt;
  109. cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
  110. // make sure the file is part of this source tree
  111. if ((tmp[0] != '/') &&
  112. (strstr(tmp.c_str(), cmake::GetCMakeFilesDirectoryPostSlash()) ==
  113. CM_NULLPTR)) {
  114. files.insert(tmp);
  115. tmp = cmSystemTools::GetFilenameName(tmp);
  116. // add all files which dont match the default
  117. // */CMakeLists.txt;*cmake; to the file pattern
  118. if ((tmp != "CMakeLists.txt") &&
  119. (strstr(tmp.c_str(), ".cmake") == CM_NULLPTR)) {
  120. cmakeFilePattern += tmp + ";";
  121. }
  122. }
  123. }
  124. // get all sources
  125. std::vector<cmGeneratorTarget*> targets = (*it)->GetGeneratorTargets();
  126. for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
  127. ti != targets.end(); ti++) {
  128. std::vector<cmSourceFile*> sources;
  129. cmGeneratorTarget* gt = *ti;
  130. gt->GetSourceFiles(sources, gt->Target->GetMakefile()->GetSafeDefinition(
  131. "CMAKE_BUILD_TYPE"));
  132. for (std::vector<cmSourceFile*>::const_iterator si = sources.begin();
  133. si != sources.end(); si++) {
  134. tmp = (*si)->GetFullPath();
  135. std::string headerBasename = cmSystemTools::GetFilenamePath(tmp);
  136. headerBasename += "/";
  137. headerBasename += cmSystemTools::GetFilenameWithoutExtension(tmp);
  138. cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
  139. if ((tmp[0] != '/') &&
  140. (strstr(tmp.c_str(), cmake::GetCMakeFilesDirectoryPostSlash()) ==
  141. CM_NULLPTR) &&
  142. (cmSystemTools::GetFilenameExtension(tmp) != ".moc")) {
  143. files.insert(tmp);
  144. // check if there's a matching header around
  145. for (std::vector<std::string>::const_iterator ext = hdrExts.begin();
  146. ext != hdrExts.end(); ++ext) {
  147. std::string hname = headerBasename;
  148. hname += ".";
  149. hname += *ext;
  150. if (cmSystemTools::FileExists(hname.c_str())) {
  151. cmSystemTools::ReplaceString(hname, projectDir.c_str(), "");
  152. files.insert(hname);
  153. break;
  154. }
  155. }
  156. }
  157. }
  158. for (std::vector<std::string>::const_iterator lt = listFiles.begin();
  159. lt != listFiles.end(); lt++) {
  160. tmp = *lt;
  161. cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
  162. if ((tmp[0] != '/') &&
  163. (strstr(tmp.c_str(), cmake::GetCMakeFilesDirectoryPostSlash()) ==
  164. CM_NULLPTR)) {
  165. files.insert(tmp);
  166. }
  167. }
  168. }
  169. }
  170. // check if the output file already exists and read it
  171. // insert all files which exist into the set of files
  172. cmsys::ifstream oldFilelist(filename.c_str());
  173. if (oldFilelist) {
  174. while (cmSystemTools::GetLineFromStream(oldFilelist, tmp)) {
  175. if (tmp[0] == '/') {
  176. continue;
  177. }
  178. std::string completePath = projectDir + tmp;
  179. if (cmSystemTools::FileExists(completePath.c_str())) {
  180. files.insert(tmp);
  181. }
  182. }
  183. oldFilelist.close();
  184. }
  185. // now write the new filename
  186. cmGeneratedFileStream fout(filename.c_str());
  187. if (!fout) {
  188. return false;
  189. }
  190. fileToOpen = "";
  191. for (std::set<std::string>::const_iterator it = files.begin();
  192. it != files.end(); it++) {
  193. // get the full path to the file
  194. tmp = cmSystemTools::CollapseFullPath(*it, projectDir.c_str());
  195. // just select the first source file
  196. if (fileToOpen.empty()) {
  197. std::string ext = cmSystemTools::GetFilenameExtension(tmp);
  198. if ((ext == ".c") || (ext == ".cc") || (ext == ".cpp") ||
  199. (ext == ".cxx") || (ext == ".C") || (ext == ".h") ||
  200. (ext == ".hpp")) {
  201. fileToOpen = tmp;
  202. }
  203. }
  204. // make it relative to the project dir
  205. cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
  206. // only put relative paths
  207. if (!tmp.empty() && tmp[0] != '/') {
  208. fout << tmp << "\n";
  209. }
  210. }
  211. return true;
  212. }
  213. /* create the project file, if it already exists, merge it with the
  214. existing one, otherwise create a new one */
  215. void cmGlobalKdevelopGenerator::CreateProjectFile(
  216. const std::string& outputDir, const std::string& projectDir,
  217. const std::string& projectname, const std::string& executable,
  218. const std::string& cmakeFilePattern, const std::string& fileToOpen)
  219. {
  220. this->Blacklist.clear();
  221. std::string filename = outputDir + "/";
  222. filename += projectname + ".kdevelop";
  223. std::string sessionFilename = outputDir + "/";
  224. sessionFilename += projectname + ".kdevses";
  225. if (cmSystemTools::FileExists(filename.c_str())) {
  226. this->MergeProjectFiles(outputDir, projectDir, filename, executable,
  227. cmakeFilePattern, fileToOpen, sessionFilename);
  228. } else {
  229. // add all subdirectories which are cmake build directories to the
  230. // kdevelop blacklist so they are not monitored for added or removed files
  231. // since this is handled by adding files to the cmake files
  232. cmsys::Directory d;
  233. if (d.Load(projectDir)) {
  234. size_t numf = d.GetNumberOfFiles();
  235. for (unsigned int i = 0; i < numf; i++) {
  236. std::string nextFile = d.GetFile(i);
  237. if ((nextFile != ".") && (nextFile != "..")) {
  238. std::string tmp = projectDir;
  239. tmp += "/";
  240. tmp += nextFile;
  241. if (cmSystemTools::FileIsDirectory(tmp)) {
  242. tmp += "/CMakeCache.txt";
  243. if ((nextFile == "CMakeFiles") ||
  244. (cmSystemTools::FileExists(tmp.c_str()))) {
  245. this->Blacklist.push_back(nextFile);
  246. }
  247. }
  248. }
  249. }
  250. }
  251. this->CreateNewProjectFile(outputDir, projectDir, filename, executable,
  252. cmakeFilePattern, fileToOpen, sessionFilename);
  253. }
  254. }
  255. void cmGlobalKdevelopGenerator::MergeProjectFiles(
  256. const std::string& outputDir, const std::string& projectDir,
  257. const std::string& filename, const std::string& executable,
  258. const std::string& cmakeFilePattern, const std::string& fileToOpen,
  259. const std::string& sessionFilename)
  260. {
  261. cmsys::ifstream oldProjectFile(filename.c_str());
  262. if (!oldProjectFile) {
  263. this->CreateNewProjectFile(outputDir, projectDir, filename, executable,
  264. cmakeFilePattern, fileToOpen, sessionFilename);
  265. return;
  266. }
  267. /* Read the existing project file (line by line), copy all lines
  268. into the new project file, except the ones which can be reliably
  269. set from contents of the CMakeLists.txt */
  270. std::string tmp;
  271. std::vector<std::string> lines;
  272. while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp)) {
  273. lines.push_back(tmp);
  274. }
  275. oldProjectFile.close();
  276. cmGeneratedFileStream fout(filename.c_str());
  277. if (!fout) {
  278. return;
  279. }
  280. for (std::vector<std::string>::const_iterator it = lines.begin();
  281. it != lines.end(); it++) {
  282. const char* line = (*it).c_str();
  283. // skip these tags as they are always replaced
  284. if ((strstr(line, "<projectdirectory>") != CM_NULLPTR) ||
  285. (strstr(line, "<projectmanagement>") != CM_NULLPTR) ||
  286. (strstr(line, "<absoluteprojectpath>") != CM_NULLPTR) ||
  287. (strstr(line, "<filelistdirectory>") != CM_NULLPTR) ||
  288. (strstr(line, "<buildtool>") != CM_NULLPTR) ||
  289. (strstr(line, "<builddir>") != CM_NULLPTR)) {
  290. continue;
  291. }
  292. // output the line from the file if it is not one of the above tags
  293. fout << *it << "\n";
  294. // if this is the <general> tag output the stuff that goes in the
  295. // general tag
  296. if (strstr(line, "<general>")) {
  297. fout << " <projectmanagement>KDevCustomProject</projectmanagement>\n";
  298. fout << " <projectdirectory>" << projectDir
  299. << "</projectdirectory>\n"; // this one is important
  300. fout << " <absoluteprojectpath>true</absoluteprojectpath>\n";
  301. // and this one
  302. }
  303. // inside kdevcustomproject the <filelistdirectory> must be put
  304. if (strstr(line, "<kdevcustomproject>")) {
  305. fout << " <filelistdirectory>" << outputDir
  306. << "</filelistdirectory>\n";
  307. }
  308. // buildtool and builddir go inside <build>
  309. if (strstr(line, "<build>")) {
  310. fout << " <buildtool>make</buildtool>\n";
  311. fout << " <builddir>" << outputDir << "</builddir>\n";
  312. }
  313. }
  314. }
  315. void cmGlobalKdevelopGenerator::CreateNewProjectFile(
  316. const std::string& outputDir, const std::string& projectDir,
  317. const std::string& filename, const std::string& executable,
  318. const std::string& cmakeFilePattern, const std::string& fileToOpen,
  319. const std::string& sessionFilename)
  320. {
  321. cmGeneratedFileStream fout(filename.c_str());
  322. if (!fout) {
  323. return;
  324. }
  325. cmXMLWriter xml(fout);
  326. // check for a version control system
  327. bool hasSvn = cmSystemTools::FileExists((projectDir + "/.svn").c_str());
  328. bool hasCvs = cmSystemTools::FileExists((projectDir + "/CVS").c_str());
  329. bool enableCxx = (this->GlobalGenerator->GetLanguageEnabled("C") ||
  330. this->GlobalGenerator->GetLanguageEnabled("CXX"));
  331. bool enableFortran = this->GlobalGenerator->GetLanguageEnabled("Fortran");
  332. std::string primaryLanguage = "C++";
  333. if (enableFortran && !enableCxx) {
  334. primaryLanguage = "Fortran77";
  335. }
  336. xml.StartDocument();
  337. xml.StartElement("kdevelop");
  338. xml.StartElement("general");
  339. xml.Element("author", "");
  340. xml.Element("email", "");
  341. xml.Element("version", "$VERSION$");
  342. xml.Element("projectmanagement", "KDevCustomProject");
  343. xml.Element("primarylanguage", primaryLanguage);
  344. xml.Element("ignoreparts");
  345. xml.Element("projectdirectory", projectDir); // this one is important
  346. xml.Element("absoluteprojectpath", "true"); // and this one
  347. // setup additional languages
  348. xml.StartElement("secondaryLanguages");
  349. if (enableFortran && enableCxx) {
  350. xml.Element("language", "Fortran");
  351. }
  352. if (enableCxx) {
  353. xml.Element("language", "C");
  354. }
  355. xml.EndElement();
  356. if (hasSvn) {
  357. xml.Element("versioncontrol", "kdevsubversion");
  358. } else if (hasCvs) {
  359. xml.Element("versioncontrol", "kdevcvsservice");
  360. }
  361. xml.EndElement(); // general
  362. xml.StartElement("kdevcustomproject");
  363. xml.Element("filelistdirectory", outputDir);
  364. xml.StartElement("run");
  365. xml.Element("mainprogram", executable);
  366. xml.Element("directoryradio", "custom");
  367. xml.Element("customdirectory", outputDir);
  368. xml.Element("programargs", "");
  369. xml.Element("terminal", "false");
  370. xml.Element("autocompile", "true");
  371. xml.Element("envvars");
  372. xml.EndElement();
  373. xml.StartElement("build");
  374. xml.Element("buildtool", "make"); // this one is important
  375. xml.Element("builddir", outputDir); // and this one
  376. xml.EndElement();
  377. xml.StartElement("make");
  378. xml.Element("abortonerror", "false");
  379. xml.Element("numberofjobs", 1);
  380. xml.Element("dontact", "false");
  381. xml.Element("makebin", this->GlobalGenerator->GetLocalGenerators()[0]
  382. ->GetMakefile()
  383. ->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"));
  384. xml.Element("selectedenvironment", "default");
  385. xml.StartElement("environments");
  386. xml.StartElement("default");
  387. xml.StartElement("envvar");
  388. xml.Attribute("value", 1);
  389. xml.Attribute("name", "VERBOSE");
  390. xml.EndElement();
  391. xml.StartElement("envvar");
  392. xml.Attribute("value", 1);
  393. xml.Attribute("name", "CMAKE_NO_VERBOSE");
  394. xml.EndElement();
  395. xml.EndElement(); // default
  396. xml.EndElement(); // environments
  397. xml.EndElement(); // make
  398. xml.StartElement("blacklist");
  399. for (std::vector<std::string>::const_iterator dirIt =
  400. this->Blacklist.begin();
  401. dirIt != this->Blacklist.end(); ++dirIt) {
  402. xml.Element("path", *dirIt);
  403. }
  404. xml.EndElement();
  405. xml.EndElement(); // kdevcustomproject
  406. xml.StartElement("kdevfilecreate");
  407. xml.Element("filetypes");
  408. xml.StartElement("useglobaltypes");
  409. xml.StartElement("type");
  410. xml.Attribute("ext", "ui");
  411. xml.EndElement();
  412. xml.StartElement("type");
  413. xml.Attribute("ext", "cpp");
  414. xml.EndElement();
  415. xml.StartElement("type");
  416. xml.Attribute("ext", "h");
  417. xml.EndElement();
  418. xml.EndElement(); // useglobaltypes
  419. xml.EndElement(); // kdevfilecreate
  420. xml.StartElement("kdevdoctreeview");
  421. xml.StartElement("projectdoc");
  422. xml.Element("userdocDir", "html/");
  423. xml.Element("apidocDir", "html/");
  424. xml.EndElement(); // projectdoc
  425. xml.Element("ignoreqt_xml");
  426. xml.Element("ignoredoxygen");
  427. xml.Element("ignorekdocs");
  428. xml.Element("ignoretocs");
  429. xml.Element("ignoredevhelp");
  430. xml.EndElement(); // kdevdoctreeview;
  431. if (enableCxx) {
  432. xml.StartElement("cppsupportpart");
  433. xml.StartElement("filetemplates");
  434. xml.Element("interfacesuffix", ".h");
  435. xml.Element("implementationsuffix", ".cpp");
  436. xml.EndElement(); // filetemplates
  437. xml.EndElement(); // cppsupportpart
  438. xml.StartElement("kdevcppsupport");
  439. xml.StartElement("codecompletion");
  440. xml.Element("includeGlobalFunctions", "true");
  441. xml.Element("includeTypes", "true");
  442. xml.Element("includeEnums", "true");
  443. xml.Element("includeTypedefs", "false");
  444. xml.Element("automaticCodeCompletion", "true");
  445. xml.Element("automaticArgumentsHint", "true");
  446. xml.Element("automaticHeaderCompletion", "true");
  447. xml.Element("codeCompletionDelay", 250);
  448. xml.Element("argumentsHintDelay", 400);
  449. xml.Element("headerCompletionDelay", 250);
  450. xml.EndElement(); // codecompletion
  451. xml.Element("references");
  452. xml.EndElement(); // kdevcppsupport;
  453. }
  454. if (enableFortran) {
  455. xml.StartElement("kdevfortransupport");
  456. xml.StartElement("ftnchek");
  457. xml.Element("division", "false");
  458. xml.Element("extern", "false");
  459. xml.Element("declare", "false");
  460. xml.Element("pure", "false");
  461. xml.Element("argumentsall", "false");
  462. xml.Element("commonall", "false");
  463. xml.Element("truncationall", "false");
  464. xml.Element("usageall", "false");
  465. xml.Element("f77all", "false");
  466. xml.Element("portabilityall", "false");
  467. xml.Element("argumentsonly");
  468. xml.Element("commononly");
  469. xml.Element("truncationonly");
  470. xml.Element("usageonly");
  471. xml.Element("f77only");
  472. xml.Element("portabilityonly");
  473. xml.EndElement(); // ftnchek
  474. xml.EndElement(); // kdevfortransupport;
  475. }
  476. // set up file groups. maybe this can be used with the CMake SOURCE_GROUP()
  477. // command
  478. xml.StartElement("kdevfileview");
  479. xml.StartElement("groups");
  480. xml.StartElement("group");
  481. xml.Attribute("pattern", cmakeFilePattern);
  482. xml.Attribute("name", "CMake");
  483. xml.EndElement();
  484. if (enableCxx) {
  485. xml.StartElement("group");
  486. xml.Attribute("pattern", "*.h;*.hxx;*.hpp");
  487. xml.Attribute("name", "Header");
  488. xml.EndElement();
  489. xml.StartElement("group");
  490. xml.Attribute("pattern", "*.c");
  491. xml.Attribute("name", "C Sources");
  492. xml.EndElement();
  493. xml.StartElement("group");
  494. xml.Attribute("pattern", "*.cpp;*.C;*.cxx;*.cc");
  495. xml.Attribute("name", "C++ Sources");
  496. xml.EndElement();
  497. }
  498. if (enableFortran) {
  499. xml.StartElement("group");
  500. xml.Attribute("pattern",
  501. "*.f;*.F;*.f77;*.F77;*.f90;*.F90;*.for;*.f95;*.F95");
  502. xml.Attribute("name", "Fortran Sources");
  503. xml.EndElement();
  504. }
  505. xml.StartElement("group");
  506. xml.Attribute("pattern", "*.ui");
  507. xml.Attribute("name", "Qt Designer files");
  508. xml.EndElement();
  509. xml.Element("hidenonprojectfiles", "true");
  510. xml.EndElement(); // groups
  511. xml.StartElement("tree");
  512. xml.Element("hidepatterns", "*.o,*.lo,CVS,*~,cmake*");
  513. xml.Element("hidenonprojectfiles", "true");
  514. xml.EndElement(); // tree
  515. xml.EndElement(); // kdevfileview
  516. xml.EndElement(); // kdevelop;
  517. xml.EndDocument();
  518. if (sessionFilename.empty()) {
  519. return;
  520. }
  521. // and a session file, so that kdevelop opens a file if it opens the
  522. // project the first time
  523. cmGeneratedFileStream devses(sessionFilename.c_str());
  524. if (!devses) {
  525. return;
  526. }
  527. cmXMLWriter sesxml(devses);
  528. sesxml.StartDocument("UTF-8");
  529. sesxml.Doctype("KDevPrjSession");
  530. sesxml.StartElement("KDevPrjSession");
  531. sesxml.StartElement("DocsAndViews");
  532. sesxml.Attribute("NumberOfDocuments", 1);
  533. sesxml.StartElement("Doc0");
  534. sesxml.Attribute("NumberOfViews", 1);
  535. sesxml.Attribute("URL", "file://" + fileToOpen);
  536. sesxml.StartElement("View0");
  537. sesxml.Attribute("line", 0);
  538. sesxml.Attribute("Type", "Source");
  539. sesxml.EndElement(); // View0
  540. sesxml.EndElement(); // Doc0
  541. sesxml.EndElement(); // DocsAndViews
  542. sesxml.EndElement(); // KDevPrjSession;
  543. }