cmGlobalKdevelopGenerator.cxx 21 KB

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