cmCPackIFWGenerator.cxx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmCPackIFWGenerator.h"
  11. #include "cmCPackIFWInstaller.h"
  12. #include "cmCPackIFWPackage.h"
  13. #include <CPack/cmCPackComponentGroup.h>
  14. #include <CPack/cmCPackLog.h>
  15. #include <cmsys/Directory.hxx>
  16. #include <cmsys/Glob.hxx>
  17. #include <cmsys/RegularExpression.hxx>
  18. #include <cmsys/SystemTools.hxx>
  19. #include <cmGeneratedFileStream.h>
  20. #include <cmGlobalGenerator.h>
  21. #include <cmMakefile.h>
  22. #include <cmSystemTools.h>
  23. #include <cmTimestamp.h>
  24. #include <cmVersionConfig.h>
  25. #include <cmXMLWriter.h>
  26. //----------------------------------------------------------------------------
  27. cmCPackIFWGenerator::cmCPackIFWGenerator()
  28. {
  29. }
  30. //----------------------------------------------------------------------------
  31. cmCPackIFWGenerator::~cmCPackIFWGenerator()
  32. {
  33. }
  34. //----------------------------------------------------------------------------
  35. bool cmCPackIFWGenerator::IsVersionLess(const char *version)
  36. {
  37. return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
  38. FrameworkVersion.data(), version);
  39. }
  40. //----------------------------------------------------------------------------
  41. bool cmCPackIFWGenerator::IsVersionGreater(const char *version)
  42. {
  43. return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
  44. FrameworkVersion.data(), version);
  45. }
  46. //----------------------------------------------------------------------------
  47. bool cmCPackIFWGenerator::IsVersionEqual(const char *version)
  48. {
  49. return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
  50. FrameworkVersion.data(), version);
  51. }
  52. //----------------------------------------------------------------------------
  53. int cmCPackIFWGenerator::PackageFiles()
  54. {
  55. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Configuration" << std::endl);
  56. // Installer configuragion
  57. Installer.GenerateInstallerFile();
  58. // Packages configuration
  59. Installer.GeneratePackageFiles();
  60. std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  61. std::string ifwTmpFile = ifwTLD;
  62. ifwTmpFile += "/IFWOutput.log";
  63. // Run repogen
  64. if (!Installer.Repositories.empty())
  65. {
  66. std::string ifwCmd = RepoGen;
  67. if(IsVersionLess("2.0.0"))
  68. {
  69. ifwCmd += " -c " + this->toplevel + "/config/config.xml";
  70. }
  71. ifwCmd += " -p " + this->toplevel + "/packages";
  72. if(!PkgsDirsVector.empty())
  73. {
  74. for(std::vector<std::string>::iterator it = PkgsDirsVector.begin();
  75. it != PkgsDirsVector.end(); ++it)
  76. {
  77. ifwCmd += " -p " + *it;
  78. }
  79. }
  80. if (!OnlineOnly && !DownloadedPackages.empty())
  81. {
  82. ifwCmd += " -i ";
  83. std::set<cmCPackIFWPackage*>::iterator it
  84. = DownloadedPackages.begin();
  85. ifwCmd += (*it)->Name;
  86. ++it;
  87. while(it != DownloadedPackages.end())
  88. {
  89. ifwCmd += "," + (*it)->Name;
  90. ++it;
  91. }
  92. }
  93. ifwCmd += " " + this->toplevel + "/repository";
  94. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd
  95. << std::endl);
  96. std::string output;
  97. int retVal = 1;
  98. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  99. "- Generate repository" << std::endl);
  100. bool res = cmSystemTools::RunSingleCommand(
  101. ifwCmd.c_str(), &output, &output,
  102. &retVal, 0, this->GeneratorVerbose, 0);
  103. if ( !res || retVal )
  104. {
  105. cmGeneratedFileStream ofs(ifwTmpFile.c_str());
  106. ofs << "# Run command: " << ifwCmd << std::endl
  107. << "# Output:" << std::endl
  108. << output << std::endl;
  109. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: "
  110. << ifwCmd << std::endl
  111. << "Please check " << ifwTmpFile << " for errors"
  112. << std::endl);
  113. return 0;
  114. }
  115. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- repository: " << this->toplevel
  116. << "/repository generated" << std::endl);
  117. }
  118. // Run binary creator
  119. {
  120. std::string ifwCmd = BinCreator;
  121. ifwCmd += " -c " + this->toplevel + "/config/config.xml";
  122. ifwCmd += " -p " + this->toplevel + "/packages";
  123. if(!PkgsDirsVector.empty())
  124. {
  125. for(std::vector<std::string>::iterator it = PkgsDirsVector.begin();
  126. it != PkgsDirsVector.end(); ++it)
  127. {
  128. ifwCmd += " -p " + *it;
  129. }
  130. }
  131. if (OnlineOnly)
  132. {
  133. ifwCmd += " --online-only";
  134. }
  135. else if (!DownloadedPackages.empty() && !Installer.Repositories.empty())
  136. {
  137. ifwCmd += " -e ";
  138. std::set<cmCPackIFWPackage*>::iterator it
  139. = DownloadedPackages.begin();
  140. ifwCmd += (*it)->Name;
  141. ++it;
  142. while(it != DownloadedPackages.end())
  143. {
  144. ifwCmd += "," + (*it)->Name;
  145. ++it;
  146. }
  147. }
  148. else if (!DependentPackages.empty())
  149. {
  150. ifwCmd += " -i ";
  151. // Binary
  152. std::set<cmCPackIFWPackage*>::iterator bit = BinaryPackages.begin();
  153. while(bit != BinaryPackages.end())
  154. {
  155. ifwCmd += (*bit)->Name + ",";
  156. ++bit;
  157. }
  158. // Depend
  159. DependenceMap::iterator it = DependentPackages.begin();
  160. ifwCmd += it->second.Name;
  161. ++it;
  162. while(it != DependentPackages.end())
  163. {
  164. ifwCmd += "," + it->second.Name;
  165. ++it;
  166. }
  167. }
  168. // TODO: set correct name for multipackages
  169. if (!this->packageFileNames.empty())
  170. {
  171. ifwCmd += " " + packageFileNames[0];
  172. }
  173. else
  174. {
  175. ifwCmd += " installer";
  176. }
  177. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd
  178. << std::endl);
  179. std::string output;
  180. int retVal = 1;
  181. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate package" << std::endl);
  182. bool res = cmSystemTools::RunSingleCommand(
  183. ifwCmd.c_str(), &output, &output,
  184. &retVal, 0, this->GeneratorVerbose, 0);
  185. if ( !res || retVal )
  186. {
  187. cmGeneratedFileStream ofs(ifwTmpFile.c_str());
  188. ofs << "# Run command: " << ifwCmd << std::endl
  189. << "# Output:" << std::endl
  190. << output << std::endl;
  191. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: "
  192. << ifwCmd << std::endl
  193. << "Please check " << ifwTmpFile << " for errors"
  194. << std::endl);
  195. return 0;
  196. }
  197. }
  198. return 1;
  199. }
  200. //----------------------------------------------------------------------------
  201. const char *cmCPackIFWGenerator::GetPackagingInstallPrefix()
  202. {
  203. const char *defPrefix = cmCPackGenerator::GetPackagingInstallPrefix();
  204. std::string tmpPref = defPrefix ? defPrefix : "";
  205. if(this->Components.empty())
  206. {
  207. tmpPref += "packages/" + GetRootPackageName() + "/data";
  208. }
  209. this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str());
  210. return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX");
  211. }
  212. //----------------------------------------------------------------------------
  213. const char *cmCPackIFWGenerator::GetOutputExtension()
  214. {
  215. return ExecutableSuffix.c_str();
  216. }
  217. //----------------------------------------------------------------------------
  218. int cmCPackIFWGenerator::InitializeInternal()
  219. {
  220. // Search Qt Installer Framework tools
  221. const std::string BinCreatorOpt = "CPACK_IFW_BINARYCREATOR_EXECUTABLE";
  222. const std::string RepoGenOpt = "CPACK_IFW_REPOGEN_EXECUTABLE";
  223. const std::string FrameworkVersionOpt = "CPACK_IFW_FRAMEWORK_VERSION";
  224. if(!this->IsSet(BinCreatorOpt) ||
  225. !this->IsSet(RepoGenOpt) ||
  226. !this->IsSet(FrameworkVersionOpt))
  227. {
  228. this->ReadListFile("CPackIFW.cmake");
  229. }
  230. // Look 'binarycreator' executable (needs)
  231. const char *BinCreatorStr = this->GetOption(BinCreatorOpt);
  232. if(!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr))
  233. {
  234. BinCreator = "";
  235. }
  236. else
  237. {
  238. BinCreator = BinCreatorStr;
  239. }
  240. if (BinCreator.empty())
  241. {
  242. cmCPackLogger(cmCPackLog::LOG_ERROR,
  243. "Cannot find QtIFW compiler \"binarycreator\": "
  244. "likely it is not installed, or not in your PATH"
  245. << std::endl);
  246. return 0;
  247. }
  248. // Look 'repogen' executable (optional)
  249. const char *RepoGenStr = this->GetOption(RepoGenOpt);
  250. if(!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr))
  251. {
  252. RepoGen = "";
  253. }
  254. else
  255. {
  256. RepoGen = RepoGenStr;
  257. }
  258. // Framework version
  259. if(const char* FrameworkVersionSrt =
  260. this->GetOption(FrameworkVersionOpt))
  261. {
  262. FrameworkVersion = FrameworkVersionSrt;
  263. }
  264. else
  265. {
  266. FrameworkVersion = "1.9.9";
  267. }
  268. // Variables that Change Behavior
  269. // Resolve duplicate names
  270. ResolveDuplicateNames = this->IsOn("CPACK_IFW_RESOLVE_DUPLICATE_NAMES");
  271. // Additional packages dirs
  272. PkgsDirsVector.clear();
  273. if(const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES"))
  274. {
  275. cmSystemTools::ExpandListArgument(dirs,
  276. PkgsDirsVector);
  277. }
  278. // Installer
  279. Installer.Generator = this;
  280. Installer.ConfigureFromOptions();
  281. if (const char* ifwDownloadAll =
  282. this->GetOption("CPACK_IFW_DOWNLOAD_ALL"))
  283. {
  284. OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
  285. }
  286. else if (const char* cpackDownloadAll =
  287. this->GetOption("CPACK_DOWNLOAD_ALL"))
  288. {
  289. OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll);
  290. }
  291. else
  292. {
  293. OnlineOnly = false;
  294. }
  295. if (!Installer.Repositories.empty() && RepoGen.empty()) {
  296. cmCPackLogger(cmCPackLog::LOG_ERROR,
  297. "Cannot find QtIFW repository generator \"repogen\": "
  298. "likely it is not installed, or not in your PATH"
  299. << std::endl);
  300. return 0;
  301. }
  302. // Executable suffix
  303. if(const char *optExeSuffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX"))
  304. {
  305. ExecutableSuffix = optExeSuffix;
  306. if(ExecutableSuffix.empty())
  307. {
  308. std::string sysName(this->GetOption("CMAKE_SYSTEM_NAME"));
  309. if(sysName == "Linux")
  310. {
  311. ExecutableSuffix = ".run";
  312. }
  313. }
  314. }
  315. else
  316. {
  317. ExecutableSuffix = cmCPackGenerator::GetOutputExtension();
  318. }
  319. return this->Superclass::InitializeInternal();
  320. }
  321. //----------------------------------------------------------------------------
  322. std::string
  323. cmCPackIFWGenerator::GetComponentInstallDirNameSuffix(
  324. const std::string& componentName)
  325. {
  326. const std::string prefix = "packages/";
  327. const std::string suffix = "/data";
  328. if (componentPackageMethod == ONE_PACKAGE) {
  329. return std::string(prefix + GetRootPackageName() + suffix);
  330. }
  331. return prefix
  332. + GetComponentPackageName(&Components[componentName])
  333. + suffix;
  334. }
  335. //----------------------------------------------------------------------------
  336. cmCPackComponent*
  337. cmCPackIFWGenerator::GetComponent(const std::string &projectName,
  338. const std::string &componentName)
  339. {
  340. ComponentsMap::iterator cit = Components.find(componentName);
  341. if ( cit != Components.end() ) return &(cit->second);
  342. cmCPackComponent* component
  343. = cmCPackGenerator::GetComponent(projectName, componentName);
  344. if(!component) return component;
  345. std::string name = GetComponentPackageName(component);
  346. PackagesMap::iterator pit = Packages.find(name);
  347. if(pit != Packages.end()) return component;
  348. cmCPackIFWPackage *package = &Packages[name];
  349. package->Name = name;
  350. package->Generator = this;
  351. if(package->ConfigureFromComponent(component))
  352. {
  353. package->Installer = &Installer;
  354. Installer.Packages.insert(
  355. std::pair<std::string, cmCPackIFWPackage*>(
  356. name, package));
  357. ComponentPackages.insert(
  358. std::pair<cmCPackComponent*, cmCPackIFWPackage*>(
  359. component, package));
  360. if(component->IsDownloaded)
  361. {
  362. DownloadedPackages.insert(package);
  363. }
  364. else
  365. {
  366. BinaryPackages.insert(package);
  367. }
  368. }
  369. else
  370. {
  371. Packages.erase(name);
  372. cmCPackLogger(cmCPackLog::LOG_ERROR,
  373. "Cannot configure package \"" << name <<
  374. "\" for component \"" << component->Name << "\""
  375. << std::endl);
  376. }
  377. return component;
  378. }
  379. //----------------------------------------------------------------------------
  380. cmCPackComponentGroup*
  381. cmCPackIFWGenerator::GetComponentGroup(const std::string &projectName,
  382. const std::string &groupName)
  383. {
  384. cmCPackComponentGroup* group
  385. = cmCPackGenerator::GetComponentGroup(projectName, groupName);
  386. if(!group) return group;
  387. std::string name = GetGroupPackageName(group);
  388. PackagesMap::iterator pit = Packages.find(name);
  389. if(pit != Packages.end()) return group;
  390. cmCPackIFWPackage *package = &Packages[name];
  391. package->Name = name;
  392. package->Generator = this;
  393. if(package->ConfigureFromGroup(group))
  394. {
  395. package->Installer = &Installer;
  396. Installer.Packages.insert(
  397. std::pair<std::string, cmCPackIFWPackage*>(
  398. name, package));
  399. GroupPackages.insert(
  400. std::pair<cmCPackComponentGroup*, cmCPackIFWPackage*>(
  401. group, package));
  402. BinaryPackages.insert(package);
  403. }
  404. else
  405. {
  406. Packages.erase(name);
  407. cmCPackLogger(cmCPackLog::LOG_ERROR,
  408. "Cannot configure package \"" << name <<
  409. "\" for component group \"" << group->Name << "\""
  410. << std::endl);
  411. }
  412. return group;
  413. }
  414. //----------------------------------------------------------------------------
  415. enum cmCPackGenerator::CPackSetDestdirSupport
  416. cmCPackIFWGenerator::SupportsSetDestdir() const
  417. {
  418. return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED;
  419. }
  420. //----------------------------------------------------------------------------
  421. bool cmCPackIFWGenerator::SupportsAbsoluteDestination() const
  422. {
  423. return false;
  424. }
  425. //----------------------------------------------------------------------------
  426. bool cmCPackIFWGenerator::SupportsComponentInstallation() const
  427. {
  428. return true;
  429. }
  430. //----------------------------------------------------------------------------
  431. bool cmCPackIFWGenerator::IsOnePackage() const
  432. {
  433. return componentPackageMethod == ONE_PACKAGE;
  434. }
  435. //----------------------------------------------------------------------------
  436. std::string cmCPackIFWGenerator::GetRootPackageName()
  437. {
  438. // Default value
  439. std::string name = "root";
  440. if (const char* optIFW_PACKAGE_GROUP =
  441. this->GetOption("CPACK_IFW_PACKAGE_GROUP"))
  442. {
  443. // Configure from root group
  444. cmCPackIFWPackage package;
  445. package.Generator = this;
  446. package.ConfigureFromGroup(optIFW_PACKAGE_GROUP);
  447. name = package.Name;
  448. }
  449. else if (const char* optIFW_PACKAGE_NAME =
  450. this->GetOption("CPACK_IFW_PACKAGE_NAME"))
  451. {
  452. // Configure from root package name
  453. name = optIFW_PACKAGE_NAME;
  454. }
  455. else if (const char* optPACKAGE_NAME =
  456. this->GetOption("CPACK_PACKAGE_NAME"))
  457. {
  458. // Configure from package name
  459. name = optPACKAGE_NAME;
  460. }
  461. return name;
  462. }
  463. //----------------------------------------------------------------------------
  464. std::string
  465. cmCPackIFWGenerator::GetGroupPackageName(cmCPackComponentGroup *group) const
  466. {
  467. std::string name;
  468. if (!group) return name;
  469. if (cmCPackIFWPackage* package = GetGroupPackage(group))
  470. {
  471. return package->Name;
  472. }
  473. const char* option = GetOption(
  474. "CPACK_IFW_COMPONENT_GROUP_"
  475. + cmsys::SystemTools::UpperCase(group->Name)
  476. + "_NAME");
  477. name = option ? option : group->Name;
  478. if(group->ParentGroup)
  479. {
  480. cmCPackIFWPackage* package = GetGroupPackage(group->ParentGroup);
  481. bool dot = !ResolveDuplicateNames;
  482. if(dot && name.substr(0, package->Name.size()) == package->Name)
  483. {
  484. dot = false;
  485. }
  486. if(dot)
  487. {
  488. name = package->Name + "." + name;
  489. }
  490. }
  491. return name;
  492. }
  493. //----------------------------------------------------------------------------
  494. std::string cmCPackIFWGenerator::GetComponentPackageName(
  495. cmCPackComponent *component) const
  496. {
  497. std::string name;
  498. if (!component) return name;
  499. if (cmCPackIFWPackage* package = GetComponentPackage(component))
  500. {
  501. return package->Name;
  502. }
  503. std::string prefix = "CPACK_IFW_COMPONENT_"
  504. + cmsys::SystemTools::UpperCase(component->Name)
  505. + "_";
  506. const char* option = GetOption(prefix + "NAME");
  507. name = option ? option : component->Name;
  508. if(component->Group)
  509. {
  510. cmCPackIFWPackage* package = GetGroupPackage(component->Group);
  511. if((componentPackageMethod == ONE_PACKAGE_PER_GROUP)
  512. || IsOn(prefix + "COMMON"))
  513. {
  514. return package->Name;
  515. }
  516. bool dot = !ResolveDuplicateNames;
  517. if(dot && name.substr(0, package->Name.size()) == package->Name)
  518. {
  519. dot = false;
  520. }
  521. if(dot)
  522. {
  523. name = package->Name + "." + name;
  524. }
  525. }
  526. return name;
  527. }
  528. //----------------------------------------------------------------------------
  529. cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage(
  530. cmCPackComponentGroup *group) const
  531. {
  532. std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit
  533. = GroupPackages.find(group);
  534. return pit != GroupPackages.end() ? pit->second : 0;
  535. }
  536. //----------------------------------------------------------------------------
  537. cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage(
  538. cmCPackComponent *component) const
  539. {
  540. std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit
  541. = ComponentPackages.find(component);
  542. return pit != ComponentPackages.end() ? pit->second : 0;
  543. }
  544. //----------------------------------------------------------------------------
  545. void cmCPackIFWGenerator::WriteGeneratedByToStrim(cmXMLWriter &xout)
  546. {
  547. std::stringstream comment;
  548. comment << "Generated by CPack " << CMake_VERSION << " IFW generator "
  549. << "for QtIFW ";
  550. if(IsVersionLess("2.0"))
  551. {
  552. comment << "less 2.0";
  553. }
  554. else
  555. {
  556. comment << FrameworkVersion;
  557. }
  558. comment << " tools at " << cmTimestamp().CurrentTime("", true);
  559. xout.Comment(comment.str().c_str());
  560. }