cmCPackRPMGenerator.cxx 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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 "cmCPackRPMGenerator.h"
  11. #include "cmCPackLog.h"
  12. #include "cmSystemTools.h"
  13. //----------------------------------------------------------------------
  14. cmCPackRPMGenerator::cmCPackRPMGenerator()
  15. {
  16. }
  17. //----------------------------------------------------------------------
  18. cmCPackRPMGenerator::~cmCPackRPMGenerator()
  19. {
  20. }
  21. //----------------------------------------------------------------------
  22. int cmCPackRPMGenerator::InitializeInternal()
  23. {
  24. this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
  25. if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR")))
  26. {
  27. this->SetOption("CPACK_SET_DESTDIR", "I_ON");
  28. }
  29. /* Replace space in CPACK_PACKAGE_NAME in order to avoid
  30. * rpmbuild scream on unwanted space in filename issue
  31. * Moreover RPM file do not usually embed space in filename
  32. */
  33. if (this->GetOption("CPACK_PACKAGE_NAME")) {
  34. std::string packageName=this->GetOption("CPACK_PACKAGE_NAME");
  35. cmSystemTools::ReplaceString(packageName," ","-");
  36. this->SetOption("CPACK_PACKAGE_NAME",packageName.c_str());
  37. }
  38. /* same for CPACK_PACKAGE_FILE_NAME */
  39. if (this->GetOption("CPACK_PACKAGE_FILE_NAME")) {
  40. std::string packageName=this->GetOption("CPACK_PACKAGE_FILE_NAME");
  41. cmSystemTools::ReplaceString(packageName," ","-");
  42. this->SetOption("CPACK_PACKAGE_FILE_NAME",packageName.c_str());
  43. }
  44. return this->Superclass::InitializeInternal();
  45. }
  46. //----------------------------------------------------------------------
  47. int cmCPackRPMGenerator::PackageOnePack(std::string initialToplevel,
  48. std::string packageName)
  49. {
  50. int retval = 1;
  51. // Begin the archive for this pack
  52. std::string localToplevel(initialToplevel);
  53. std::string packageFileName(
  54. cmSystemTools::GetParentDirectory(toplevel.c_str())
  55. );
  56. std::string outputFileName(
  57. GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
  58. packageName,
  59. true)
  60. + this->GetOutputExtension()
  61. );
  62. localToplevel += "/"+ packageName;
  63. /* replace the TEMP DIRECTORY with the component one */
  64. this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
  65. packageFileName += "/"+ outputFileName;
  66. /* replace proposed CPACK_OUTPUT_FILE_NAME */
  67. this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
  68. /* replace the TEMPORARY package file name */
  69. this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
  70. packageFileName.c_str());
  71. // Tell CPackRPM.cmake the name of the component NAME.
  72. this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",packageName.c_str());
  73. if (!this->ReadListFile("CPackRPM.cmake"))
  74. {
  75. cmCPackLogger(cmCPackLog::LOG_ERROR,
  76. "Error while execution CPackRPM.cmake" << std::endl);
  77. retval = 0;
  78. }
  79. // add the generated package to package file names list
  80. packageFileNames.push_back(packageFileName);
  81. return retval;
  82. }
  83. //----------------------------------------------------------------------
  84. int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
  85. {
  86. int retval = 1;
  87. /* Reset package file name list it will be populated during the
  88. * component packaging run*/
  89. packageFileNames.clear();
  90. std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
  91. // The default behavior is to have one package by component group
  92. // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
  93. if (!ignoreGroup)
  94. {
  95. std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
  96. for (compGIt=this->ComponentGroups.begin();
  97. compGIt!=this->ComponentGroups.end(); ++compGIt)
  98. {
  99. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
  100. << compGIt->first
  101. << std::endl);
  102. retval &= PackageOnePack(initialTopLevel,compGIt->first);
  103. }
  104. // Handle Orphan components (components not belonging to any groups)
  105. std::map<std::string, cmCPackComponent>::iterator compIt;
  106. for (compIt=this->Components.begin();
  107. compIt!=this->Components.end(); ++compIt )
  108. {
  109. // Does the component belong to a group?
  110. if (compIt->second.Group==NULL)
  111. {
  112. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  113. "Component <"
  114. << compIt->second.Name
  115. << "> does not belong to any group, package it separately."
  116. << std::endl);
  117. retval &= PackageOnePack(initialTopLevel,compIt->first);
  118. }
  119. }
  120. }
  121. // CPACK_COMPONENTS_IGNORE_GROUPS is set
  122. // We build 1 package per component
  123. else
  124. {
  125. std::map<std::string, cmCPackComponent>::iterator compIt;
  126. for (compIt=this->Components.begin();
  127. compIt!=this->Components.end(); ++compIt )
  128. {
  129. retval &= PackageOnePack(initialTopLevel,compIt->first);
  130. }
  131. }
  132. return retval;
  133. }
  134. //----------------------------------------------------------------------
  135. int cmCPackRPMGenerator::PackageComponentsAllInOne()
  136. {
  137. int retval = 1;
  138. std::string compInstDirName;
  139. /* Reset package file name list it will be populated during the
  140. * component packaging run*/
  141. packageFileNames.clear();
  142. std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
  143. compInstDirName = "ALL_COMPONENTS_IN_ONE";
  144. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  145. "Packaging all groups in one package..."
  146. "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
  147. << std::endl);
  148. // The ALL GROUPS in ONE package case
  149. std::string localToplevel(initialTopLevel);
  150. std::string packageFileName(
  151. cmSystemTools::GetParentDirectory(toplevel.c_str())
  152. );
  153. std::string outputFileName(
  154. std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
  155. + this->GetOutputExtension()
  156. );
  157. // all GROUP in one vs all COMPONENT in one
  158. localToplevel += "/"+compInstDirName;
  159. /* replace the TEMP DIRECTORY with the component one */
  160. this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
  161. packageFileName += "/"+ outputFileName;
  162. /* replace proposed CPACK_OUTPUT_FILE_NAME */
  163. this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
  164. /* replace the TEMPORARY package file name */
  165. this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
  166. packageFileName.c_str());
  167. // Tell CPackRPM.cmake the name of the component GROUP.
  168. this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compInstDirName.c_str());
  169. if (!this->ReadListFile("CPackRPM.cmake"))
  170. {
  171. cmCPackLogger(cmCPackLog::LOG_ERROR,
  172. "Error while execution CPackRPM.cmake" << std::endl);
  173. retval = 0;
  174. }
  175. // add the generated package to package file names list
  176. packageFileNames.push_back(packageFileName);
  177. return retval;
  178. }
  179. //----------------------------------------------------------------------
  180. int cmCPackRPMGenerator::PackageFiles()
  181. {
  182. int retval = 1;
  183. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
  184. << toplevel << std::endl);
  185. /* Are we in the component packaging case */
  186. if (SupportsComponentInstallation()) {
  187. // CASE 1 : COMPONENT ALL-IN-ONE package
  188. // If ALL COMPONENTS in ONE package has been requested
  189. // then the package file is unique and should be open here.
  190. if (componentPackageMethod == ONE_PACKAGE)
  191. {
  192. return PackageComponentsAllInOne();
  193. }
  194. // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
  195. // There will be 1 package for each component group
  196. // however one may require to ignore component group and
  197. // in this case you'll get 1 package for each component.
  198. else
  199. {
  200. return PackageComponents(componentPackageMethod ==
  201. ONE_PACKAGE_PER_COMPONENT);
  202. }
  203. }
  204. // CASE 3 : NON COMPONENT package.
  205. else
  206. {
  207. if (!this->ReadListFile("CPackRPM.cmake"))
  208. {
  209. cmCPackLogger(cmCPackLog::LOG_ERROR,
  210. "Error while execution CPackRPM.cmake" << std::endl);
  211. retval = 0;
  212. }
  213. }
  214. if (!this->IsSet("RPMBUILD_EXECUTABLE"))
  215. {
  216. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find rpmbuild" << std::endl);
  217. retval = 0;
  218. }
  219. return retval;
  220. }
  221. bool cmCPackRPMGenerator::SupportsComponentInstallation() const
  222. {
  223. if (IsOn("CPACK_RPM_COMPONENT_INSTALL"))
  224. {
  225. return true;
  226. }
  227. else
  228. {
  229. return false;
  230. }
  231. }
  232. std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
  233. const std::string& componentName)
  234. {
  235. if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
  236. return componentName;
  237. }
  238. if (componentPackageMethod == ONE_PACKAGE) {
  239. return std::string("ALL_COMPONENTS_IN_ONE");
  240. }
  241. // We have to find the name of the COMPONENT GROUP
  242. // the current COMPONENT belongs to.
  243. std::string groupVar = "CPACK_COMPONENT_" +
  244. cmSystemTools::UpperCase(componentName) + "_GROUP";
  245. if (NULL != GetOption(groupVar.c_str()))
  246. {
  247. return std::string(GetOption(groupVar.c_str()));
  248. }
  249. else
  250. {
  251. return componentName;
  252. }
  253. }