cmCPackIFWPackage.cxx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  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 "cmCPackIFWPackage.h"
  4. #include "cmCPackComponentGroup.h"
  5. #include "cmCPackIFWCommon.h"
  6. #include "cmCPackIFWGenerator.h"
  7. #include "cmCPackIFWInstaller.h"
  8. #include "cmCPackLog.h" // IWYU pragma: keep
  9. #include "cmGeneratedFileStream.h"
  10. #include "cmSystemTools.h"
  11. #include "cmTimestamp.h"
  12. #include "cmXMLWriter.h"
  13. #include <map>
  14. #include <sstream>
  15. #include <stddef.h>
  16. #include <utility>
  17. //---------------------------------------------------------- CompareStruct ---
  18. cmCPackIFWPackage::CompareStruct::CompareStruct()
  19. : Type(cmCPackIFWPackage::CompareNone)
  20. {
  21. }
  22. //------------------------------------------------------- DependenceStruct ---
  23. cmCPackIFWPackage::DependenceStruct::DependenceStruct()
  24. {
  25. }
  26. cmCPackIFWPackage::DependenceStruct::DependenceStruct(
  27. const std::string& dependence)
  28. {
  29. // Search compare section
  30. size_t pos = std::string::npos;
  31. if ((pos = dependence.find("<=")) != std::string::npos) {
  32. this->Compare.Type = cmCPackIFWPackage::CompareLessOrEqual;
  33. this->Compare.Value = dependence.substr(pos + 2);
  34. } else if ((pos = dependence.find(">=")) != std::string::npos) {
  35. this->Compare.Type = cmCPackIFWPackage::CompareGreaterOrEqual;
  36. this->Compare.Value = dependence.substr(pos + 2);
  37. } else if ((pos = dependence.find('<')) != std::string::npos) {
  38. this->Compare.Type = cmCPackIFWPackage::CompareLess;
  39. this->Compare.Value = dependence.substr(pos + 1);
  40. } else if ((pos = dependence.find('=')) != std::string::npos) {
  41. this->Compare.Type = cmCPackIFWPackage::CompareEqual;
  42. this->Compare.Value = dependence.substr(pos + 1);
  43. } else if ((pos = dependence.find('>')) != std::string::npos) {
  44. this->Compare.Type = cmCPackIFWPackage::CompareGreater;
  45. this->Compare.Value = dependence.substr(pos + 1);
  46. } else if ((pos = dependence.find('-')) != std::string::npos) {
  47. this->Compare.Type = cmCPackIFWPackage::CompareNone;
  48. this->Compare.Value = dependence.substr(pos + 1);
  49. }
  50. size_t dashPos = dependence.find('-');
  51. if (dashPos != std::string::npos) {
  52. pos = dashPos;
  53. }
  54. this->Name =
  55. pos == std::string::npos ? dependence : dependence.substr(0, pos);
  56. }
  57. std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
  58. {
  59. if (this->Compare.Type == cmCPackIFWPackage::CompareNone) {
  60. return this->Name;
  61. }
  62. std::string result = this->Name;
  63. if (this->Compare.Type != cmCPackIFWPackage::CompareNone ||
  64. !this->Compare.Value.empty()) {
  65. result += "-";
  66. }
  67. if (this->Compare.Type == cmCPackIFWPackage::CompareLessOrEqual) {
  68. result += "<=";
  69. } else if (this->Compare.Type == cmCPackIFWPackage::CompareGreaterOrEqual) {
  70. result += ">=";
  71. } else if (this->Compare.Type == cmCPackIFWPackage::CompareLess) {
  72. result += "<";
  73. } else if (this->Compare.Type == cmCPackIFWPackage::CompareEqual) {
  74. result += "=";
  75. } else if (this->Compare.Type == cmCPackIFWPackage::CompareGreater) {
  76. result += ">";
  77. }
  78. result += this->Compare.Value;
  79. return result;
  80. }
  81. //------------------------------------------------------ cmCPackIFWPackage ---
  82. cmCPackIFWPackage::cmCPackIFWPackage()
  83. : Installer(nullptr)
  84. {
  85. }
  86. std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent* component)
  87. {
  88. if (!component) {
  89. return "";
  90. }
  91. const char* option =
  92. this->GetOption("CPACK_IFW_COMPONENT_" +
  93. cmsys::SystemTools::UpperCase(component->Name) + "_NAME");
  94. return option ? option : component->Name;
  95. }
  96. void cmCPackIFWPackage::DefaultConfiguration()
  97. {
  98. this->DisplayName.clear();
  99. this->Description.clear();
  100. this->Version.clear();
  101. this->ReleaseDate.clear();
  102. this->Script.clear();
  103. this->Licenses.clear();
  104. this->UserInterfaces.clear();
  105. this->Translations.clear();
  106. this->SortingPriority.clear();
  107. this->UpdateText.clear();
  108. this->Default.clear();
  109. this->Essential.clear();
  110. this->Virtual.clear();
  111. this->ForcedInstallation.clear();
  112. this->RequiresAdminRights.clear();
  113. }
  114. // Default configuration (all in one package)
  115. int cmCPackIFWPackage::ConfigureFromOptions()
  116. {
  117. // Restore default configuration
  118. this->DefaultConfiguration();
  119. // Name
  120. this->Name = this->Generator->GetRootPackageName();
  121. // Display name
  122. if (const char* option = this->GetOption("CPACK_PACKAGE_NAME")) {
  123. this->DisplayName[""] = option;
  124. } else {
  125. this->DisplayName[""] = "Your package";
  126. }
  127. // Description
  128. if (const char* option =
  129. this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) {
  130. this->Description[""] = option;
  131. } else {
  132. this->Description[""] = "Your package description";
  133. }
  134. // Version
  135. if (const char* option = this->GetOption("CPACK_PACKAGE_VERSION")) {
  136. this->Version = option;
  137. } else {
  138. this->Version = "1.0.0";
  139. }
  140. this->ForcedInstallation = "true";
  141. return 1;
  142. }
  143. int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component)
  144. {
  145. if (!component) {
  146. return 0;
  147. }
  148. // Restore default configuration
  149. this->DefaultConfiguration();
  150. std::string prefix = "CPACK_IFW_COMPONENT_" +
  151. cmsys::SystemTools::UpperCase(component->Name) + "_";
  152. // Display name
  153. this->DisplayName[""] = component->DisplayName;
  154. // Description
  155. this->Description[""] = component->Description;
  156. // Version
  157. if (const char* optVERSION = this->GetOption(prefix + "VERSION")) {
  158. this->Version = optVERSION;
  159. } else if (const char* optPACKAGE_VERSION =
  160. this->GetOption("CPACK_PACKAGE_VERSION")) {
  161. this->Version = optPACKAGE_VERSION;
  162. } else {
  163. this->Version = "1.0.0";
  164. }
  165. // Script
  166. if (const char* option = this->GetOption(prefix + "SCRIPT")) {
  167. this->Script = option;
  168. }
  169. // User interfaces
  170. if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
  171. this->UserInterfaces.clear();
  172. cmSystemTools::ExpandListArgument(option, this->UserInterfaces);
  173. }
  174. // CMake dependencies
  175. if (!component->Dependencies.empty()) {
  176. for (cmCPackComponent* dep : component->Dependencies) {
  177. this->Dependencies.insert(this->Generator->ComponentPackages[dep]);
  178. }
  179. }
  180. // Licenses
  181. if (const char* option = this->GetOption(prefix + "LICENSES")) {
  182. this->Licenses.clear();
  183. cmSystemTools::ExpandListArgument(option, this->Licenses);
  184. if (this->Licenses.size() % 2 != 0) {
  185. cmCPackIFWLogger(
  186. WARNING,
  187. prefix << "LICENSES"
  188. << " should contain pairs of <display_name> and <file_path>."
  189. << std::endl);
  190. this->Licenses.clear();
  191. }
  192. }
  193. // Priority
  194. if (const char* option = this->GetOption(prefix + "PRIORITY")) {
  195. this->SortingPriority = option;
  196. cmCPackIFWLogger(
  197. WARNING,
  198. "The \"PRIORITY\" option is set "
  199. << "for component \"" << component->Name << "\", but there option is "
  200. << "deprecated. Please use \"SORTING_PRIORITY\" option instead."
  201. << std::endl);
  202. }
  203. // Default
  204. this->Default = component->IsDisabledByDefault ? "false" : "true";
  205. // Essential
  206. if (this->IsOn(prefix + "ESSENTIAL")) {
  207. this->Essential = "true";
  208. }
  209. // Virtual
  210. this->Virtual = component->IsHidden ? "true" : "";
  211. // ForcedInstallation
  212. this->ForcedInstallation = component->IsRequired ? "true" : "false";
  213. return this->ConfigureFromPrefix(prefix);
  214. }
  215. int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group)
  216. {
  217. if (!group) {
  218. return 0;
  219. }
  220. // Restore default configuration
  221. this->DefaultConfiguration();
  222. std::string prefix = "CPACK_IFW_COMPONENT_GROUP_" +
  223. cmsys::SystemTools::UpperCase(group->Name) + "_";
  224. this->DisplayName[""] = group->DisplayName;
  225. this->Description[""] = group->Description;
  226. // Version
  227. if (const char* optVERSION = this->GetOption(prefix + "VERSION")) {
  228. this->Version = optVERSION;
  229. } else if (const char* optPACKAGE_VERSION =
  230. this->GetOption("CPACK_PACKAGE_VERSION")) {
  231. this->Version = optPACKAGE_VERSION;
  232. } else {
  233. this->Version = "1.0.0";
  234. }
  235. // Script
  236. if (const char* option = this->GetOption(prefix + "SCRIPT")) {
  237. this->Script = option;
  238. }
  239. // User interfaces
  240. if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
  241. this->UserInterfaces.clear();
  242. cmSystemTools::ExpandListArgument(option, this->UserInterfaces);
  243. }
  244. // Licenses
  245. if (const char* option = this->GetOption(prefix + "LICENSES")) {
  246. this->Licenses.clear();
  247. cmSystemTools::ExpandListArgument(option, this->Licenses);
  248. if (this->Licenses.size() % 2 != 0) {
  249. cmCPackIFWLogger(
  250. WARNING,
  251. prefix << "LICENSES"
  252. << " should contain pairs of <display_name> and <file_path>."
  253. << std::endl);
  254. this->Licenses.clear();
  255. }
  256. }
  257. // Priority
  258. if (const char* option = this->GetOption(prefix + "PRIORITY")) {
  259. this->SortingPriority = option;
  260. cmCPackIFWLogger(
  261. WARNING,
  262. "The \"PRIORITY\" option is set "
  263. << "for component group \"" << group->Name
  264. << "\", but there option is "
  265. << "deprecated. Please use \"SORTING_PRIORITY\" option instead."
  266. << std::endl);
  267. }
  268. return this->ConfigureFromPrefix(prefix);
  269. }
  270. int cmCPackIFWPackage::ConfigureFromGroup(const std::string& groupName)
  271. {
  272. // Group configuration
  273. cmCPackComponentGroup group;
  274. std::string prefix =
  275. "CPACK_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(groupName) + "_";
  276. if (const char* option = this->GetOption(prefix + "DISPLAY_NAME")) {
  277. group.DisplayName = option;
  278. } else {
  279. group.DisplayName = group.Name;
  280. }
  281. if (const char* option = this->GetOption(prefix + "DESCRIPTION")) {
  282. group.Description = option;
  283. }
  284. group.IsBold = this->IsOn(prefix + "BOLD_TITLE");
  285. group.IsExpandedByDefault = this->IsOn(prefix + "EXPANDED");
  286. // Package configuration
  287. group.Name = groupName;
  288. if (Generator) {
  289. this->Name = this->Generator->GetGroupPackageName(&group);
  290. } else {
  291. this->Name = group.Name;
  292. }
  293. return this->ConfigureFromGroup(&group);
  294. }
  295. // Common options for components and groups
  296. int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
  297. {
  298. // Temporary variable for full option name
  299. std::string option;
  300. // Display name
  301. option = prefix + "DISPLAY_NAME";
  302. if (this->IsSetToEmpty(option)) {
  303. this->DisplayName.clear();
  304. } else if (const char* value = this->GetOption(option)) {
  305. this->ExpandListArgument(value, this->DisplayName);
  306. }
  307. // Description
  308. option = prefix + "DESCRIPTION";
  309. if (this->IsSetToEmpty(option)) {
  310. this->Description.clear();
  311. } else if (const char* value = this->GetOption(option)) {
  312. this->ExpandListArgument(value, this->Description);
  313. }
  314. // Release date
  315. option = prefix + "RELEASE_DATE";
  316. if (this->IsSetToEmpty(option)) {
  317. this->ReleaseDate.clear();
  318. } else if (const char* value = this->GetOption(option)) {
  319. this->ReleaseDate = value;
  320. }
  321. // Sorting priority
  322. option = prefix + "SORTING_PRIORITY";
  323. if (this->IsSetToEmpty(option)) {
  324. this->SortingPriority.clear();
  325. } else if (const char* value = this->GetOption(option)) {
  326. this->SortingPriority = value;
  327. }
  328. // Update text
  329. option = prefix + "UPDATE_TEXT";
  330. if (this->IsSetToEmpty(option)) {
  331. this->UpdateText.clear();
  332. } else if (const char* value = this->GetOption(option)) {
  333. this->UpdateText = value;
  334. }
  335. // Translations
  336. option = prefix + "TRANSLATIONS";
  337. if (this->IsSetToEmpty(option)) {
  338. this->Translations.clear();
  339. } else if (const char* value = this->GetOption(option)) {
  340. this->Translations.clear();
  341. cmSystemTools::ExpandListArgument(value, this->Translations);
  342. }
  343. // QtIFW dependencies
  344. std::vector<std::string> deps;
  345. option = prefix + "DEPENDS";
  346. if (const char* value = this->GetOption(option)) {
  347. cmSystemTools::ExpandListArgument(value, deps);
  348. }
  349. option = prefix + "DEPENDENCIES";
  350. if (const char* value = this->GetOption(option)) {
  351. cmSystemTools::ExpandListArgument(value, deps);
  352. }
  353. for (std::string const& d : deps) {
  354. DependenceStruct dep(d);
  355. if (this->Generator->Packages.count(dep.Name)) {
  356. cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
  357. dep.Name = depPkg.Name;
  358. }
  359. bool hasDep = this->Generator->DependentPackages.count(dep.Name) > 0;
  360. DependenceStruct& depRef = this->Generator->DependentPackages[dep.Name];
  361. if (!hasDep) {
  362. depRef = dep;
  363. }
  364. this->AlienDependencies.insert(&depRef);
  365. }
  366. // Automatic dependency on
  367. option = prefix + "AUTO_DEPEND_ON";
  368. if (this->IsSetToEmpty(option)) {
  369. this->AlienAutoDependOn.clear();
  370. } else if (const char* value = this->GetOption(option)) {
  371. std::vector<std::string> depsOn;
  372. cmSystemTools::ExpandListArgument(value, depsOn);
  373. for (std::string const& d : depsOn) {
  374. DependenceStruct dep(d);
  375. if (this->Generator->Packages.count(dep.Name)) {
  376. cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
  377. dep.Name = depPkg.Name;
  378. }
  379. bool hasDep = this->Generator->DependentPackages.count(dep.Name) > 0;
  380. DependenceStruct& depRef = this->Generator->DependentPackages[dep.Name];
  381. if (!hasDep) {
  382. depRef = dep;
  383. }
  384. this->AlienAutoDependOn.insert(&depRef);
  385. }
  386. }
  387. // Visibility
  388. option = prefix + "VIRTUAL";
  389. if (this->IsSetToEmpty(option)) {
  390. this->Virtual.clear();
  391. } else if (this->IsOn(option)) {
  392. this->Virtual = "true";
  393. }
  394. // Default selection
  395. option = prefix + "DEFAULT";
  396. if (this->IsSetToEmpty(option)) {
  397. this->Default.clear();
  398. } else if (const char* value = this->GetOption(option)) {
  399. std::string lowerValue = cmsys::SystemTools::LowerCase(value);
  400. if (lowerValue == "true") {
  401. this->Default = "true";
  402. } else if (lowerValue == "false") {
  403. this->Default = "false";
  404. } else if (lowerValue == "script") {
  405. this->Default = "script";
  406. } else {
  407. this->Default = value;
  408. }
  409. }
  410. // Forsed installation
  411. option = prefix + "FORCED_INSTALLATION";
  412. if (this->IsSetToEmpty(option)) {
  413. this->ForcedInstallation.clear();
  414. } else if (this->IsOn(option)) {
  415. this->ForcedInstallation = "true";
  416. } else if (this->IsSetToOff(option)) {
  417. this->ForcedInstallation = "false";
  418. }
  419. // Replaces
  420. option = prefix + "REPLACES";
  421. if (this->IsSetToEmpty(option)) {
  422. this->Replaces.clear();
  423. } else if (const char* value = this->GetOption(option)) {
  424. this->Replaces.clear();
  425. cmSystemTools::ExpandListArgument(value, this->Replaces);
  426. }
  427. // Requires admin rights
  428. option = prefix + "REQUIRES_ADMIN_RIGHTS";
  429. if (this->IsSetToEmpty(option)) {
  430. this->RequiresAdminRights.clear();
  431. } else if (this->IsOn(option)) {
  432. this->RequiresAdminRights = "true";
  433. } else if (this->IsSetToOff(option)) {
  434. this->RequiresAdminRights = "false";
  435. }
  436. // Checkable
  437. option = prefix + "CHECKABLE";
  438. if (this->IsSetToEmpty(option)) {
  439. this->Checkable.clear();
  440. } else if (this->IsOn(option)) {
  441. this->Checkable = "true";
  442. } else if (this->IsSetToOff(option)) {
  443. this->Checkable = "false";
  444. }
  445. return 1;
  446. }
  447. void cmCPackIFWPackage::GeneratePackageFile()
  448. {
  449. // Lazy directory initialization
  450. if (this->Directory.empty()) {
  451. if (this->Installer) {
  452. this->Directory = this->Installer->Directory + "/packages/" + this->Name;
  453. } else if (this->Generator) {
  454. this->Directory = this->Generator->toplevel + "/packages/" + this->Name;
  455. }
  456. }
  457. // Output stream
  458. cmGeneratedFileStream fout((this->Directory + "/meta/package.xml").data());
  459. cmXMLWriter xout(fout);
  460. xout.StartDocument();
  461. WriteGeneratedByToStrim(xout);
  462. xout.StartElement("Package");
  463. // DisplayName (with translations)
  464. for (auto const& dn : this->DisplayName) {
  465. xout.StartElement("DisplayName");
  466. if (!dn.first.empty()) {
  467. xout.Attribute("xml:lang", dn.first);
  468. }
  469. xout.Content(dn.second);
  470. xout.EndElement();
  471. }
  472. // Description (with translations)
  473. for (auto const& d : this->Description) {
  474. xout.StartElement("Description");
  475. if (!d.first.empty()) {
  476. xout.Attribute("xml:lang", d.first);
  477. }
  478. xout.Content(d.second);
  479. xout.EndElement();
  480. }
  481. // Update text
  482. if (!this->UpdateText.empty()) {
  483. xout.Element("UpdateText", this->UpdateText);
  484. }
  485. xout.Element("Name", this->Name);
  486. xout.Element("Version", this->Version);
  487. if (!this->ReleaseDate.empty()) {
  488. xout.Element("ReleaseDate", this->ReleaseDate);
  489. } else {
  490. xout.Element("ReleaseDate", cmTimestamp().CurrentTime("%Y-%m-%d", true));
  491. }
  492. // Script (copy to meta dir)
  493. if (!this->Script.empty()) {
  494. std::string name = cmSystemTools::GetFilenameName(this->Script);
  495. std::string path = this->Directory + "/meta/" + name;
  496. cmsys::SystemTools::CopyFileIfDifferent(this->Script, path);
  497. xout.Element("Script", name);
  498. }
  499. // User Interfaces (copy to meta dir)
  500. std::vector<std::string> userInterfaces = UserInterfaces;
  501. for (std::string& userInterface : userInterfaces) {
  502. std::string name = cmSystemTools::GetFilenameName(userInterface);
  503. std::string path = this->Directory + "/meta/" + name;
  504. cmsys::SystemTools::CopyFileIfDifferent(userInterface, path);
  505. userInterface = name;
  506. }
  507. if (!userInterfaces.empty()) {
  508. xout.StartElement("UserInterfaces");
  509. for (std::string const& userInterface : userInterfaces) {
  510. xout.Element("UserInterface", userInterface);
  511. }
  512. xout.EndElement();
  513. }
  514. // Translations (copy to meta dir)
  515. std::vector<std::string> translations = Translations;
  516. for (std::string& translation : translations) {
  517. std::string name = cmSystemTools::GetFilenameName(translation);
  518. std::string path = this->Directory + "/meta/" + name;
  519. cmsys::SystemTools::CopyFileIfDifferent(translation, path);
  520. translation = name;
  521. }
  522. if (!translations.empty()) {
  523. xout.StartElement("Translations");
  524. for (std::string const& translation : translations) {
  525. xout.Element("Translation", translation);
  526. }
  527. xout.EndElement();
  528. }
  529. // Dependencies
  530. std::set<DependenceStruct> compDepSet;
  531. for (DependenceStruct* ad : this->AlienDependencies) {
  532. compDepSet.insert(*ad);
  533. }
  534. for (cmCPackIFWPackage* d : this->Dependencies) {
  535. compDepSet.insert(DependenceStruct(d->Name));
  536. }
  537. // Write dependencies
  538. if (!compDepSet.empty()) {
  539. std::ostringstream dependencies;
  540. std::set<DependenceStruct>::iterator it = compDepSet.begin();
  541. dependencies << it->NameWithCompare();
  542. ++it;
  543. while (it != compDepSet.end()) {
  544. dependencies << "," << it->NameWithCompare();
  545. ++it;
  546. }
  547. xout.Element("Dependencies", dependencies.str());
  548. }
  549. // Automatic dependency on
  550. std::set<DependenceStruct> compAutoDepSet;
  551. for (DependenceStruct* aad : this->AlienAutoDependOn) {
  552. compAutoDepSet.insert(*aad);
  553. }
  554. // Write automatic dependency on
  555. if (!compAutoDepSet.empty()) {
  556. std::ostringstream dependencies;
  557. std::set<DependenceStruct>::iterator it = compAutoDepSet.begin();
  558. dependencies << it->NameWithCompare();
  559. ++it;
  560. while (it != compAutoDepSet.end()) {
  561. dependencies << "," << it->NameWithCompare();
  562. ++it;
  563. }
  564. xout.Element("AutoDependOn", dependencies.str());
  565. }
  566. // Licenses (copy to meta dir)
  567. std::vector<std::string> licenses = this->Licenses;
  568. for (size_t i = 1; i < licenses.size(); i += 2) {
  569. std::string name = cmSystemTools::GetFilenameName(licenses[i]);
  570. std::string path = this->Directory + "/meta/" + name;
  571. cmsys::SystemTools::CopyFileIfDifferent(licenses[i], path);
  572. licenses[i] = name;
  573. }
  574. if (!licenses.empty()) {
  575. xout.StartElement("Licenses");
  576. for (size_t i = 0; i < licenses.size(); i += 2) {
  577. xout.StartElement("License");
  578. xout.Attribute("name", licenses[i]);
  579. xout.Attribute("file", licenses[i + 1]);
  580. xout.EndElement();
  581. }
  582. xout.EndElement();
  583. }
  584. if (!this->ForcedInstallation.empty()) {
  585. xout.Element("ForcedInstallation", this->ForcedInstallation);
  586. }
  587. // Replaces
  588. if (!this->Replaces.empty()) {
  589. std::ostringstream replaces;
  590. std::vector<std::string>::iterator it = this->Replaces.begin();
  591. replaces << *it;
  592. ++it;
  593. while (it != this->Replaces.end()) {
  594. replaces << "," << *it;
  595. ++it;
  596. }
  597. xout.Element("Replaces", replaces.str());
  598. }
  599. if (!this->RequiresAdminRights.empty()) {
  600. xout.Element("RequiresAdminRights", this->RequiresAdminRights);
  601. }
  602. if (!this->Virtual.empty()) {
  603. xout.Element("Virtual", this->Virtual);
  604. } else if (!this->Default.empty()) {
  605. xout.Element("Default", this->Default);
  606. }
  607. // Essential
  608. if (!this->Essential.empty()) {
  609. xout.Element("Essential", this->Essential);
  610. }
  611. // Priority
  612. if (!this->SortingPriority.empty()) {
  613. xout.Element("SortingPriority", this->SortingPriority);
  614. }
  615. // Checkable
  616. if (!this->Checkable.empty()) {
  617. xout.Element("Checkable", this->Checkable);
  618. }
  619. xout.EndElement();
  620. xout.EndDocument();
  621. }