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