cmCPackRPMGenerator.cxx 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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)
  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. // Tell CPackRPM.cmake the path where the component is.
  74. std::string component_path = "/";
  75. component_path += packageName;
  76. this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH",
  77. component_path.c_str());
  78. if (!this->ReadListFile("CPackRPM.cmake"))
  79. {
  80. cmCPackLogger(cmCPackLog::LOG_ERROR,
  81. "Error while execution CPackRPM.cmake" << std::endl);
  82. retval = 0;
  83. }
  84. // add the generated package to package file names list
  85. packageFileNames.push_back(packageFileName);
  86. return retval;
  87. }
  88. //----------------------------------------------------------------------
  89. int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
  90. {
  91. int retval = 1;
  92. /* Reset package file name list it will be populated during the
  93. * component packaging run*/
  94. packageFileNames.clear();
  95. std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
  96. // The default behavior is to have one package by component group
  97. // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
  98. if (!ignoreGroup)
  99. {
  100. std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
  101. for (compGIt=this->ComponentGroups.begin();
  102. compGIt!=this->ComponentGroups.end(); ++compGIt)
  103. {
  104. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
  105. << compGIt->first
  106. << std::endl);
  107. retval &= PackageOnePack(initialTopLevel,compGIt->first);
  108. }
  109. // Handle Orphan components (components not belonging to any groups)
  110. std::map<std::string, cmCPackComponent>::iterator compIt;
  111. for (compIt=this->Components.begin();
  112. compIt!=this->Components.end(); ++compIt )
  113. {
  114. // Does the component belong to a group?
  115. if (compIt->second.Group==NULL)
  116. {
  117. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  118. "Component <"
  119. << compIt->second.Name
  120. << "> does not belong to any group, package it separately."
  121. << std::endl);
  122. retval &= PackageOnePack(initialTopLevel,compIt->first);
  123. }
  124. }
  125. }
  126. // CPACK_COMPONENTS_IGNORE_GROUPS is set
  127. // We build 1 package per component
  128. else
  129. {
  130. std::map<std::string, cmCPackComponent>::iterator compIt;
  131. for (compIt=this->Components.begin();
  132. compIt!=this->Components.end(); ++compIt )
  133. {
  134. retval &= PackageOnePack(initialTopLevel,compIt->first);
  135. }
  136. }
  137. return retval;
  138. }
  139. //----------------------------------------------------------------------
  140. int cmCPackRPMGenerator::PackageComponentsAllInOne()
  141. {
  142. int retval = 1;
  143. std::string compInstDirName;
  144. /* Reset package file name list it will be populated during the
  145. * component packaging run*/
  146. packageFileNames.clear();
  147. std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
  148. compInstDirName = "ALL_COMPONENTS_IN_ONE";
  149. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  150. "Packaging all groups in one package..."
  151. "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
  152. << std::endl);
  153. // The ALL GROUPS in ONE package case
  154. std::string localToplevel(initialTopLevel);
  155. std::string packageFileName(
  156. cmSystemTools::GetParentDirectory(toplevel)
  157. );
  158. std::string outputFileName(
  159. std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
  160. + this->GetOutputExtension()
  161. );
  162. // all GROUP in one vs all COMPONENT in one
  163. localToplevel += "/"+compInstDirName;
  164. /* replace the TEMP DIRECTORY with the component one */
  165. this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
  166. packageFileName += "/"+ outputFileName;
  167. /* replace proposed CPACK_OUTPUT_FILE_NAME */
  168. this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
  169. /* replace the TEMPORARY package file name */
  170. this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
  171. packageFileName.c_str());
  172. // Tell CPackRPM.cmake the path where the component is.
  173. std::string component_path = "/";
  174. component_path += compInstDirName;
  175. this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH",
  176. component_path.c_str());
  177. if (!this->ReadListFile("CPackRPM.cmake"))
  178. {
  179. cmCPackLogger(cmCPackLog::LOG_ERROR,
  180. "Error while execution CPackRPM.cmake" << std::endl);
  181. retval = 0;
  182. }
  183. // add the generated package to package file names list
  184. packageFileNames.push_back(packageFileName);
  185. return retval;
  186. }
  187. //----------------------------------------------------------------------
  188. int cmCPackRPMGenerator::PackageFiles()
  189. {
  190. int retval = 1;
  191. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
  192. << toplevel << std::endl);
  193. /* Are we in the component packaging case */
  194. if (WantsComponentInstallation()) {
  195. // CASE 1 : COMPONENT ALL-IN-ONE package
  196. // If ALL COMPONENTS in ONE package has been requested
  197. // then the package file is unique and should be open here.
  198. if (componentPackageMethod == ONE_PACKAGE)
  199. {
  200. return PackageComponentsAllInOne();
  201. }
  202. // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
  203. // There will be 1 package for each component group
  204. // however one may require to ignore component group and
  205. // in this case you'll get 1 package for each component.
  206. else
  207. {
  208. return PackageComponents(componentPackageMethod ==
  209. ONE_PACKAGE_PER_COMPONENT);
  210. }
  211. }
  212. // CASE 3 : NON COMPONENT package.
  213. else
  214. {
  215. if (!this->ReadListFile("CPackRPM.cmake"))
  216. {
  217. cmCPackLogger(cmCPackLog::LOG_ERROR,
  218. "Error while execution CPackRPM.cmake" << std::endl);
  219. retval = 0;
  220. }
  221. }
  222. if (!this->IsSet("RPMBUILD_EXECUTABLE"))
  223. {
  224. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find rpmbuild" << std::endl);
  225. retval = 0;
  226. }
  227. return retval;
  228. }
  229. bool cmCPackRPMGenerator::SupportsComponentInstallation() const
  230. {
  231. if (IsOn("CPACK_RPM_COMPONENT_INSTALL"))
  232. {
  233. return true;
  234. }
  235. else
  236. {
  237. return false;
  238. }
  239. }
  240. std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
  241. const std::string& componentName)
  242. {
  243. if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
  244. return componentName;
  245. }
  246. if (componentPackageMethod == ONE_PACKAGE) {
  247. return std::string("ALL_COMPONENTS_IN_ONE");
  248. }
  249. // We have to find the name of the COMPONENT GROUP
  250. // the current COMPONENT belongs to.
  251. std::string groupVar = "CPACK_COMPONENT_" +
  252. cmSystemTools::UpperCase(componentName) + "_GROUP";
  253. if (NULL != GetOption(groupVar))
  254. {
  255. return std::string(GetOption(groupVar));
  256. }
  257. else
  258. {
  259. return componentName;
  260. }
  261. }