cmCPackIFWGenerator.cxx 16 KB

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