cmExtraCodeLiteGenerator.cxx 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmExtraCodeLiteGenerator.h"
  4. #include "cmGeneratedFileStream.h"
  5. #include "cmGeneratorTarget.h"
  6. #include "cmGlobalGenerator.h"
  7. #include "cmLocalGenerator.h"
  8. #include "cmMakefile.h"
  9. #include "cmSourceFile.h"
  10. #include "cmStateTypes.h"
  11. #include "cmSystemTools.h"
  12. #include "cmXMLWriter.h"
  13. #include "cmake.h"
  14. #include "cmsys/SystemInformation.hxx"
  15. #include <map>
  16. #include <set>
  17. #include <sstream>
  18. #include <string.h>
  19. #include <utility>
  20. cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator()
  21. : cmExternalMakefileProjectGenerator()
  22. , ConfigName("NoConfig")
  23. , CpuCount(2)
  24. {
  25. }
  26. cmExternalMakefileProjectGeneratorFactory*
  27. cmExtraCodeLiteGenerator::GetFactory()
  28. {
  29. static cmExternalMakefileProjectGeneratorSimpleFactory<
  30. cmExtraCodeLiteGenerator>
  31. factory("CodeLite", "Generates CodeLite project files.");
  32. if (factory.GetSupportedGlobalGenerators().empty()) {
  33. #if defined(_WIN32)
  34. factory.AddSupportedGlobalGenerator("MinGW Makefiles");
  35. factory.AddSupportedGlobalGenerator("NMake Makefiles");
  36. #endif
  37. factory.AddSupportedGlobalGenerator("Ninja");
  38. factory.AddSupportedGlobalGenerator("Unix Makefiles");
  39. }
  40. return &factory;
  41. }
  42. void cmExtraCodeLiteGenerator::Generate()
  43. {
  44. // Hold root tree information for creating the workspace
  45. std::string workspaceProjectName;
  46. std::string workspaceOutputDir;
  47. std::string workspaceFileName;
  48. std::string workspaceSourcePath;
  49. const std::map<std::string, std::vector<cmLocalGenerator*>>& projectMap =
  50. this->GlobalGenerator->GetProjectMap();
  51. // loop projects and locate the root project.
  52. // and extract the information for creating the worspace
  53. // root makefile
  54. for (auto const& it : projectMap) {
  55. const cmMakefile* mf = it.second[0]->GetMakefile();
  56. this->ConfigName = GetConfigurationName(mf);
  57. if (strcmp(it.second[0]->GetCurrentBinaryDirectory(),
  58. it.second[0]->GetBinaryDirectory()) == 0) {
  59. workspaceOutputDir = it.second[0]->GetCurrentBinaryDirectory();
  60. workspaceProjectName = it.second[0]->GetProjectName();
  61. workspaceSourcePath = it.second[0]->GetSourceDirectory();
  62. workspaceFileName = workspaceOutputDir + "/";
  63. workspaceFileName += workspaceProjectName + ".workspace";
  64. this->WorkspacePath = it.second[0]->GetCurrentBinaryDirectory();
  65. ;
  66. break;
  67. }
  68. }
  69. cmGeneratedFileStream fout(workspaceFileName.c_str());
  70. cmXMLWriter xml(fout);
  71. xml.StartDocument("utf-8");
  72. xml.StartElement("CodeLite_Workspace");
  73. xml.Attribute("Name", workspaceProjectName);
  74. bool const targetsAreProjects =
  75. this->GlobalGenerator->GlobalSettingIsOn("CMAKE_CODELITE_USE_TARGETS");
  76. std::vector<std::string> ProjectNames;
  77. if (targetsAreProjects) {
  78. ProjectNames = CreateProjectsByTarget(&xml);
  79. } else {
  80. ProjectNames = CreateProjectsByProjectMaps(&xml);
  81. }
  82. xml.StartElement("BuildMatrix");
  83. xml.StartElement("WorkspaceConfiguration");
  84. xml.Attribute("Name", this->ConfigName);
  85. xml.Attribute("Selected", "yes");
  86. for (std::string const& it : ProjectNames) {
  87. xml.StartElement("Project");
  88. xml.Attribute("Name", it);
  89. xml.Attribute("ConfigName", this->ConfigName);
  90. xml.EndElement();
  91. }
  92. xml.EndElement(); // WorkspaceConfiguration
  93. xml.EndElement(); // BuildMatrix
  94. xml.EndElement(); // CodeLite_Workspace
  95. }
  96. // Create projects where targets are the projects
  97. std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
  98. cmXMLWriter* xml)
  99. {
  100. std::vector<std::string> retval;
  101. // for each target in the workspace create a codelite project
  102. const std::vector<cmLocalGenerator*>& lgs =
  103. this->GlobalGenerator->GetLocalGenerators();
  104. for (cmLocalGenerator* lg : lgs) {
  105. for (cmGeneratorTarget* lt : lg->GetGeneratorTargets()) {
  106. cmStateEnums::TargetType type = lt->GetType();
  107. std::string outputDir = lg->GetCurrentBinaryDirectory();
  108. std::string targetName = lt->GetName();
  109. std::string filename = outputDir + "/" + targetName + ".project";
  110. retval.push_back(targetName);
  111. // Make the project file relative to the workspace
  112. std::string relafilename = cmSystemTools::RelativePath(
  113. this->WorkspacePath.c_str(), filename.c_str());
  114. std::string visualname = targetName;
  115. switch (type) {
  116. case cmStateEnums::SHARED_LIBRARY:
  117. case cmStateEnums::STATIC_LIBRARY:
  118. case cmStateEnums::MODULE_LIBRARY:
  119. visualname = "lib" + visualname;
  120. CM_FALLTHROUGH;
  121. case cmStateEnums::EXECUTABLE:
  122. xml->StartElement("Project");
  123. xml->Attribute("Name", visualname);
  124. xml->Attribute("Path", relafilename);
  125. xml->Attribute("Active", "No");
  126. xml->EndElement();
  127. CreateNewProjectFile(lt, filename);
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133. }
  134. return retval;
  135. }
  136. // The "older way of doing it.
  137. std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps(
  138. cmXMLWriter* xml)
  139. {
  140. std::vector<std::string> retval;
  141. // for each sub project in the workspace create a codelite project
  142. for (auto const& it : this->GlobalGenerator->GetProjectMap()) {
  143. std::string outputDir = it.second[0]->GetCurrentBinaryDirectory();
  144. std::string projectName = it.second[0]->GetProjectName();
  145. retval.push_back(projectName);
  146. std::string filename = outputDir + "/" + projectName + ".project";
  147. // Make the project file relative to the workspace
  148. filename = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
  149. filename.c_str());
  150. // create a project file
  151. this->CreateProjectFile(it.second);
  152. xml->StartElement("Project");
  153. xml->Attribute("Name", projectName);
  154. xml->Attribute("Path", filename);
  155. xml->Attribute("Active", "No");
  156. xml->EndElement();
  157. }
  158. return retval;
  159. }
  160. /* create the project file */
  161. void cmExtraCodeLiteGenerator::CreateProjectFile(
  162. const std::vector<cmLocalGenerator*>& lgs)
  163. {
  164. std::string outputDir = lgs[0]->GetCurrentBinaryDirectory();
  165. std::string projectName = lgs[0]->GetProjectName();
  166. std::string filename = outputDir + "/";
  167. filename += projectName + ".project";
  168. this->CreateNewProjectFile(lgs, filename);
  169. }
  170. std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
  171. const cmMakefile* makefile, const cmGeneratorTarget* gt,
  172. std::map<std::string, cmSourceFile*>& cFiles,
  173. std::set<std::string>& otherFiles)
  174. {
  175. const std::vector<std::string>& srcExts =
  176. this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
  177. std::string projectType;
  178. switch (gt->GetType()) {
  179. case cmStateEnums::EXECUTABLE: {
  180. projectType = "Executable";
  181. } break;
  182. case cmStateEnums::STATIC_LIBRARY: {
  183. projectType = "Static Library";
  184. } break;
  185. case cmStateEnums::SHARED_LIBRARY: {
  186. projectType = "Dynamic Library";
  187. } break;
  188. case cmStateEnums::MODULE_LIBRARY: {
  189. projectType = "Dynamic Library";
  190. } break;
  191. default: // intended fallthrough
  192. break;
  193. }
  194. switch (gt->GetType()) {
  195. case cmStateEnums::EXECUTABLE:
  196. case cmStateEnums::STATIC_LIBRARY:
  197. case cmStateEnums::SHARED_LIBRARY:
  198. case cmStateEnums::MODULE_LIBRARY: {
  199. std::vector<cmSourceFile*> sources;
  200. gt->GetSourceFiles(sources,
  201. makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
  202. for (cmSourceFile* s : sources) {
  203. // check whether it is a C/C++ implementation file
  204. bool isCFile = false;
  205. std::string lang = s->GetLanguage();
  206. if (lang == "C" || lang == "CXX") {
  207. std::string const& srcext = s->GetExtension();
  208. for (std::string const& ext : srcExts) {
  209. if (srcext == ext) {
  210. isCFile = true;
  211. break;
  212. }
  213. }
  214. }
  215. // then put it accordingly into one of the two containers
  216. if (isCFile) {
  217. cFiles[s->GetFullPath()] = s;
  218. } else {
  219. otherFiles.insert(s->GetFullPath());
  220. }
  221. }
  222. }
  223. default: // intended fallthrough
  224. break;
  225. }
  226. return projectType;
  227. }
  228. void cmExtraCodeLiteGenerator::CreateNewProjectFile(
  229. const std::vector<cmLocalGenerator*>& lgs, const std::string& filename)
  230. {
  231. const cmMakefile* mf = lgs[0]->GetMakefile();
  232. cmGeneratedFileStream fout(filename.c_str());
  233. if (!fout) {
  234. return;
  235. }
  236. cmXMLWriter xml(fout);
  237. ////////////////////////////////////
  238. xml.StartDocument("utf-8");
  239. xml.StartElement("CodeLite_Project");
  240. xml.Attribute("Name", lgs[0]->GetProjectName());
  241. xml.Attribute("InternalType", "");
  242. std::string projectType;
  243. // Collect all used source files in the project
  244. // Sort them into two containers, one for C/C++ implementation files
  245. // which may have an acompanying header, one for all other files
  246. std::map<std::string, cmSourceFile*> cFiles;
  247. std::set<std::string> otherFiles;
  248. for (cmLocalGenerator* lg : lgs) {
  249. cmMakefile* makefile = lg->GetMakefile();
  250. const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
  251. for (cmGeneratorTarget* target : targets) {
  252. projectType = CollectSourceFiles(makefile, target, cFiles, otherFiles);
  253. }
  254. }
  255. // Get the project path ( we need it later to convert files to
  256. // their relative path)
  257. std::string projectPath = cmSystemTools::GetFilenamePath(filename);
  258. CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
  259. projectType, "");
  260. xml.EndElement(); // CodeLite_Project
  261. }
  262. void cmExtraCodeLiteGenerator::FindMatchingHeaderfiles(
  263. std::map<std::string, cmSourceFile*>& cFiles,
  264. std::set<std::string>& otherFiles)
  265. {
  266. const std::vector<std::string>& headerExts =
  267. this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
  268. // The following loop tries to add header files matching to implementation
  269. // files to the project. It does that by iterating over all source files,
  270. // replacing the file name extension with ".h" and checks whether such a
  271. // file exists. If it does, it is inserted into the map of files.
  272. // A very similar version of that code exists also in the kdevelop
  273. // project generator.
  274. for (auto const& sit : cFiles) {
  275. std::string headerBasename = cmSystemTools::GetFilenamePath(sit.first);
  276. headerBasename += "/";
  277. headerBasename += cmSystemTools::GetFilenameWithoutExtension(sit.first);
  278. // check if there's a matching header around
  279. for (std::string const& ext : headerExts) {
  280. std::string hname = headerBasename;
  281. hname += ".";
  282. hname += ext;
  283. // if it's already in the set, don't check if it exists on disk
  284. std::set<std::string>::const_iterator headerIt = otherFiles.find(hname);
  285. if (headerIt != otherFiles.end()) {
  286. break;
  287. }
  288. if (cmSystemTools::FileExists(hname.c_str())) {
  289. otherFiles.insert(hname);
  290. break;
  291. }
  292. }
  293. }
  294. }
  295. void cmExtraCodeLiteGenerator::CreateFoldersAndFiles(
  296. std::set<std::string>& cFiles, cmXMLWriter& xml,
  297. const std::string& projectPath)
  298. {
  299. std::vector<std::string> tmp_path;
  300. std::vector<std::string> components;
  301. size_t numOfEndEl = 0;
  302. for (std::string const& cFile : cFiles) {
  303. std::string frelapath =
  304. cmSystemTools::RelativePath(projectPath.c_str(), cFile.c_str());
  305. cmsys::SystemTools::SplitPath(frelapath, components, false);
  306. components.pop_back(); // erase last member -> it is file, not folder
  307. components.erase(components.begin()); // erase "root"
  308. size_t sizeOfSkip = 0;
  309. for (size_t i = 0; i < components.size(); ++i) {
  310. // skip relative path
  311. if (components[i] == ".." || components[i] == ".") {
  312. sizeOfSkip++;
  313. continue;
  314. }
  315. // same folder
  316. if (tmp_path.size() > i - sizeOfSkip &&
  317. tmp_path[i - sizeOfSkip] == components[i]) {
  318. continue;
  319. }
  320. // delete "old" subfolders
  321. if (tmp_path.size() > i - sizeOfSkip) {
  322. numOfEndEl = tmp_path.size() - i + sizeOfSkip;
  323. tmp_path.erase(tmp_path.end() - numOfEndEl, tmp_path.end());
  324. for (; numOfEndEl--;) {
  325. xml.EndElement();
  326. }
  327. }
  328. // add folder
  329. xml.StartElement("VirtualDirectory");
  330. xml.Attribute("Name", components[i]);
  331. tmp_path.push_back(components[i]);
  332. }
  333. // delete "old" subfolders
  334. numOfEndEl = tmp_path.size() - components.size() + sizeOfSkip;
  335. if (numOfEndEl) {
  336. tmp_path.erase(tmp_path.end() - numOfEndEl, tmp_path.end());
  337. for (; numOfEndEl--;) {
  338. xml.EndElement();
  339. }
  340. }
  341. // add file
  342. xml.StartElement("File");
  343. xml.Attribute("Name", frelapath);
  344. xml.EndElement();
  345. }
  346. // end of folders
  347. numOfEndEl = tmp_path.size();
  348. for (; numOfEndEl--;) {
  349. xml.EndElement();
  350. }
  351. }
  352. void cmExtraCodeLiteGenerator::CreateFoldersAndFiles(
  353. std::map<std::string, cmSourceFile*>& cFiles, cmXMLWriter& xml,
  354. const std::string& projectPath)
  355. {
  356. std::set<std::string> s;
  357. for (auto const& it : cFiles) {
  358. s.insert(it.first);
  359. }
  360. this->CreateFoldersAndFiles(s, xml, projectPath);
  361. }
  362. void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
  363. std::map<std::string, cmSourceFile*>& cFiles,
  364. std::set<std::string>& otherFiles, cmXMLWriter* _xml,
  365. const std::string& projectPath, const cmMakefile* mf,
  366. const std::string& projectType, const std::string& targetName)
  367. {
  368. cmXMLWriter& xml(*_xml);
  369. FindMatchingHeaderfiles(cFiles, otherFiles);
  370. // Create 2 virtual folders: src and include
  371. // and place all the implementation files into the src
  372. // folder, the rest goes to the include folder
  373. xml.StartElement("VirtualDirectory");
  374. xml.Attribute("Name", "src");
  375. // insert all source files in the codelite project
  376. // first the C/C++ implementation files, then all others
  377. this->CreateFoldersAndFiles(cFiles, xml, projectPath);
  378. xml.EndElement(); // VirtualDirectory
  379. xml.StartElement("VirtualDirectory");
  380. xml.Attribute("Name", "include");
  381. this->CreateFoldersAndFiles(otherFiles, xml, projectPath);
  382. xml.EndElement(); // VirtualDirectory
  383. // Get the number of CPUs. We use this information for the make -jN
  384. // command
  385. cmsys::SystemInformation info;
  386. info.RunCPUCheck();
  387. this->CpuCount =
  388. info.GetNumberOfLogicalCPU() * info.GetNumberOfPhysicalCPU();
  389. std::string codeliteCompilerName = this->GetCodeLiteCompilerName(mf);
  390. xml.StartElement("Settings");
  391. xml.Attribute("Type", projectType);
  392. xml.StartElement("Configuration");
  393. xml.Attribute("Name", this->ConfigName);
  394. xml.Attribute("CompilerType", this->GetCodeLiteCompilerName(mf));
  395. xml.Attribute("DebuggerType", "GNU gdb debugger");
  396. xml.Attribute("Type", projectType);
  397. xml.Attribute("BuildCmpWithGlobalSettings", "append");
  398. xml.Attribute("BuildLnkWithGlobalSettings", "append");
  399. xml.Attribute("BuildResWithGlobalSettings", "append");
  400. xml.StartElement("Compiler");
  401. xml.Attribute("Options", "-g");
  402. xml.Attribute("Required", "yes");
  403. xml.Attribute("PreCompiledHeader", "");
  404. xml.StartElement("IncludePath");
  405. xml.Attribute("Value", ".");
  406. xml.EndElement(); // IncludePath
  407. xml.EndElement(); // Compiler
  408. xml.StartElement("Linker");
  409. xml.Attribute("Options", "");
  410. xml.Attribute("Required", "yes");
  411. xml.EndElement(); // Linker
  412. xml.StartElement("ResourceCompiler");
  413. xml.Attribute("Options", "");
  414. xml.Attribute("Required", "no");
  415. xml.EndElement(); // ResourceCompiler
  416. xml.StartElement("General");
  417. std::string outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
  418. std::string relapath;
  419. if (!outputPath.empty()) {
  420. relapath = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
  421. outputPath.c_str());
  422. xml.Attribute("OutputFile", relapath + "/$(ProjectName)");
  423. } else {
  424. xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)");
  425. }
  426. xml.Attribute("IntermediateDirectory", "./");
  427. xml.Attribute("Command", "./$(ProjectName)");
  428. xml.Attribute("CommandArguments", "");
  429. if (!outputPath.empty()) {
  430. xml.Attribute("WorkingDirectory", relapath);
  431. } else {
  432. xml.Attribute("WorkingDirectory", "$(IntermediateDirectory)");
  433. }
  434. xml.Attribute("PauseExecWhenProcTerminates", "yes");
  435. xml.EndElement(); // General
  436. xml.StartElement("Debugger");
  437. xml.Attribute("IsRemote", "no");
  438. xml.Attribute("RemoteHostName", "");
  439. xml.Attribute("RemoteHostPort", "");
  440. xml.Attribute("DebuggerPath", "");
  441. xml.Element("PostConnectCommands");
  442. xml.Element("StartupCommands");
  443. xml.EndElement(); // Debugger
  444. xml.Element("PreBuild");
  445. xml.Element("PostBuild");
  446. xml.StartElement("CustomBuild");
  447. xml.Attribute("Enabled", "yes");
  448. xml.Element("RebuildCommand", GetRebuildCommand(mf, targetName));
  449. xml.Element("CleanCommand", GetCleanCommand(mf, targetName));
  450. xml.Element("BuildCommand", GetBuildCommand(mf, targetName));
  451. xml.Element("SingleFileCommand", GetSingleFileBuildCommand(mf));
  452. xml.Element("PreprocessFileCommand");
  453. xml.Element("WorkingDirectory", "$(WorkspacePath)");
  454. xml.EndElement(); // CustomBuild
  455. xml.StartElement("AdditionalRules");
  456. xml.Element("CustomPostBuild");
  457. xml.Element("CustomPreBuild");
  458. xml.EndElement(); // AdditionalRules
  459. xml.EndElement(); // Configuration
  460. xml.StartElement("GlobalSettings");
  461. xml.StartElement("Compiler");
  462. xml.Attribute("Options", "");
  463. xml.StartElement("IncludePath");
  464. xml.Attribute("Value", ".");
  465. xml.EndElement(); // IncludePath
  466. xml.EndElement(); // Compiler
  467. xml.StartElement("Linker");
  468. xml.Attribute("Options", "");
  469. xml.StartElement("LibraryPath");
  470. xml.Attribute("Value", ".");
  471. xml.EndElement(); // LibraryPath
  472. xml.EndElement(); // Linker
  473. xml.StartElement("ResourceCompiler");
  474. xml.Attribute("Options", "");
  475. xml.EndElement(); // ResourceCompiler
  476. xml.EndElement(); // GlobalSettings
  477. xml.EndElement(); // Settings
  478. }
  479. void cmExtraCodeLiteGenerator::CreateNewProjectFile(
  480. const cmGeneratorTarget* gt, const std::string& filename)
  481. {
  482. const cmMakefile* mf = gt->Makefile;
  483. cmGeneratedFileStream fout(filename.c_str());
  484. if (!fout) {
  485. return;
  486. }
  487. cmXMLWriter xml(fout);
  488. ////////////////////////////////////
  489. xml.StartDocument("utf-8");
  490. xml.StartElement("CodeLite_Project");
  491. std::string targetName = gt->GetName();
  492. std::string visualname = targetName;
  493. switch (gt->GetType()) {
  494. case cmStateEnums::STATIC_LIBRARY:
  495. case cmStateEnums::SHARED_LIBRARY:
  496. case cmStateEnums::MODULE_LIBRARY:
  497. visualname = "lib" + targetName;
  498. default: // intended fallthrough
  499. break;
  500. }
  501. xml.Attribute("Name", visualname);
  502. xml.Attribute("InternalType", "");
  503. // Collect all used source files in the project
  504. // Sort them into two containers, one for C/C++ implementation files
  505. // which may have an acompanying header, one for all other files
  506. std::string projectType;
  507. std::map<std::string, cmSourceFile*> cFiles;
  508. std::set<std::string> otherFiles;
  509. projectType = CollectSourceFiles(mf, gt, cFiles, otherFiles);
  510. // Get the project path ( we need it later to convert files to
  511. // their relative path)
  512. std::string projectPath = cmSystemTools::GetFilenamePath(filename);
  513. CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
  514. projectType, targetName);
  515. xml.EndElement(); // CodeLite_Project
  516. }
  517. std::string cmExtraCodeLiteGenerator::GetCodeLiteCompilerName(
  518. const cmMakefile* mf) const
  519. {
  520. // figure out which language to use
  521. // for now care only for C and C++
  522. std::string compilerIdVar = "CMAKE_CXX_COMPILER_ID";
  523. if (!this->GlobalGenerator->GetLanguageEnabled("CXX")) {
  524. compilerIdVar = "CMAKE_C_COMPILER_ID";
  525. }
  526. std::string compilerId = mf->GetSafeDefinition(compilerIdVar);
  527. std::string compiler = "gnu g++"; // default to g++
  528. // Since we need the compiler for parsing purposes only
  529. // it does not matter if we use clang or clang++, same as
  530. // "gnu gcc" vs "gnu g++"
  531. if (compilerId == "MSVC") {
  532. compiler = "VC++";
  533. } else if (compilerId == "Clang") {
  534. compiler = "clang++";
  535. } else if (compilerId == "GNU") {
  536. compiler = "gnu g++";
  537. }
  538. return compiler;
  539. }
  540. std::string cmExtraCodeLiteGenerator::GetConfigurationName(
  541. const cmMakefile* mf) const
  542. {
  543. std::string confName = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
  544. // Trim the configuration name from whitespaces (left and right)
  545. confName.erase(0, confName.find_first_not_of(" \t\r\v\n"));
  546. confName.erase(confName.find_last_not_of(" \t\r\v\n") + 1);
  547. if (confName.empty()) {
  548. confName = "NoConfig";
  549. }
  550. return confName;
  551. }
  552. std::string cmExtraCodeLiteGenerator::GetBuildCommand(
  553. const cmMakefile* mf, const std::string& targetName) const
  554. {
  555. std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
  556. std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  557. std::string buildCommand = make; // Default
  558. std::ostringstream ss;
  559. if (generator == "NMake Makefiles" || generator == "Ninja") {
  560. ss << make;
  561. } else if (generator == "MinGW Makefiles" || generator == "Unix Makefiles") {
  562. ss << make << " -j " << this->CpuCount;
  563. }
  564. if (!targetName.empty()) {
  565. ss << " " << targetName;
  566. }
  567. buildCommand = ss.str();
  568. return buildCommand;
  569. }
  570. std::string cmExtraCodeLiteGenerator::GetCleanCommand(
  571. const cmMakefile* mf, const std::string& targetName) const
  572. {
  573. std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
  574. std::ostringstream ss;
  575. std::string buildcommand = GetBuildCommand(mf, "");
  576. if (!targetName.empty() && generator == "Ninja") {
  577. ss << buildcommand << " -t clean " << targetName;
  578. } else {
  579. ss << buildcommand << " clean";
  580. }
  581. return ss.str();
  582. }
  583. std::string cmExtraCodeLiteGenerator::GetRebuildCommand(
  584. const cmMakefile* mf, const std::string& targetName) const
  585. {
  586. return GetCleanCommand(mf, targetName) + " && " +
  587. GetBuildCommand(mf, targetName);
  588. }
  589. std::string cmExtraCodeLiteGenerator::GetSingleFileBuildCommand(
  590. const cmMakefile* mf) const
  591. {
  592. std::string buildCommand;
  593. std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  594. std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
  595. if (generator == "Unix Makefiles" || generator == "MinGW Makefiles") {
  596. std::ostringstream ss;
  597. ss << make << " -f$(ProjectPath)/Makefile $(CurrentFileName).cpp.o";
  598. buildCommand = ss.str();
  599. }
  600. return buildCommand;
  601. }