cmCPackGenerator.cxx 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683
  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 "cmCPackGenerator.h"
  11. #include "cmMakefile.h"
  12. #include "cmCPackLog.h"
  13. #include "cmake.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmLocalGenerator.h"
  16. #include "cmGeneratedFileStream.h"
  17. #include "cmCPackComponentGroup.h"
  18. #include "cmXMLSafe.h"
  19. #include <cmsys/SystemTools.hxx>
  20. #include <cmsys/Glob.hxx>
  21. #include <algorithm>
  22. #if defined(__HAIKU__)
  23. #include <StorageKit.h>
  24. #endif
  25. //----------------------------------------------------------------------
  26. cmCPackGenerator::cmCPackGenerator()
  27. {
  28. this->GeneratorVerbose = cmSystemTools::OUTPUT_NONE;
  29. this->MakefileMap = 0;
  30. this->Logger = 0;
  31. this->componentPackageMethod = ONE_PACKAGE_PER_GROUP;
  32. }
  33. //----------------------------------------------------------------------
  34. cmCPackGenerator::~cmCPackGenerator()
  35. {
  36. this->MakefileMap = 0;
  37. }
  38. //----------------------------------------------------------------------
  39. void cmCPackGeneratorProgress(const char *msg, float prog, void* ptr)
  40. {
  41. cmCPackGenerator* self = static_cast<cmCPackGenerator*>(ptr);
  42. self->DisplayVerboseOutput(msg, prog);
  43. }
  44. //----------------------------------------------------------------------
  45. void cmCPackGenerator::DisplayVerboseOutput(const char* msg,
  46. float progress)
  47. {
  48. (void)progress;
  49. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl);
  50. }
  51. //----------------------------------------------------------------------
  52. int cmCPackGenerator::PrepareNames()
  53. {
  54. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  55. "Create temp directory." << std::endl);
  56. // checks CPACK_SET_DESTDIR support
  57. if (IsOn("CPACK_SET_DESTDIR"))
  58. {
  59. if (SETDESTDIR_UNSUPPORTED==SupportsSetDestdir())
  60. {
  61. cmCPackLogger(cmCPackLog::LOG_ERROR,
  62. "CPACK_SET_DESTDIR is set to ON but the '"
  63. << Name << "' generator does NOT support it."
  64. << std::endl);
  65. return 0;
  66. }
  67. else if (SETDESTDIR_SHOULD_NOT_BE_USED==SupportsSetDestdir())
  68. {
  69. cmCPackLogger(cmCPackLog::LOG_WARNING,
  70. "CPACK_SET_DESTDIR is set to ON but it is "
  71. << "usually a bad idea to do that with '"
  72. << Name << "' generator. Use at your own risk."
  73. << std::endl);
  74. }
  75. }
  76. std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY");
  77. tempDirectory += "/_CPack_Packages/";
  78. const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG");
  79. if ( toplevelTag )
  80. {
  81. tempDirectory += toplevelTag;
  82. tempDirectory += "/";
  83. }
  84. tempDirectory += this->GetOption("CPACK_GENERATOR");
  85. std::string topDirectory = tempDirectory;
  86. const char* pfname = this->GetOption("CPACK_PACKAGE_FILE_NAME");
  87. if(!pfname)
  88. {
  89. cmCPackLogger(cmCPackLog::LOG_ERROR,
  90. "CPACK_PACKAGE_FILE_NAME not specified" << std::endl);
  91. return 0;
  92. }
  93. std::string outName = pfname;
  94. tempDirectory += "/" + outName;
  95. if(!this->GetOutputExtension())
  96. {
  97. cmCPackLogger(cmCPackLog::LOG_ERROR,
  98. "No output extension specified" << std::endl);
  99. return 0;
  100. }
  101. outName += this->GetOutputExtension();
  102. const char* pdir = this->GetOption("CPACK_PACKAGE_DIRECTORY");
  103. if(!pdir)
  104. {
  105. cmCPackLogger(cmCPackLog::LOG_ERROR,
  106. "CPACK_PACKAGE_DIRECTORY not specified" << std::endl);
  107. return 0;
  108. }
  109. std::string destFile = pdir;
  110. this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PREFIX", destFile.c_str());
  111. destFile += "/" + outName;
  112. std::string outFile = topDirectory + "/" + outName;
  113. this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory.c_str());
  114. this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory.c_str());
  115. this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName.c_str());
  116. this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile.c_str());
  117. this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
  118. outFile.c_str());
  119. this->SetOptionIfNotSet("CPACK_INSTALL_DIRECTORY", this->GetInstallPath());
  120. this->SetOptionIfNotSet("CPACK_NATIVE_INSTALL_DIRECTORY",
  121. cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath()).c_str());
  122. this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY",
  123. tempDirectory.c_str());
  124. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  125. "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl);
  126. const char* descFileName
  127. = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
  128. if ( descFileName )
  129. {
  130. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  131. "Look for: " << descFileName << std::endl);
  132. if ( !cmSystemTools::FileExists(descFileName) )
  133. {
  134. cmCPackLogger(cmCPackLog::LOG_ERROR,
  135. "Cannot find description file name: ["
  136. << descFileName << "]" << std::endl);
  137. return 0;
  138. }
  139. std::ifstream ifs(descFileName);
  140. if ( !ifs )
  141. {
  142. cmCPackLogger(cmCPackLog::LOG_ERROR,
  143. "Cannot open description file name: " << descFileName << std::endl);
  144. return 0;
  145. }
  146. cmOStringStream ostr;
  147. std::string line;
  148. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  149. "Read description file: " << descFileName << std::endl);
  150. while ( ifs && cmSystemTools::GetLineFromStream(ifs, line) )
  151. {
  152. ostr << cmXMLSafe(line) << std::endl;
  153. }
  154. this->SetOptionIfNotSet("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str());
  155. }
  156. if ( !this->GetOption("CPACK_PACKAGE_DESCRIPTION") )
  157. {
  158. cmCPackLogger(cmCPackLog::LOG_ERROR,
  159. "Project description not specified. Please specify "
  160. "CPACK_PACKAGE_DESCRIPTION or CPACK_PACKAGE_DESCRIPTION_FILE."
  161. << std::endl);
  162. return 0;
  163. }
  164. this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1");
  165. return 1;
  166. }
  167. //----------------------------------------------------------------------
  168. int cmCPackGenerator::InstallProject()
  169. {
  170. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Install projects" << std::endl);
  171. this->CleanTemporaryDirectory();
  172. std::string bareTempInstallDirectory
  173. = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
  174. std::string tempInstallDirectoryStr = bareTempInstallDirectory;
  175. bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR"))
  176. | cmSystemTools::IsInternallyOn(
  177. this->GetOption("CPACK_SET_DESTDIR"));
  178. if (!setDestDir)
  179. {
  180. tempInstallDirectoryStr += this->GetPackagingInstallPrefix();
  181. }
  182. const char* tempInstallDirectory = tempInstallDirectoryStr.c_str();
  183. int res = 1;
  184. if ( !cmsys::SystemTools::MakeDirectory(bareTempInstallDirectory.c_str()))
  185. {
  186. cmCPackLogger(cmCPackLog::LOG_ERROR,
  187. "Problem creating temporary directory: "
  188. << (tempInstallDirectory ? tempInstallDirectory : "(NULL)")
  189. << std::endl);
  190. return 0;
  191. }
  192. if ( setDestDir )
  193. {
  194. std::string destDir = "DESTDIR=";
  195. destDir += tempInstallDirectory;
  196. cmSystemTools::PutEnv(destDir.c_str());
  197. }
  198. else
  199. {
  200. // Make sure there is no destdir
  201. cmSystemTools::PutEnv("DESTDIR=");
  202. }
  203. // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them
  204. // as listed
  205. if ( !this->InstallProjectViaInstallCommands(
  206. setDestDir, tempInstallDirectory) )
  207. {
  208. return 0;
  209. }
  210. // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
  211. // as listed
  212. if ( !this->InstallProjectViaInstallScript(
  213. setDestDir, tempInstallDirectory) )
  214. {
  215. return 0;
  216. }
  217. // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES
  218. // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY
  219. // This is used in Source packaging
  220. if ( !this->InstallProjectViaInstalledDirectories(
  221. setDestDir, tempInstallDirectory) )
  222. {
  223. return 0;
  224. }
  225. // If the project is a CMAKE project then run pre-install
  226. // and then read the cmake_install script to run it
  227. if ( !this->InstallProjectViaInstallCMakeProjects(
  228. setDestDir, bareTempInstallDirectory.c_str()) )
  229. {
  230. return 0;
  231. }
  232. if ( setDestDir )
  233. {
  234. cmSystemTools::PutEnv("DESTDIR=");
  235. }
  236. return res;
  237. }
  238. //----------------------------------------------------------------------
  239. int cmCPackGenerator::InstallProjectViaInstallCommands(
  240. bool setDestDir, const char* tempInstallDirectory)
  241. {
  242. (void) setDestDir;
  243. const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
  244. if ( installCommands && *installCommands )
  245. {
  246. std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX=";
  247. tempInstallDirectoryEnv += tempInstallDirectory;
  248. cmSystemTools::PutEnv(tempInstallDirectoryEnv.c_str());
  249. std::vector<std::string> installCommandsVector;
  250. cmSystemTools::ExpandListArgument(installCommands,installCommandsVector);
  251. std::vector<std::string>::iterator it;
  252. for ( it = installCommandsVector.begin();
  253. it != installCommandsVector.end();
  254. ++it )
  255. {
  256. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << it->c_str()
  257. << std::endl);
  258. std::string output;
  259. int retVal = 1;
  260. bool resB = cmSystemTools::RunSingleCommand(it->c_str(), &output,
  261. &retVal, 0, this->GeneratorVerbose, 0);
  262. if ( !resB || retVal )
  263. {
  264. std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  265. tmpFile += "/InstallOutput.log";
  266. cmGeneratedFileStream ofs(tmpFile.c_str());
  267. ofs << "# Run command: " << it->c_str() << std::endl
  268. << "# Output:" << std::endl
  269. << output.c_str() << std::endl;
  270. cmCPackLogger(cmCPackLog::LOG_ERROR,
  271. "Problem running install command: " << it->c_str() << std::endl
  272. << "Please check " << tmpFile.c_str() << " for errors"
  273. << std::endl);
  274. return 0;
  275. }
  276. }
  277. }
  278. return 1;
  279. }
  280. //----------------------------------------------------------------------
  281. int cmCPackGenerator::InstallProjectViaInstalledDirectories(
  282. bool setDestDir, const char* tempInstallDirectory)
  283. {
  284. (void)setDestDir;
  285. (void)tempInstallDirectory;
  286. std::vector<cmsys::RegularExpression> ignoreFilesRegex;
  287. const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
  288. if ( cpackIgnoreFiles )
  289. {
  290. std::vector<std::string> ignoreFilesRegexString;
  291. cmSystemTools::ExpandListArgument(cpackIgnoreFiles,
  292. ignoreFilesRegexString);
  293. std::vector<std::string>::iterator it;
  294. for ( it = ignoreFilesRegexString.begin();
  295. it != ignoreFilesRegexString.end();
  296. ++it )
  297. {
  298. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  299. "Create ignore files regex for: " << it->c_str() << std::endl);
  300. ignoreFilesRegex.push_back(it->c_str());
  301. }
  302. }
  303. const char* installDirectories
  304. = this->GetOption("CPACK_INSTALLED_DIRECTORIES");
  305. if ( installDirectories && *installDirectories )
  306. {
  307. std::vector<std::string> installDirectoriesVector;
  308. cmSystemTools::ExpandListArgument(installDirectories,
  309. installDirectoriesVector);
  310. if ( installDirectoriesVector.size() % 2 != 0 )
  311. {
  312. cmCPackLogger(cmCPackLog::LOG_ERROR,
  313. "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
  314. "<subdirectory>. The <subdirectory> can be '.' to be installed in "
  315. "the toplevel directory of installation." << std::endl);
  316. return 0;
  317. }
  318. std::vector<std::string>::iterator it;
  319. const char* tempDir = tempInstallDirectory;
  320. for ( it = installDirectoriesVector.begin();
  321. it != installDirectoriesVector.end();
  322. ++it )
  323. {
  324. std::list<std::pair<std::string,std::string> > symlinkedFiles;
  325. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
  326. cmsys::Glob gl;
  327. std::string top = it->c_str();
  328. it ++;
  329. std::string subdir = it->c_str();
  330. std::string findExpr = top;
  331. findExpr += "/*";
  332. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  333. "- Install directory: " << top << std::endl);
  334. gl.RecurseOn();
  335. if ( !gl.FindFiles(findExpr) )
  336. {
  337. cmCPackLogger(cmCPackLog::LOG_ERROR,
  338. "Cannot find any files in the installed directory" << std::endl);
  339. return 0;
  340. }
  341. files = gl.GetFiles();
  342. std::vector<std::string>::iterator gfit;
  343. std::vector<cmsys::RegularExpression>::iterator regIt;
  344. for ( gfit = files.begin(); gfit != files.end(); ++ gfit )
  345. {
  346. bool skip = false;
  347. std::string &inFile = *gfit;
  348. for ( regIt= ignoreFilesRegex.begin();
  349. regIt!= ignoreFilesRegex.end();
  350. ++ regIt)
  351. {
  352. if ( regIt->find(inFile.c_str()) )
  353. {
  354. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Ignore file: "
  355. << inFile.c_str() << std::endl);
  356. skip = true;
  357. }
  358. }
  359. if ( skip )
  360. {
  361. continue;
  362. }
  363. std::string filePath = tempDir;
  364. filePath += "/" + subdir + "/"
  365. + cmSystemTools::RelativePath(top.c_str(), gfit->c_str());
  366. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: "
  367. << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
  368. /* If the file is a symlink we will have to re-create it */
  369. if ( cmSystemTools::FileIsSymlink(inFile.c_str()))
  370. {
  371. std::string targetFile;
  372. std::string inFileRelative =
  373. cmSystemTools::RelativePath(top.c_str(),inFile.c_str());
  374. cmSystemTools::ReadSymlink(inFile.c_str(),targetFile);
  375. symlinkedFiles.push_back(std::pair<std::string,
  376. std::string>(targetFile,inFileRelative));
  377. }
  378. /* If it is not a symlink then do a plain copy */
  379. else if (!(
  380. cmSystemTools::CopyFileIfDifferent(inFile.c_str(),filePath.c_str())
  381. &&
  382. cmSystemTools::CopyFileTime(inFile.c_str(),filePath.c_str())
  383. ) )
  384. {
  385. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying file: "
  386. << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
  387. return 0;
  388. }
  389. }
  390. /* rebuild symlinks in the installed tree */
  391. if (symlinkedFiles.size()>0)
  392. {
  393. std::list< std::pair<std::string,std::string> >::iterator symlinkedIt;
  394. std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
  395. std::string goToDir = tempDir;
  396. goToDir += "/"+subdir;
  397. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  398. "Change dir to: " << goToDir <<std::endl);
  399. cmSystemTools::ChangeDirectory(goToDir.c_str());
  400. for (symlinkedIt=symlinkedFiles.begin();
  401. symlinkedIt != symlinkedFiles.end();
  402. ++symlinkedIt)
  403. {
  404. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: "
  405. << symlinkedIt->second << "--> "
  406. << symlinkedIt->first << std::endl);
  407. if (!cmSystemTools::CreateSymlink((symlinkedIt->first).c_str(),
  408. (symlinkedIt->second).c_str()))
  409. {
  410. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create symlink: "
  411. << symlinkedIt->second << "--> "
  412. << symlinkedIt->first << std::endl);
  413. return 0;
  414. }
  415. }
  416. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Going back to: "
  417. << curDir <<std::endl);
  418. cmSystemTools::ChangeDirectory(curDir.c_str());
  419. }
  420. }
  421. }
  422. return 1;
  423. }
  424. //----------------------------------------------------------------------
  425. int cmCPackGenerator::InstallProjectViaInstallScript(
  426. bool setDestDir, const char* tempInstallDirectory)
  427. {
  428. const char* cmakeScripts
  429. = this->GetOption("CPACK_INSTALL_SCRIPT");
  430. if ( cmakeScripts && *cmakeScripts )
  431. {
  432. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  433. "- Install scripts: " << cmakeScripts << std::endl);
  434. std::vector<std::string> cmakeScriptsVector;
  435. cmSystemTools::ExpandListArgument(cmakeScripts,
  436. cmakeScriptsVector);
  437. std::vector<std::string>::iterator it;
  438. for ( it = cmakeScriptsVector.begin();
  439. it != cmakeScriptsVector.end();
  440. ++it )
  441. {
  442. std::string installScript = it->c_str();
  443. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  444. "- Install script: " << installScript << std::endl);
  445. if ( setDestDir )
  446. {
  447. // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
  448. // underneath the tempInstallDirectory. The value of the project's
  449. // CMAKE_INSTALL_PREFIX is sent in here as the value of the
  450. // CPACK_INSTALL_PREFIX variable.
  451. std::string dir;
  452. if (this->GetOption("CPACK_INSTALL_PREFIX"))
  453. {
  454. dir += this->GetOption("CPACK_INSTALL_PREFIX");
  455. }
  456. this->SetOption("CMAKE_INSTALL_PREFIX", dir.c_str());
  457. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  458. "- Using DESTDIR + CPACK_INSTALL_PREFIX... (this->SetOption)"
  459. << std::endl);
  460. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  461. "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" << std::endl);
  462. }
  463. else
  464. {
  465. this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
  466. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  467. "- Using non-DESTDIR install... (this->SetOption)" << std::endl);
  468. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  469. "- Setting CMAKE_INSTALL_PREFIX to '" << tempInstallDirectory
  470. << "'" << std::endl);
  471. }
  472. this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR",
  473. tempInstallDirectory);
  474. this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR",
  475. tempInstallDirectory);
  476. int res = this->MakefileMap->ReadListFile(0, installScript.c_str());
  477. if ( cmSystemTools::GetErrorOccuredFlag() || !res )
  478. {
  479. return 0;
  480. }
  481. }
  482. }
  483. return 1;
  484. }
  485. //----------------------------------------------------------------------
  486. int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
  487. bool setDestDir, const char* baseTempInstallDirectory)
  488. {
  489. const char* cmakeProjects
  490. = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
  491. const char* cmakeGenerator
  492. = this->GetOption("CPACK_CMAKE_GENERATOR");
  493. std::string absoluteDestFiles;
  494. if ( cmakeProjects && *cmakeProjects )
  495. {
  496. if ( !cmakeGenerator )
  497. {
  498. cmCPackLogger(cmCPackLog::LOG_ERROR,
  499. "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
  500. "CPACK_CMAKE_GENERATOR is not. CPACK_CMAKE_GENERATOR "
  501. "is required to install the project."
  502. << std::endl);
  503. return 0;
  504. }
  505. std::vector<std::string> cmakeProjectsVector;
  506. cmSystemTools::ExpandListArgument(cmakeProjects,
  507. cmakeProjectsVector);
  508. std::vector<std::string>::iterator it;
  509. for ( it = cmakeProjectsVector.begin();
  510. it != cmakeProjectsVector.end();
  511. ++it )
  512. {
  513. if ( it+1 == cmakeProjectsVector.end() ||
  514. it+2 == cmakeProjectsVector.end() ||
  515. it+3 == cmakeProjectsVector.end() )
  516. {
  517. cmCPackLogger(cmCPackLog::LOG_ERROR,
  518. "Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. "
  519. "CPACK_INSTALL_CMAKE_PROJECTS should hold quadruplet of install "
  520. "directory, install project name, install component, and install "
  521. "subdirectory."
  522. << std::endl);
  523. return 0;
  524. }
  525. std::string installDirectory = it->c_str();
  526. ++it;
  527. std::string installProjectName = it->c_str();
  528. ++it;
  529. std::string installComponent = it->c_str();
  530. ++it;
  531. std::string installSubDirectory = it->c_str();
  532. std::string installFile = installDirectory + "/cmake_install.cmake";
  533. std::vector<std::string> componentsVector;
  534. bool componentInstall = false;
  535. /*
  536. * We do a component install iff
  537. * - the CPack generator support component
  538. * - the user did not request Monolithic install
  539. * (this works at CPack time too)
  540. */
  541. if (this->SupportsComponentInstallation() &
  542. !(this->IsSet("CPACK_MONOLITHIC_INSTALL")))
  543. {
  544. // Determine the installation types for this project (if provided).
  545. std::string installTypesVar = "CPACK_"
  546. + cmSystemTools::UpperCase(installComponent) + "_INSTALL_TYPES";
  547. const char *installTypes = this->GetOption(installTypesVar.c_str());
  548. if (installTypes && *installTypes)
  549. {
  550. std::vector<std::string> installTypesVector;
  551. cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
  552. std::vector<std::string>::iterator installTypeIt;
  553. for (installTypeIt = installTypesVector.begin();
  554. installTypeIt != installTypesVector.end();
  555. ++installTypeIt)
  556. {
  557. this->GetInstallationType(installProjectName.c_str(),
  558. installTypeIt->c_str());
  559. }
  560. }
  561. // Determine the set of components that will be used in this project
  562. std::string componentsVar
  563. = "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent);
  564. const char *components = this->GetOption(componentsVar.c_str());
  565. if (components && *components)
  566. {
  567. cmSystemTools::ExpandListArgument(components, componentsVector);
  568. std::vector<std::string>::iterator compIt;
  569. for (compIt = componentsVector.begin();
  570. compIt != componentsVector.end();
  571. ++compIt)
  572. {
  573. GetComponent(installProjectName.c_str(), compIt->c_str());
  574. }
  575. componentInstall = true;
  576. }
  577. }
  578. if (componentsVector.empty())
  579. {
  580. componentsVector.push_back(installComponent);
  581. }
  582. const char* buildConfig = this->GetOption("CPACK_BUILD_CONFIG");
  583. cmGlobalGenerator* globalGenerator
  584. = this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
  585. cmakeGenerator);
  586. // set the global flag for unix style paths on cmSystemTools as
  587. // soon as the generator is set. This allows gmake to be used
  588. // on windows.
  589. cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths());
  590. // Does this generator require pre-install?
  591. if ( globalGenerator->GetPreinstallTargetName() )
  592. {
  593. globalGenerator->FindMakeProgram(this->MakefileMap);
  594. const char* cmakeMakeProgram
  595. = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM");
  596. std::string buildCommand
  597. = globalGenerator->GenerateBuildCommand(cmakeMakeProgram,
  598. installProjectName.c_str(), 0, 0,
  599. globalGenerator->GetPreinstallTargetName(),
  600. buildConfig, false, false);
  601. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  602. "- Install command: " << buildCommand << std::endl);
  603. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  604. "- Run preinstall target for: " << installProjectName << std::endl);
  605. std::string output;
  606. int retVal = 1;
  607. bool resB =
  608. cmSystemTools::RunSingleCommand(buildCommand.c_str(),
  609. &output,
  610. &retVal,
  611. installDirectory.c_str(),
  612. this->GeneratorVerbose, 0);
  613. if ( !resB || retVal )
  614. {
  615. std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  616. tmpFile += "/PreinstallOutput.log";
  617. cmGeneratedFileStream ofs(tmpFile.c_str());
  618. ofs << "# Run command: " << buildCommand.c_str() << std::endl
  619. << "# Directory: " << installDirectory.c_str() << std::endl
  620. << "# Output:" << std::endl
  621. << output.c_str() << std::endl;
  622. cmCPackLogger(cmCPackLog::LOG_ERROR,
  623. "Problem running install command: " << buildCommand.c_str()
  624. << std::endl
  625. << "Please check " << tmpFile.c_str() << " for errors"
  626. << std::endl);
  627. return 0;
  628. }
  629. }
  630. delete globalGenerator;
  631. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  632. "- Install project: " << installProjectName << std::endl);
  633. // Run the installation for each component
  634. std::vector<std::string>::iterator componentIt;
  635. for (componentIt = componentsVector.begin();
  636. componentIt != componentsVector.end();
  637. ++componentIt)
  638. {
  639. std::string tempInstallDirectory = baseTempInstallDirectory;
  640. installComponent = *componentIt;
  641. if (componentInstall)
  642. {
  643. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  644. "- Install component: " << installComponent
  645. << std::endl);
  646. }
  647. cmake cm;
  648. cm.AddCMakePaths();
  649. cm.SetProgressCallback(cmCPackGeneratorProgress, this);
  650. cmGlobalGenerator gg;
  651. gg.SetCMakeInstance(&cm);
  652. cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
  653. cmMakefile *mf = lg->GetMakefile();
  654. std::string realInstallDirectory = tempInstallDirectory;
  655. if ( !installSubDirectory.empty() && installSubDirectory != "/" )
  656. {
  657. realInstallDirectory += installSubDirectory;
  658. }
  659. if (componentInstall)
  660. {
  661. tempInstallDirectory += "/";
  662. // Some CPack generators would rather chose
  663. // the local installation directory suffix.
  664. // Some (e.g. RPM) use
  665. // one install directory for each component **GROUP**
  666. // instead of the default
  667. // one install directory for each component.
  668. tempInstallDirectory +=
  669. GetComponentInstallDirNameSuffix(installComponent);
  670. if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY"))
  671. {
  672. tempInstallDirectory += "/";
  673. tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME");
  674. }
  675. }
  676. if (!setDestDir)
  677. {
  678. tempInstallDirectory += this->GetPackagingInstallPrefix();
  679. }
  680. if ( setDestDir )
  681. {
  682. // For DESTDIR based packaging, use the *project*
  683. // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
  684. // value of the project's CMAKE_INSTALL_PREFIX is sent in here as
  685. // the value of the CPACK_INSTALL_PREFIX variable.
  686. //
  687. // If DESTDIR has been 'internally set ON' this means that
  688. // the underlying CPack specific generator did ask for that
  689. // In this case we may override CPACK_INSTALL_PREFIX with
  690. // CPACK_PACKAGING_INSTALL_PREFIX
  691. // I know this is tricky and awkward but it's the price for
  692. // CPACK_SET_DESTDIR backward compatibility.
  693. if (cmSystemTools::IsInternallyOn(
  694. this->GetOption("CPACK_SET_DESTDIR")))
  695. {
  696. this->SetOption("CPACK_INSTALL_PREFIX",
  697. this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
  698. }
  699. std::string dir;
  700. if (this->GetOption("CPACK_INSTALL_PREFIX"))
  701. {
  702. dir += this->GetOption("CPACK_INSTALL_PREFIX");
  703. }
  704. mf->AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
  705. cmCPackLogger(
  706. cmCPackLog::LOG_DEBUG,
  707. "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf->AddDefinition)"
  708. << std::endl);
  709. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  710. "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'"
  711. << std::endl);
  712. // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
  713. // exists:
  714. //
  715. if (cmSystemTools::StringStartsWith(dir.c_str(), "/"))
  716. {
  717. dir = tempInstallDirectory + dir;
  718. }
  719. else
  720. {
  721. dir = tempInstallDirectory + "/" + dir;
  722. }
  723. /*
  724. * We must re-set DESTDIR for each component
  725. * We must not add the CPACK_INSTALL_PREFIX part because
  726. * it will be added using the override of CMAKE_INSTALL_PREFIX
  727. * The main reason for this awkward trick is that
  728. * are using DESTDIR for 2 different reasons:
  729. * - Because it was asked by the CPack Generator or the user
  730. * using CPACK_SET_DESTDIR
  731. * - Because it was already used for component install
  732. * in order to put things in subdirs...
  733. */
  734. cmSystemTools::PutEnv(
  735. (std::string("DESTDIR=")+tempInstallDirectory).c_str()
  736. );
  737. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  738. "- Creating directory: '" << dir << "'" << std::endl);
  739. if ( !cmsys::SystemTools::MakeDirectory(dir.c_str()))
  740. {
  741. cmCPackLogger(cmCPackLog::LOG_ERROR,
  742. "Problem creating temporary directory: "
  743. << dir << std::endl);
  744. return 0;
  745. }
  746. }
  747. else
  748. {
  749. mf->AddDefinition("CMAKE_INSTALL_PREFIX",
  750. tempInstallDirectory.c_str());
  751. if ( !cmsys::SystemTools::MakeDirectory(
  752. tempInstallDirectory.c_str()))
  753. {
  754. cmCPackLogger(cmCPackLog::LOG_ERROR,
  755. "Problem creating temporary directory: "
  756. << tempInstallDirectory << std::endl);
  757. return 0;
  758. }
  759. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  760. "- Using non-DESTDIR install... (mf->AddDefinition)"
  761. << std::endl);
  762. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  763. "- Setting CMAKE_INSTALL_PREFIX to '"
  764. << tempInstallDirectory
  765. << "'" << std::endl);
  766. }
  767. if ( buildConfig && *buildConfig )
  768. {
  769. mf->AddDefinition("BUILD_TYPE", buildConfig);
  770. }
  771. std::string installComponentLowerCase
  772. = cmSystemTools::LowerCase(installComponent);
  773. if ( installComponentLowerCase != "all" )
  774. {
  775. mf->AddDefinition("CMAKE_INSTALL_COMPONENT",
  776. installComponent.c_str());
  777. }
  778. // strip on TRUE, ON, 1, one or several file names, but not on
  779. // FALSE, OFF, 0 and an empty string
  780. if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES")))
  781. {
  782. mf->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
  783. }
  784. // Remember the list of files before installation
  785. // of the current component (if we are in component install)
  786. const char* InstallPrefix = tempInstallDirectory.c_str();
  787. std::vector<std::string> filesBefore;
  788. std::string findExpr(InstallPrefix);
  789. if (componentInstall)
  790. {
  791. cmsys::Glob glB;
  792. findExpr += "/*";
  793. glB.RecurseOn();
  794. glB.FindFiles(findExpr);
  795. filesBefore = glB.GetFiles();
  796. std::sort(filesBefore.begin(),filesBefore.end());
  797. }
  798. // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION
  799. // then forward request to cmake_install.cmake script
  800. if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION"))
  801. {
  802. mf->AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION",
  803. "1");
  804. }
  805. // If current CPack generator does support
  806. // ABSOLUTE INSTALL DESTINATION or CPack has been asked for
  807. // then ask cmake_install.cmake script to error out
  808. // as soon as it occurs (before installing file)
  809. if (!SupportsAbsoluteDestination() ||
  810. this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION"))
  811. {
  812. mf->AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION",
  813. "1");
  814. }
  815. // do installation
  816. int res = mf->ReadListFile(0, installFile.c_str());
  817. // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
  818. // to CPack (may be used by generators like CPack RPM or DEB)
  819. // in order to transparently handle ABSOLUTE PATH
  820. if (mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"))
  821. {
  822. mf->AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES",
  823. mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"));
  824. }
  825. // Now rebuild the list of files after installation
  826. // of the current component (if we are in component install)
  827. if (componentInstall)
  828. {
  829. cmsys::Glob glA;
  830. glA.RecurseOn();
  831. glA.FindFiles(findExpr);
  832. std::vector<std::string> filesAfter = glA.GetFiles();
  833. std::sort(filesAfter.begin(),filesAfter.end());
  834. std::vector<std::string>::iterator diff;
  835. std::vector<std::string> result(filesAfter.size());
  836. diff = std::set_difference (
  837. filesAfter.begin(),filesAfter.end(),
  838. filesBefore.begin(),filesBefore.end(),
  839. result.begin());
  840. std::vector<std::string>::iterator fit;
  841. std::string localFileName;
  842. // Populate the File field of each component
  843. for (fit=result.begin();fit!=diff;++fit)
  844. {
  845. localFileName =
  846. cmSystemTools::RelativePath(InstallPrefix, fit->c_str());
  847. localFileName =
  848. localFileName.substr(localFileName.find_first_not_of('/'),
  849. std::string::npos);
  850. Components[installComponent].Files.push_back(localFileName);
  851. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <"
  852. <<localFileName<<"> to component <"
  853. <<installComponent<<">"<<std::endl);
  854. }
  855. }
  856. if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
  857. if (absoluteDestFiles.length()>0) {
  858. absoluteDestFiles +=";";
  859. }
  860. absoluteDestFiles +=
  861. mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
  862. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  863. "Got some ABSOLUTE DESTINATION FILES: "
  864. << absoluteDestFiles << std::endl);
  865. // define component specific var
  866. if (componentInstall)
  867. {
  868. std::string absoluteDestFileComponent =
  869. std::string("CPACK_ABSOLUTE_DESTINATION_FILES")
  870. + "_" + GetComponentInstallDirNameSuffix(installComponent);
  871. if (NULL != this->GetOption(absoluteDestFileComponent.c_str()))
  872. {
  873. std::string absoluteDestFilesListComponent =
  874. this->GetOption(absoluteDestFileComponent.c_str());
  875. absoluteDestFilesListComponent +=";";
  876. absoluteDestFilesListComponent +=
  877. mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
  878. this->SetOption(absoluteDestFileComponent.c_str(),
  879. absoluteDestFilesListComponent.c_str());
  880. }
  881. else
  882. {
  883. this->SetOption(absoluteDestFileComponent.c_str(),
  884. mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
  885. }
  886. }
  887. }
  888. if ( cmSystemTools::GetErrorOccuredFlag() || !res )
  889. {
  890. return 0;
  891. }
  892. }
  893. }
  894. }
  895. this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",
  896. absoluteDestFiles.c_str());
  897. return 1;
  898. }
  899. //----------------------------------------------------------------------
  900. bool cmCPackGenerator::ReadListFile(const char* moduleName)
  901. {
  902. bool retval;
  903. std::string fullPath = this->MakefileMap->GetModulesFile(moduleName);
  904. retval = this->MakefileMap->ReadListFile(0, fullPath.c_str());
  905. // include FATAL_ERROR and ERROR in the return status
  906. retval = retval && (! cmSystemTools::GetErrorOccuredFlag());
  907. return retval;
  908. }
  909. //----------------------------------------------------------------------
  910. void cmCPackGenerator::SetOptionIfNotSet(const char* op,
  911. const char* value)
  912. {
  913. const char* def = this->MakefileMap->GetDefinition(op);
  914. if ( def && *def )
  915. {
  916. return;
  917. }
  918. this->SetOption(op, value);
  919. }
  920. //----------------------------------------------------------------------
  921. void cmCPackGenerator::SetOption(const char* op, const char* value)
  922. {
  923. if ( !op )
  924. {
  925. return;
  926. }
  927. if ( !value )
  928. {
  929. this->MakefileMap->RemoveDefinition(op);
  930. return;
  931. }
  932. cmCPackLogger(cmCPackLog::LOG_DEBUG, this->GetNameOfClass()
  933. << "::SetOption(" << op << ", " << value << ")" << std::endl);
  934. this->MakefileMap->AddDefinition(op, value);
  935. }
  936. //----------------------------------------------------------------------
  937. int cmCPackGenerator::DoPackage()
  938. {
  939. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  940. "Create package using " << this->Name.c_str() << std::endl);
  941. // Prepare CPack internal name and check
  942. // values for many CPACK_xxx vars
  943. if ( !this->PrepareNames() )
  944. {
  945. return 0;
  946. }
  947. // Digest Component grouping specification
  948. if ( !this->PrepareGroupingKind() )
  949. {
  950. return 0;
  951. }
  952. if ( cmSystemTools::IsOn(
  953. this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) )
  954. {
  955. const char* toplevelDirectory
  956. = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  957. if ( cmSystemTools::FileExists(toplevelDirectory) )
  958. {
  959. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  960. "Remove toplevel directory: "
  961. << toplevelDirectory << std::endl);
  962. if ( !cmSystemTools::RepeatedRemoveDirectory(toplevelDirectory) )
  963. {
  964. cmCPackLogger(cmCPackLog::LOG_ERROR,
  965. "Problem removing toplevel directory: "
  966. << toplevelDirectory
  967. << std::endl);
  968. return 0;
  969. }
  970. }
  971. }
  972. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  973. "About to install project " << std::endl);
  974. if ( !this->InstallProject() )
  975. {
  976. return 0;
  977. }
  978. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  979. "Done install project " << std::endl);
  980. const char* tempPackageFileName = this->GetOption(
  981. "CPACK_TEMPORARY_PACKAGE_FILE_NAME");
  982. const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
  983. const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  984. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
  985. cmsys::Glob gl;
  986. std::string findExpr = tempDirectory;
  987. findExpr += "/*";
  988. gl.RecurseOn();
  989. gl.SetRecurseThroughSymlinks(false);
  990. if ( !gl.FindFiles(findExpr) )
  991. {
  992. cmCPackLogger(cmCPackLog::LOG_ERROR,
  993. "Cannot find any files in the packaging tree" << std::endl);
  994. return 0;
  995. }
  996. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package" << std::endl);
  997. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Package files to: "
  998. << (tempPackageFileName ? tempPackageFileName : "(NULL)") << std::endl);
  999. if ( cmSystemTools::FileExists(tempPackageFileName) )
  1000. {
  1001. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove old package file"
  1002. << std::endl);
  1003. cmSystemTools::RemoveFile(tempPackageFileName);
  1004. }
  1005. if ( cmSystemTools::IsOn(this->GetOption(
  1006. "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) )
  1007. {
  1008. tempDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  1009. }
  1010. // The files to be installed
  1011. files = gl.GetFiles();
  1012. packageFileNames.clear();
  1013. /* Put at least one file name into the list of
  1014. * wanted packageFileNames. The specific generator
  1015. * may update this during PackageFiles.
  1016. * (either putting several names or updating the provided one)
  1017. */
  1018. packageFileNames.push_back(tempPackageFileName);
  1019. toplevel = tempDirectory;
  1020. if ( !this->PackageFiles() || cmSystemTools::GetErrorOccuredFlag())
  1021. {
  1022. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory"
  1023. << std::endl);
  1024. return 0;
  1025. }
  1026. /*
  1027. * Copy the generated packages to final destination
  1028. * - there may be several of them
  1029. * - the initially provided name may have changed
  1030. * (because the specific generator did 'normalize' it)
  1031. */
  1032. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copying final package(s) ["
  1033. <<packageFileNames.size()
  1034. <<"]:"<<std::endl);
  1035. std::vector<std::string>::iterator it;
  1036. /* now copy package one by one */
  1037. for (it=packageFileNames.begin();it!=packageFileNames.end();++it)
  1038. {
  1039. std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
  1040. tempPackageFileName = it->c_str();
  1041. tmpPF += "/"+cmSystemTools::GetFilenameName(*it);
  1042. packageFileName = tmpPF.c_str();
  1043. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
  1044. << (tempPackageFileName ? tempPackageFileName : "(NULL)" )
  1045. << " to "
  1046. << (packageFileName ? packageFileName : "(NULL)")
  1047. << std::endl);
  1048. if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName,
  1049. packageFileName) )
  1050. {
  1051. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: "
  1052. << (tempPackageFileName ? tempPackageFileName : "(NULL)" )
  1053. << " to "
  1054. << (packageFileName ? packageFileName : "(NULL)")
  1055. << std::endl);
  1056. return 0;
  1057. }
  1058. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- package: "
  1059. << packageFileName
  1060. << " generated." << std::endl);
  1061. }
  1062. return 1;
  1063. }
  1064. //----------------------------------------------------------------------
  1065. int cmCPackGenerator::Initialize(const char* name, cmMakefile* mf)
  1066. {
  1067. this->MakefileMap = mf;
  1068. this->Name = name;
  1069. if ( !this->SetCMakeRoot() )
  1070. {
  1071. cmCPackLogger(cmCPackLog::LOG_ERROR,
  1072. "Cannot initialize the generator" << std::endl);
  1073. return 0;
  1074. }
  1075. // set the running generator name
  1076. this->SetOption("CPACK_GENERATOR", this->Name.c_str());
  1077. // Load the project specific config file
  1078. const char* config =
  1079. this->GetOption("CPACK_PROJECT_CONFIG_FILE");
  1080. if(config)
  1081. {
  1082. mf->ReadListFile(config);
  1083. }
  1084. int result = this->InitializeInternal();
  1085. if (cmSystemTools::GetErrorOccuredFlag())
  1086. {
  1087. return 0;
  1088. }
  1089. // If a generator subclass did not already set this option in its
  1090. // InitializeInternal implementation, and the project did not already set
  1091. // it, the default value should be:
  1092. this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/");
  1093. return result;
  1094. }
  1095. //----------------------------------------------------------------------
  1096. int cmCPackGenerator::InitializeInternal()
  1097. {
  1098. return 1;
  1099. }
  1100. //----------------------------------------------------------------------
  1101. bool cmCPackGenerator::IsSet(const char* name) const
  1102. {
  1103. return this->MakefileMap->IsSet(name);
  1104. }
  1105. //----------------------------------------------------------------------
  1106. bool cmCPackGenerator::IsOn(const char* name) const
  1107. {
  1108. return cmSystemTools::IsOn(GetOption(name));
  1109. }
  1110. //----------------------------------------------------------------------
  1111. const char* cmCPackGenerator::GetOption(const char* op) const
  1112. {
  1113. const char* ret = this->MakefileMap->GetDefinition(op);
  1114. if(!ret)
  1115. {
  1116. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  1117. "Warning, GetOption return NULL for: "
  1118. << op
  1119. << std::endl);
  1120. }
  1121. return ret;
  1122. }
  1123. //----------------------------------------------------------------------
  1124. int cmCPackGenerator::SetCMakeRoot()
  1125. {
  1126. // use the CMAKE_ROOT from cmake which should have been
  1127. // found by now
  1128. const char* root=
  1129. this->MakefileMap->GetDefinition("CMAKE_ROOT");
  1130. if(root)
  1131. {
  1132. this->CMakeRoot = root;
  1133. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  1134. << this->CMakeRoot.c_str() << std::endl);
  1135. this->SetOption("CMAKE_ROOT", this->CMakeRoot.c_str());
  1136. return 1;
  1137. }
  1138. cmCPackLogger(cmCPackLog::LOG_ERROR,
  1139. "Could not find CMAKE_ROOT !!!"
  1140. << std::endl
  1141. << "CMake has most likely not been installed correctly."
  1142. << std::endl
  1143. <<"Modules directory not found in"
  1144. << std::endl);
  1145. return 0;
  1146. }
  1147. //----------------------------------------------------------------------
  1148. int cmCPackGenerator::PackageFiles()
  1149. {
  1150. return 0;
  1151. }
  1152. //----------------------------------------------------------------------
  1153. const char* cmCPackGenerator::GetInstallPath()
  1154. {
  1155. if ( !this->InstallPath.empty() )
  1156. {
  1157. return this->InstallPath.c_str();
  1158. }
  1159. #if defined(_WIN32) && !defined(__CYGWIN__)
  1160. const char* prgfiles = cmsys::SystemTools::GetEnv("ProgramFiles");
  1161. const char* sysDrive = cmsys::SystemTools::GetEnv("SystemDrive");
  1162. if ( prgfiles )
  1163. {
  1164. this->InstallPath = prgfiles;
  1165. }
  1166. else if ( sysDrive )
  1167. {
  1168. this->InstallPath = sysDrive;
  1169. this->InstallPath += "/Program Files";
  1170. }
  1171. else
  1172. {
  1173. this->InstallPath = "c:/Program Files";
  1174. }
  1175. this->InstallPath += "/";
  1176. this->InstallPath += this->GetOption("CPACK_PACKAGE_NAME");
  1177. this->InstallPath += "-";
  1178. this->InstallPath += this->GetOption("CPACK_PACKAGE_VERSION");
  1179. #elif defined(__HAIKU__)
  1180. BPath dir;
  1181. if (find_directory(B_COMMON_DIRECTORY, &dir) == B_OK)
  1182. {
  1183. this->InstallPath = dir.Path();
  1184. }
  1185. else
  1186. {
  1187. this->InstallPath = "/boot/common";
  1188. }
  1189. #else
  1190. this->InstallPath = "/usr/local/";
  1191. #endif
  1192. return this->InstallPath.c_str();
  1193. }
  1194. //----------------------------------------------------------------------
  1195. const char* cmCPackGenerator::GetPackagingInstallPrefix()
  1196. {
  1197. cmCPackLogger(cmCPackLog::LOG_DEBUG, "GetPackagingInstallPrefix: '"
  1198. << this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX") << "'" << std::endl);
  1199. return this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
  1200. }
  1201. //----------------------------------------------------------------------
  1202. std::string cmCPackGenerator::FindTemplate(const char* name)
  1203. {
  1204. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for template: "
  1205. << (name ? name : "(NULL)") << std::endl);
  1206. std::string ffile = this->MakefileMap->GetModulesFile(name);
  1207. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Found template: "
  1208. << ffile.c_str() << std::endl);
  1209. return ffile;
  1210. }
  1211. //----------------------------------------------------------------------
  1212. bool cmCPackGenerator::ConfigureString(const std::string& inString,
  1213. std::string& outString)
  1214. {
  1215. this->MakefileMap->ConfigureString(inString,
  1216. outString, true, false);
  1217. return true;
  1218. }
  1219. //----------------------------------------------------------------------
  1220. bool cmCPackGenerator::ConfigureFile(const char* inName,
  1221. const char* outName, bool copyOnly /* = false */)
  1222. {
  1223. return this->MakefileMap->ConfigureFile(inName, outName,
  1224. copyOnly, true, false) == 1;
  1225. }
  1226. //----------------------------------------------------------------------
  1227. int cmCPackGenerator::CleanTemporaryDirectory()
  1228. {
  1229. std::string tempInstallDirectoryWithPostfix
  1230. = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
  1231. const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str();
  1232. if(cmsys::SystemTools::FileExists(tempInstallDirectory))
  1233. {
  1234. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  1235. "- Clean temporary : "
  1236. << tempInstallDirectory << std::endl);
  1237. if(!cmSystemTools::RepeatedRemoveDirectory(tempInstallDirectory))
  1238. {
  1239. cmCPackLogger(cmCPackLog::LOG_ERROR,
  1240. "Problem removing temporary directory: " <<
  1241. tempInstallDirectory
  1242. << std::endl);
  1243. return 0;
  1244. }
  1245. }
  1246. return 1;
  1247. }
  1248. //----------------------------------------------------------------------
  1249. int cmCPackGenerator::PrepareGroupingKind()
  1250. {
  1251. // find a component package method specified by the user
  1252. ComponentPackageMethod method = UNKNOWN_COMPONENT_PACKAGE_METHOD;
  1253. if(this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))
  1254. {
  1255. method = ONE_PACKAGE;
  1256. }
  1257. if(this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))
  1258. {
  1259. method = ONE_PACKAGE_PER_COMPONENT;
  1260. }
  1261. if(this->GetOption("CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP"))
  1262. {
  1263. method = ONE_PACKAGE_PER_GROUP;
  1264. }
  1265. std::string groupingType;
  1266. // Second way to specify grouping
  1267. if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) {
  1268. groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING");
  1269. }
  1270. if (groupingType.length()>0)
  1271. {
  1272. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
  1273. << this->Name << "]"
  1274. << " requested component grouping = "<< groupingType <<std::endl);
  1275. if (groupingType == "ALL_COMPONENTS_IN_ONE")
  1276. {
  1277. method = ONE_PACKAGE;
  1278. }
  1279. else if (groupingType == "IGNORE")
  1280. {
  1281. method = ONE_PACKAGE_PER_COMPONENT;
  1282. }
  1283. else if (groupingType == "ONE_PER_GROUP")
  1284. {
  1285. method = ONE_PACKAGE_PER_GROUP;
  1286. }
  1287. else
  1288. {
  1289. cmCPackLogger(cmCPackLog::LOG_WARNING, "["
  1290. << this->Name << "]"
  1291. << " requested component grouping type <"<< groupingType
  1292. << "> UNKNOWN not in (ALL_COMPONENTS_IN_ONE,IGNORE,ONE_PER_GROUP)"
  1293. << std::endl);
  1294. }
  1295. }
  1296. // Some components were defined but NO group
  1297. // fallback to default if not group based
  1298. if(method == ONE_PACKAGE_PER_GROUP &&
  1299. this->ComponentGroups.empty() && !this->Components.empty())
  1300. {
  1301. if(componentPackageMethod == ONE_PACKAGE)
  1302. {
  1303. method = ONE_PACKAGE;
  1304. }
  1305. else
  1306. {
  1307. method = ONE_PACKAGE_PER_COMPONENT;
  1308. }
  1309. cmCPackLogger(cmCPackLog::LOG_WARNING, "["
  1310. << this->Name << "]"
  1311. << " One package per component group requested, "
  1312. << "but NO component groups exist: Ignoring component group."
  1313. << std::endl);
  1314. }
  1315. // if user specified packaging method, override the default packaging method
  1316. if(method != UNKNOWN_COMPONENT_PACKAGE_METHOD)
  1317. {
  1318. componentPackageMethod = method;
  1319. }
  1320. const char* method_names[] =
  1321. {
  1322. "ALL_COMPONENTS_IN_ONE",
  1323. "IGNORE_GROUPS",
  1324. "ONE_PER_GROUP"
  1325. };
  1326. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
  1327. << this->Name << "]"
  1328. << " requested component grouping = "
  1329. << method_names[componentPackageMethod]
  1330. << std::endl);
  1331. return 1;
  1332. }
  1333. //----------------------------------------------------------------------
  1334. std::string cmCPackGenerator::GetComponentInstallDirNameSuffix(
  1335. const std::string& componentName) {
  1336. return componentName;
  1337. }
  1338. //----------------------------------------------------------------------
  1339. std::string cmCPackGenerator::GetComponentPackageFileName(
  1340. const std::string& initialPackageFileName,
  1341. const std::string& groupOrComponentName,
  1342. bool isGroupName) {
  1343. /*
  1344. * the default behavior is to use the
  1345. * component [group] name as a suffix
  1346. */
  1347. std::string suffix="-"+groupOrComponentName;
  1348. /* check if we should use DISPLAY name */
  1349. std::string dispNameVar = "CPACK_"+Name+"_USE_DISPLAY_NAME_IN_FILENAME";
  1350. if (IsOn(dispNameVar.c_str()))
  1351. {
  1352. /* the component Group case */
  1353. if (isGroupName)
  1354. {
  1355. std::string groupDispVar = "CPACK_COMPONENT_GROUP_"
  1356. + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
  1357. const char* groupDispName = GetOption(groupDispVar.c_str());
  1358. if (groupDispName)
  1359. {
  1360. suffix = "-"+std::string(groupDispName);
  1361. }
  1362. }
  1363. /* the [single] component case */
  1364. else
  1365. {
  1366. std::string dispVar = "CPACK_COMPONENT_"
  1367. + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
  1368. const char* dispName = GetOption(dispVar.c_str());
  1369. if(dispName)
  1370. {
  1371. suffix = "-"+std::string(dispName);
  1372. }
  1373. }
  1374. }
  1375. return initialPackageFileName + suffix;
  1376. }
  1377. //----------------------------------------------------------------------
  1378. enum cmCPackGenerator::CPackSetDestdirSupport
  1379. cmCPackGenerator::SupportsSetDestdir() const
  1380. {
  1381. return cmCPackGenerator::SETDESTDIR_SUPPORTED;
  1382. }
  1383. //----------------------------------------------------------------------
  1384. bool cmCPackGenerator::SupportsAbsoluteDestination() const
  1385. {
  1386. return true;
  1387. }
  1388. //----------------------------------------------------------------------
  1389. bool cmCPackGenerator::SupportsComponentInstallation() const
  1390. {
  1391. return false;
  1392. }
  1393. //----------------------------------------------------------------------
  1394. bool cmCPackGenerator::WantsComponentInstallation() const
  1395. {
  1396. return (!IsOn("CPACK_MONOLITHIC_INSTALL") & SupportsComponentInstallation());
  1397. }
  1398. //----------------------------------------------------------------------
  1399. cmCPackInstallationType*
  1400. cmCPackGenerator::GetInstallationType(const char *projectName,
  1401. const char *name)
  1402. {
  1403. (void) projectName;
  1404. bool hasInstallationType = this->InstallationTypes.count(name) != 0;
  1405. cmCPackInstallationType *installType = &this->InstallationTypes[name];
  1406. if (!hasInstallationType)
  1407. {
  1408. // Define the installation type
  1409. std::string macroPrefix = "CPACK_INSTALL_TYPE_"
  1410. + cmsys::SystemTools::UpperCase(name);
  1411. installType->Name = name;
  1412. const char* displayName
  1413. = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
  1414. if (displayName && *displayName)
  1415. {
  1416. installType->DisplayName = displayName;
  1417. }
  1418. else
  1419. {
  1420. installType->DisplayName = installType->Name;
  1421. }
  1422. installType->Index = static_cast<unsigned>(
  1423. this->InstallationTypes.size());
  1424. }
  1425. return installType;
  1426. }
  1427. //----------------------------------------------------------------------
  1428. cmCPackComponent*
  1429. cmCPackGenerator::GetComponent(const char *projectName, const char *name)
  1430. {
  1431. bool hasComponent = this->Components.count(name) != 0;
  1432. cmCPackComponent *component = &this->Components[name];
  1433. if (!hasComponent)
  1434. {
  1435. // Define the component
  1436. std::string macroPrefix = "CPACK_COMPONENT_"
  1437. + cmsys::SystemTools::UpperCase(name);
  1438. component->Name = name;
  1439. const char* displayName
  1440. = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
  1441. if (displayName && *displayName)
  1442. {
  1443. component->DisplayName = displayName;
  1444. }
  1445. else
  1446. {
  1447. component->DisplayName = component->Name;
  1448. }
  1449. component->IsHidden
  1450. = this->IsSet((macroPrefix + "_HIDDEN").c_str());
  1451. component->IsRequired
  1452. = this->IsSet((macroPrefix + "_REQUIRED").c_str());
  1453. component->IsDisabledByDefault
  1454. = this->IsSet((macroPrefix + "_DISABLED").c_str());
  1455. component->IsDownloaded
  1456. = this->IsSet((macroPrefix + "_DOWNLOADED").c_str())
  1457. || cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
  1458. const char* archiveFile = this->GetOption((macroPrefix +
  1459. "_ARCHIVE_FILE").c_str());
  1460. if (archiveFile && *archiveFile)
  1461. {
  1462. component->ArchiveFile = archiveFile;
  1463. }
  1464. const char* groupName = this->GetOption((macroPrefix + "_GROUP").c_str());
  1465. if (groupName && *groupName)
  1466. {
  1467. component->Group = GetComponentGroup(projectName, groupName);
  1468. component->Group->Components.push_back(component);
  1469. }
  1470. else
  1471. {
  1472. component->Group = 0;
  1473. }
  1474. const char* description
  1475. = this->GetOption((macroPrefix + "_DESCRIPTION").c_str());
  1476. if (description && *description)
  1477. {
  1478. component->Description = description;
  1479. }
  1480. // Determine the installation types.
  1481. const char *installTypes
  1482. = this->GetOption((macroPrefix + "_INSTALL_TYPES").c_str());
  1483. if (installTypes && *installTypes)
  1484. {
  1485. std::vector<std::string> installTypesVector;
  1486. cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
  1487. std::vector<std::string>::iterator installTypesIt;
  1488. for (installTypesIt = installTypesVector.begin();
  1489. installTypesIt != installTypesVector.end();
  1490. ++installTypesIt)
  1491. {
  1492. component->InstallationTypes.push_back(
  1493. this->GetInstallationType(projectName, installTypesIt->c_str()));
  1494. }
  1495. }
  1496. // Determine the component dependencies.
  1497. const char *depends = this->GetOption((macroPrefix + "_DEPENDS").c_str());
  1498. if (depends && *depends)
  1499. {
  1500. std::vector<std::string> dependsVector;
  1501. cmSystemTools::ExpandListArgument(depends, dependsVector);
  1502. std::vector<std::string>::iterator dependIt;
  1503. for (dependIt = dependsVector.begin();
  1504. dependIt != dependsVector.end();
  1505. ++dependIt)
  1506. {
  1507. cmCPackComponent *child = GetComponent(projectName,
  1508. dependIt->c_str());
  1509. component->Dependencies.push_back(child);
  1510. child->ReverseDependencies.push_back(component);
  1511. }
  1512. }
  1513. }
  1514. return component;
  1515. }
  1516. //----------------------------------------------------------------------
  1517. cmCPackComponentGroup*
  1518. cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name)
  1519. {
  1520. (void) projectName;
  1521. std::string macroPrefix = "CPACK_COMPONENT_GROUP_"
  1522. + cmsys::SystemTools::UpperCase(name);
  1523. bool hasGroup = this->ComponentGroups.count(name) != 0;
  1524. cmCPackComponentGroup *group = &this->ComponentGroups[name];
  1525. if (!hasGroup)
  1526. {
  1527. // Define the group
  1528. group->Name = name;
  1529. const char* displayName
  1530. = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
  1531. if (displayName && *displayName)
  1532. {
  1533. group->DisplayName = displayName;
  1534. }
  1535. else
  1536. {
  1537. group->DisplayName = group->Name;
  1538. }
  1539. const char* description
  1540. = this->GetOption((macroPrefix + "_DESCRIPTION").c_str());
  1541. if (description && *description)
  1542. {
  1543. group->Description = description;
  1544. }
  1545. group->IsBold
  1546. = this->IsSet((macroPrefix + "_BOLD_TITLE").c_str());
  1547. group->IsExpandedByDefault
  1548. = this->IsSet((macroPrefix + "_EXPANDED").c_str());
  1549. const char* parentGroupName
  1550. = this->GetOption((macroPrefix + "_PARENT_GROUP").c_str());
  1551. if (parentGroupName && *parentGroupName)
  1552. {
  1553. group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
  1554. group->ParentGroup->Subgroups.push_back(group);
  1555. }
  1556. else
  1557. {
  1558. group->ParentGroup = 0;
  1559. }
  1560. }
  1561. return group;
  1562. }