cmCPackRPMGenerator.cxx 10 KB

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