cmCPackGenericGenerator.cxx 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmCPackGenericGenerator.h"
  14. #include "cmMakefile.h"
  15. #include "cmCPackLog.h"
  16. #include "cmake.h"
  17. #include "cmGlobalGenerator.h"
  18. #include "cmLocalGenerator.h"
  19. #include "cmGeneratedFileStream.h"
  20. #include <cmsys/SystemTools.hxx>
  21. #include <cmsys/Glob.hxx>
  22. #include <memory> // auto_ptr
  23. //----------------------------------------------------------------------
  24. cmCPackGenericGenerator::cmCPackGenericGenerator()
  25. {
  26. this->GeneratorVerbose = false;
  27. this->MakefileMap = 0;
  28. this->Logger = 0;
  29. }
  30. //----------------------------------------------------------------------
  31. cmCPackGenericGenerator::~cmCPackGenericGenerator()
  32. {
  33. this->MakefileMap = 0;
  34. }
  35. //----------------------------------------------------------------------
  36. void cmCPackGenericGeneratorProgress(const char *msg, float prog, void* ptr)
  37. {
  38. cmCPackGenericGenerator* self = static_cast<cmCPackGenericGenerator*>(ptr);
  39. self->DisplayVerboseOutput(msg, prog);
  40. }
  41. //----------------------------------------------------------------------
  42. void cmCPackGenericGenerator::DisplayVerboseOutput(const char* msg,
  43. float progress)
  44. {
  45. (void)progress;
  46. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl);
  47. }
  48. //----------------------------------------------------------------------
  49. int cmCPackGenericGenerator::PrepareNames()
  50. {
  51. this->SetOption("CPACK_GENERATOR", this->Name.c_str());
  52. std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY");
  53. tempDirectory += "/_CPack_Packages/";
  54. const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG");
  55. if ( toplevelTag )
  56. {
  57. tempDirectory += toplevelTag;
  58. tempDirectory += "/";
  59. }
  60. tempDirectory += this->GetOption("CPACK_GENERATOR");
  61. std::string topDirectory = tempDirectory;
  62. std::string outName = this->GetOption("CPACK_PACKAGE_FILE_NAME");
  63. tempDirectory += "/" + outName;
  64. outName += this->GetOutputExtension();
  65. std::string destFile = this->GetOption("CPACK_PACKAGE_DIRECTORY");
  66. destFile += "/" + outName;
  67. std::string outFile = topDirectory + "/" + outName;
  68. std::string installPrefix = tempDirectory + this->GetInstallPrefix();
  69. this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory.c_str());
  70. this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory.c_str());
  71. this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName.c_str());
  72. this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile.c_str());
  73. this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
  74. outFile.c_str());
  75. this->SetOptionIfNotSet("CPACK_INSTALL_DIRECTORY", this->GetInstallPath());
  76. this->SetOptionIfNotSet("CPACK_NATIVE_INSTALL_DIRECTORY",
  77. cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath()).c_str());
  78. this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY",
  79. installPrefix.c_str());
  80. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  81. "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl);
  82. const char* descFileName
  83. = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
  84. if ( descFileName )
  85. {
  86. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  87. "Look for: " << descFileName << std::endl);
  88. if ( !cmSystemTools::FileExists(descFileName) )
  89. {
  90. cmCPackLogger(cmCPackLog::LOG_ERROR,
  91. "Cannot find description file name: ["
  92. << descFileName << "]" << std::endl);
  93. return 0;
  94. }
  95. std::ifstream ifs(descFileName);
  96. if ( !ifs )
  97. {
  98. cmCPackLogger(cmCPackLog::LOG_ERROR,
  99. "Cannot open description file name: " << descFileName << std::endl);
  100. return 0;
  101. }
  102. cmOStringStream ostr;
  103. std::string line;
  104. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  105. "Read description file: " << descFileName << std::endl);
  106. while ( ifs && cmSystemTools::GetLineFromStream(ifs, line) )
  107. {
  108. ostr << cmSystemTools::MakeXMLSafe(line.c_str()) << std::endl;
  109. }
  110. this->SetOptionIfNotSet("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str());
  111. }
  112. if ( !this->GetOption("CPACK_PACKAGE_DESCRIPTION") )
  113. {
  114. cmCPackLogger(cmCPackLog::LOG_ERROR,
  115. "Project description not specified. Please specify "
  116. "CPACK_PACKAGE_DESCRIPTION or CPACK_PACKAGE_DESCRIPTION_FILE."
  117. << std::endl);
  118. return 0;
  119. }
  120. std::vector<std::string> path;
  121. std::string pkgPath = cmSystemTools::FindProgram("strip", path, false);
  122. if ( !pkgPath.empty() )
  123. {
  124. this->SetOptionIfNotSet("CPACK_STRIP_COMMAND", pkgPath.c_str());
  125. }
  126. this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1");
  127. return 1;
  128. }
  129. //----------------------------------------------------------------------
  130. int cmCPackGenericGenerator::InstallProject()
  131. {
  132. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Install projects" << std::endl);
  133. this->CleanTemporaryDirectory();
  134. std::string tempInstallDirectoryWithPostfix
  135. = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
  136. tempInstallDirectoryWithPostfix
  137. += this->GetTemporaryInstallDirectoryPostfix();
  138. const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str();
  139. int res = 1;
  140. if ( !cmsys::SystemTools::MakeDirectory(tempInstallDirectory))
  141. {
  142. cmCPackLogger(cmCPackLog::LOG_ERROR,
  143. "Problem creating temporary directory: "
  144. << (tempInstallDirectory ? tempInstallDirectory : "(NULL}")
  145. << std::endl);
  146. return 0;
  147. }
  148. bool movable = true;
  149. if ( movable )
  150. {
  151. // Make sure there is no destdir
  152. cmSystemTools::PutEnv("DESTDIR=");
  153. }
  154. else
  155. {
  156. std::string destDir = "DESTDIR=";
  157. destDir += tempInstallDirectory;
  158. cmSystemTools::PutEnv(destDir.c_str());
  159. }
  160. // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them
  161. // as listed
  162. if ( !this->InstallProjectViaInstallCommands(
  163. movable, tempInstallDirectory) )
  164. {
  165. return 0;
  166. }
  167. // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
  168. // as listed
  169. if ( !this->InstallProjectViaInstallScript(
  170. movable, tempInstallDirectory) )
  171. {
  172. return 0;
  173. }
  174. // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES
  175. // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY
  176. // This is used in Source packageing
  177. if ( !this->InstallProjectViaInstalledDirectories(
  178. movable, tempInstallDirectory) )
  179. {
  180. return 0;
  181. }
  182. // If the project is a CMAKE project then run pre-install
  183. // and then read the cmake_install script to run it
  184. if ( !this->InstallProjectViaInstallCMakeProjects(
  185. movable, tempInstallDirectory) )
  186. {
  187. return 0;
  188. }
  189. if ( !movable )
  190. {
  191. cmSystemTools::PutEnv("DESTDIR=");
  192. }
  193. const char* stripExecutable = this->GetOption("CPACK_STRIP_COMMAND");
  194. const char* stripFiles
  195. = this->GetOption("CPACK_STRIP_FILES");
  196. if ( stripFiles && *stripFiles && stripExecutable && *stripExecutable )
  197. {
  198. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Strip files" << std::endl);
  199. std::vector<std::string> stripFilesVector;
  200. cmSystemTools::ExpandListArgument(stripFiles,
  201. stripFilesVector);
  202. std::vector<std::string>::iterator it;
  203. for ( it = stripFilesVector.begin();
  204. it != stripFilesVector.end();
  205. ++it )
  206. {
  207. std::string fileName = tempInstallDirectory;
  208. fileName += "/" + *it;
  209. fileName += cmSystemTools::GetExecutableExtension();
  210. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  211. " Strip file: " << fileName.c_str()
  212. << std::endl);
  213. std::string stripCommand = stripExecutable;
  214. stripCommand += " \"";
  215. stripCommand += fileName + "\"";
  216. int retVal = 1;
  217. std::string output;
  218. bool resB =
  219. cmSystemTools::RunSingleCommand(stripCommand.c_str(), &output,
  220. &retVal, 0,
  221. this->GeneratorVerbose, 0);
  222. if ( !resB || retVal )
  223. {
  224. cmCPackLogger(cmCPackLog::LOG_ERROR,
  225. "Problem running install command: " << stripCommand.c_str()
  226. << std::endl
  227. << "Error was: \"" << output.c_str() << "\""
  228. << std::endl);
  229. return 0;
  230. }
  231. }
  232. }
  233. return res;
  234. }
  235. //----------------------------------------------------------------------
  236. int cmCPackGenericGenerator::InstallProjectViaInstallCommands(
  237. bool movable, const char* tempInstallDirectory)
  238. {
  239. (void)movable;
  240. (void)tempInstallDirectory;
  241. const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
  242. if ( installCommands && *installCommands )
  243. {
  244. std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX=";
  245. tempInstallDirectoryEnv += tempInstallDirectory;
  246. cmSystemTools::PutEnv(tempInstallDirectoryEnv.c_str());
  247. std::vector<std::string> installCommandsVector;
  248. cmSystemTools::ExpandListArgument(installCommands,installCommandsVector);
  249. std::vector<std::string>::iterator it;
  250. for ( it = installCommandsVector.begin();
  251. it != installCommandsVector.end();
  252. ++it )
  253. {
  254. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << it->c_str()
  255. << std::endl);
  256. std::string output;
  257. int retVal = 1;
  258. bool resB = cmSystemTools::RunSingleCommand(it->c_str(), &output,
  259. &retVal, 0, this->GeneratorVerbose, 0);
  260. if ( !resB || retVal )
  261. {
  262. std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  263. tmpFile += "/InstallOutput.log";
  264. cmGeneratedFileStream ofs(tmpFile.c_str());
  265. ofs << "# Run command: " << it->c_str() << std::endl
  266. << "# Output:" << std::endl
  267. << output.c_str() << std::endl;
  268. cmCPackLogger(cmCPackLog::LOG_ERROR,
  269. "Problem running install command: " << it->c_str() << std::endl
  270. << "Please check " << tmpFile.c_str() << " for errors"
  271. << std::endl);
  272. return 0;
  273. }
  274. }
  275. }
  276. return 1;
  277. }
  278. //----------------------------------------------------------------------
  279. int cmCPackGenericGenerator::InstallProjectViaInstalledDirectories(
  280. bool movable, const char* tempInstallDirectory)
  281. {
  282. (void)movable;
  283. (void)tempInstallDirectory;
  284. std::vector<cmsys::RegularExpression> ignoreFilesRegex;
  285. const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
  286. if ( cpackIgnoreFiles )
  287. {
  288. std::vector<std::string> ignoreFilesRegexString;
  289. cmSystemTools::ExpandListArgument(cpackIgnoreFiles,
  290. ignoreFilesRegexString);
  291. std::vector<std::string>::iterator it;
  292. for ( it = ignoreFilesRegexString.begin();
  293. it != ignoreFilesRegexString.end();
  294. ++it )
  295. {
  296. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  297. "Create ignore files regex for: " << it->c_str() << std::endl);
  298. ignoreFilesRegex.push_back(it->c_str());
  299. }
  300. }
  301. const char* installDirectories
  302. = this->GetOption("CPACK_INSTALLED_DIRECTORIES");
  303. if ( installDirectories && *installDirectories )
  304. {
  305. std::vector<std::string> installDirectoriesVector;
  306. cmSystemTools::ExpandListArgument(installDirectories,
  307. installDirectoriesVector);
  308. if ( installDirectoriesVector.size() % 2 != 0 )
  309. {
  310. cmCPackLogger(cmCPackLog::LOG_ERROR,
  311. "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
  312. "<subdirectory>. The <subdirectory> can be '.' to be installed in "
  313. "the toplevel directory of installation." << std::endl);
  314. return 0;
  315. }
  316. std::vector<std::string>::iterator it;
  317. const char* tempDir = tempInstallDirectory;
  318. // this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  319. for ( it = installDirectoriesVector.begin();
  320. it != installDirectoriesVector.end();
  321. ++it )
  322. {
  323. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
  324. cmsys::Glob gl;
  325. std::string toplevel = it->c_str();
  326. it ++;
  327. std::string subdir = it->c_str();
  328. std::string findExpr = toplevel;
  329. findExpr += "/*";
  330. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  331. "- Install directory: " << toplevel << std::endl);
  332. gl.RecurseOn();
  333. if ( !gl.FindFiles(findExpr) )
  334. {
  335. cmCPackLogger(cmCPackLog::LOG_ERROR,
  336. "Cannot find any files in the installed directory" << std::endl);
  337. return 0;
  338. }
  339. std::vector<std::string>& files = gl.GetFiles();
  340. std::vector<std::string>::iterator gfit;
  341. std::vector<cmsys::RegularExpression>::iterator regIt;
  342. for ( gfit = files.begin(); gfit != files.end(); ++ gfit )
  343. {
  344. bool skip = false;
  345. std::string &inFile = *gfit;
  346. for ( regIt= ignoreFilesRegex.begin();
  347. regIt!= ignoreFilesRegex.end();
  348. ++ regIt)
  349. {
  350. if ( regIt->find(inFile.c_str()) )
  351. {
  352. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Ignore file: "
  353. << inFile.c_str() << std::endl);
  354. skip = true;
  355. }
  356. }
  357. if ( skip )
  358. {
  359. continue;
  360. }
  361. std::string filePath = tempDir;
  362. filePath += "/" + subdir + "/"
  363. + cmSystemTools::RelativePath(toplevel.c_str(), gfit->c_str());
  364. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: "
  365. << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
  366. if ( !cmSystemTools::CopyFileIfDifferent(inFile.c_str(),
  367. filePath.c_str()) )
  368. {
  369. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying file: "
  370. << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
  371. return 0;
  372. }
  373. }
  374. }
  375. }
  376. return 1;
  377. }
  378. //----------------------------------------------------------------------
  379. int cmCPackGenericGenerator::InstallProjectViaInstallScript(
  380. bool movable, const char* tempInstallDirectory)
  381. {
  382. const char* cmakeScripts
  383. = this->GetOption("CPACK_INSTALL_SCRIPT");
  384. std::string currentWorkingDirectory =
  385. cmSystemTools::GetCurrentWorkingDirectory();
  386. if ( cmakeScripts && *cmakeScripts )
  387. {
  388. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  389. "- Install scripts: " << cmakeScripts << std::endl);
  390. std::vector<std::string> cmakeScriptsVector;
  391. cmSystemTools::ExpandListArgument(cmakeScripts,
  392. cmakeScriptsVector);
  393. std::vector<std::string>::iterator it;
  394. for ( it = cmakeScriptsVector.begin();
  395. it != cmakeScriptsVector.end();
  396. ++it )
  397. {
  398. std::string installScript = it->c_str();
  399. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  400. "- Install script: " << installScript << std::endl);
  401. if ( movable )
  402. {
  403. this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
  404. }
  405. this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR",
  406. tempInstallDirectory);
  407. this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR",
  408. tempInstallDirectory);
  409. int res = this->MakefileMap->ReadListFile(0, installScript.c_str());
  410. if ( cmSystemTools::GetErrorOccuredFlag() || !res )
  411. {
  412. return 0;
  413. }
  414. }
  415. }
  416. return 1;
  417. }
  418. //----------------------------------------------------------------------
  419. int cmCPackGenericGenerator::InstallProjectViaInstallCMakeProjects(
  420. bool movable, const char* tempInstallDirectory)
  421. {
  422. const char* cmakeProjects
  423. = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
  424. const char* cmakeGenerator
  425. = this->GetOption("CPACK_CMAKE_GENERATOR");
  426. std::string currentWorkingDirectory =
  427. cmSystemTools::GetCurrentWorkingDirectory();
  428. if ( cmakeProjects && *cmakeProjects )
  429. {
  430. if ( !cmakeGenerator )
  431. {
  432. cmCPackLogger(cmCPackLog::LOG_ERROR,
  433. "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
  434. "CPACK_CMAKE_GENERATOR is not. CPACK_CMAKE_GENERATOR "
  435. "is required to install the project."
  436. << std::endl);
  437. return 0;
  438. }
  439. std::vector<std::string> cmakeProjectsVector;
  440. cmSystemTools::ExpandListArgument(cmakeProjects,
  441. cmakeProjectsVector);
  442. std::vector<std::string>::iterator it;
  443. for ( it = cmakeProjectsVector.begin();
  444. it != cmakeProjectsVector.end();
  445. ++it )
  446. {
  447. if ( it+1 == cmakeProjectsVector.end() ||
  448. it+2 == cmakeProjectsVector.end() ||
  449. it+3 == cmakeProjectsVector.end() )
  450. {
  451. cmCPackLogger(cmCPackLog::LOG_ERROR,
  452. "Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. "
  453. "CPACK_INSTALL_CMAKE_PROJECTS should hold quadruplet of install "
  454. "directory, install project name, install component, and install "
  455. "subdirectory."
  456. << std::endl);
  457. return 0;
  458. }
  459. std::string installDirectory = it->c_str();
  460. ++it;
  461. std::string installProjectName = it->c_str();
  462. ++it;
  463. std::string installComponent = it->c_str();
  464. ++it;
  465. std::string installSubDirectory = it->c_str();
  466. std::string installFile = installDirectory + "/cmake_install.cmake";
  467. const char* buildConfig = this->GetOption("CPACK_BUILD_CONFIG");
  468. cmGlobalGenerator* globalGenerator
  469. = this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
  470. cmakeGenerator);
  471. // set the global flag for unix style paths on cmSystemTools as
  472. // soon as the generator is set. This allows gmake to be used
  473. // on windows.
  474. cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths());
  475. // Does this generator require pre-install?
  476. if ( globalGenerator->GetPreinstallTargetName() )
  477. {
  478. globalGenerator->FindMakeProgram(this->MakefileMap);
  479. const char* cmakeMakeProgram
  480. = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM");
  481. std::string buildCommand
  482. = globalGenerator->GenerateBuildCommand(cmakeMakeProgram,
  483. installProjectName.c_str(), 0,
  484. globalGenerator->GetPreinstallTargetName(),
  485. buildConfig, false, false);
  486. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  487. "- Install command: " << buildCommand << std::endl);
  488. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  489. "- Run preinstall target for: " << installProjectName << std::endl);
  490. std::string output;
  491. int retVal = 1;
  492. bool resB =
  493. cmSystemTools::RunSingleCommand(buildCommand.c_str(),
  494. &output,
  495. &retVal,
  496. installDirectory.c_str(),
  497. this->GeneratorVerbose, 0);
  498. if ( !resB || retVal )
  499. {
  500. std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  501. tmpFile += "/PreinstallOutput.log";
  502. cmGeneratedFileStream ofs(tmpFile.c_str());
  503. ofs << "# Run command: " << buildCommand.c_str() << std::endl
  504. << "# Directory: " << installDirectory.c_str() << std::endl
  505. << "# Output:" << std::endl
  506. << output.c_str() << std::endl;
  507. cmCPackLogger(cmCPackLog::LOG_ERROR,
  508. "Problem running install command: " << buildCommand.c_str()
  509. << std::endl
  510. << "Please check " << tmpFile.c_str() << " for errors"
  511. << std::endl);
  512. return 0;
  513. }
  514. }
  515. delete globalGenerator;
  516. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  517. "- Install project: " << installProjectName << std::endl);
  518. cmake cm;
  519. cm.SetProgressCallback(cmCPackGenericGeneratorProgress, this);
  520. cmGlobalGenerator gg;
  521. gg.SetCMakeInstance(&cm);
  522. std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
  523. lg->SetGlobalGenerator(&gg);
  524. cmMakefile *mf = lg->GetMakefile();
  525. std::string realInstallDirectory = tempInstallDirectory;
  526. if ( !installSubDirectory.empty() && installSubDirectory != "/" )
  527. {
  528. realInstallDirectory += installSubDirectory;
  529. }
  530. if ( movable )
  531. {
  532. mf->AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
  533. }
  534. if ( buildConfig && *buildConfig )
  535. {
  536. mf->AddDefinition("BUILD_TYPE", buildConfig);
  537. }
  538. std::string installComponentLowerCase
  539. = cmSystemTools::LowerCase(installComponent);
  540. if ( installComponentLowerCase != "all" )
  541. {
  542. mf->AddDefinition("CMAKE_INSTALL_COMPONENT",
  543. installComponent.c_str());
  544. }
  545. int res = mf->ReadListFile(0, installFile.c_str());
  546. if ( cmSystemTools::GetErrorOccuredFlag() || !res )
  547. {
  548. return 0;
  549. }
  550. }
  551. }
  552. return 1;
  553. }
  554. //----------------------------------------------------------------------
  555. void cmCPackGenericGenerator::SetOptionIfNotSet(const char* op,
  556. const char* value)
  557. {
  558. const char* def = this->MakefileMap->GetDefinition(op);
  559. if ( def && *def )
  560. {
  561. return;
  562. }
  563. this->SetOption(op, value);
  564. }
  565. //----------------------------------------------------------------------
  566. void cmCPackGenericGenerator::SetOption(const char* op, const char* value)
  567. {
  568. if ( !op )
  569. {
  570. return;
  571. }
  572. if ( !value )
  573. {
  574. this->MakefileMap->RemoveDefinition(op);
  575. return;
  576. }
  577. cmCPackLogger(cmCPackLog::LOG_DEBUG, this->GetNameOfClass()
  578. << "::SetOption(" << op << ", " << value << ")" << std::endl);
  579. this->MakefileMap->AddDefinition(op, value);
  580. }
  581. //----------------------------------------------------------------------
  582. int cmCPackGenericGenerator::ProcessGenerator()
  583. {
  584. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  585. "Create package using " << this->Name.c_str() << std::endl);
  586. if ( !this->PrepareNames() )
  587. {
  588. return 0;
  589. }
  590. if ( cmSystemTools::IsOn(
  591. this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) )
  592. {
  593. const char* toplevelDirectory
  594. = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  595. if ( cmSystemTools::FileExists(toplevelDirectory) )
  596. {
  597. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove toplevel directory: "
  598. << toplevelDirectory << std::endl);
  599. if ( !cmSystemTools::RemoveADirectory(toplevelDirectory) )
  600. {
  601. cmCPackLogger(cmCPackLog::LOG_ERROR,
  602. "Problem removing toplevel directory: "
  603. << toplevelDirectory
  604. << std::endl);
  605. return 0;
  606. }
  607. }
  608. }
  609. if ( !this->InstallProject() )
  610. {
  611. return 0;
  612. }
  613. const char* tempPackageFileName = this->GetOption(
  614. "CPACK_TEMPORARY_PACKAGE_FILE_NAME");
  615. const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
  616. const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  617. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
  618. cmsys::Glob gl;
  619. std::string findExpr = tempDirectory;
  620. findExpr += "/*";
  621. gl.RecurseOn();
  622. if ( !gl.FindFiles(findExpr) )
  623. {
  624. cmCPackLogger(cmCPackLog::LOG_ERROR,
  625. "Cannot find any files in the packaging tree" << std::endl);
  626. return 0;
  627. }
  628. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Compress package" << std::endl);
  629. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Compress files to: "
  630. << (tempPackageFileName ? tempPackageFileName : "(NULL)") << std::endl);
  631. if ( cmSystemTools::FileExists(tempPackageFileName) )
  632. {
  633. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove old package file"
  634. << std::endl);
  635. cmSystemTools::RemoveFile(tempPackageFileName);
  636. }
  637. if ( cmSystemTools::IsOn(this->GetOption(
  638. "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) )
  639. {
  640. tempDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  641. }
  642. if ( !this->CompressFiles(tempPackageFileName,
  643. tempDirectory, gl.GetFiles()) )
  644. {
  645. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory"
  646. << std::endl);
  647. return 0;
  648. }
  649. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Finalize package" << std::endl);
  650. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copy final package: "
  651. << (tempPackageFileName ? tempPackageFileName : "(NULL)" )
  652. << " to "
  653. << (packageFileName ? packageFileName : "(NULL)")
  654. << std::endl);
  655. if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName,
  656. packageFileName) )
  657. {
  658. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: "
  659. << (tempPackageFileName ? tempPackageFileName : "(NULL)" )
  660. << " to "
  661. << (packageFileName ? packageFileName : "(NULL)")
  662. << std::endl);
  663. return 0;
  664. }
  665. cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Package "
  666. << (packageFileName ? packageFileName : "(NULL)")
  667. << " generated." << std::endl);
  668. return 1;
  669. }
  670. //----------------------------------------------------------------------
  671. int cmCPackGenericGenerator::Initialize(const char* name, cmMakefile* mf,
  672. const char* argv0)
  673. {
  674. this->MakefileMap = mf;
  675. this->Name = name;
  676. if ( !this->FindRunningCMake(argv0) )
  677. {
  678. cmCPackLogger(cmCPackLog::LOG_ERROR,
  679. "Cannot initialize the generator" << std::endl);
  680. return 0;
  681. }
  682. return this->InitializeInternal();
  683. }
  684. //----------------------------------------------------------------------
  685. int cmCPackGenericGenerator::InitializeInternal()
  686. {
  687. return 1;
  688. }
  689. //----------------------------------------------------------------------
  690. const char* cmCPackGenericGenerator::GetOption(const char* op)
  691. {
  692. return this->MakefileMap->GetDefinition(op);
  693. }
  694. //----------------------------------------------------------------------
  695. int cmCPackGenericGenerator::FindRunningCMake(const char* arg0)
  696. {
  697. int found = 0;
  698. // Find our own executable.
  699. std::vector<cmStdString> failures;
  700. this->CPackSelf = arg0;
  701. cmSystemTools::ConvertToUnixSlashes(this->CPackSelf);
  702. failures.push_back(this->CPackSelf);
  703. this->CPackSelf = cmSystemTools::FindProgram(this->CPackSelf.c_str());
  704. if(!cmSystemTools::FileExists(this->CPackSelf.c_str()))
  705. {
  706. failures.push_back(this->CPackSelf);
  707. this->CPackSelf = "/usr/local/bin/ctest";
  708. }
  709. if(!cmSystemTools::FileExists(this->CPackSelf.c_str()))
  710. {
  711. failures.push_back(this->CPackSelf);
  712. cmOStringStream msg;
  713. msg << "CPack can not find the command line program ctest.\n";
  714. msg << " argv[0] = \"" << arg0 << "\"\n";
  715. msg << " Attempted paths:\n";
  716. std::vector<cmStdString>::iterator i;
  717. for(i=failures.begin(); i != failures.end(); ++i)
  718. {
  719. msg << " \"" << i->c_str() << "\"\n";
  720. }
  721. cmCPackLogger(cmCPackLog::LOG_ERROR, msg.str().c_str()
  722. << std::endl);
  723. return 0;
  724. }
  725. std::string dir;
  726. std::string file;
  727. if(cmSystemTools::SplitProgramPath(this->CPackSelf.c_str(),
  728. dir, file, true))
  729. {
  730. this->CMakeSelf = dir += "/cmake";
  731. this->CMakeSelf += cmSystemTools::GetExecutableExtension();
  732. if(cmSystemTools::FileExists(this->CMakeSelf.c_str()))
  733. {
  734. found = 1;
  735. }
  736. }
  737. if ( !found )
  738. {
  739. failures.push_back(this->CMakeSelf);
  740. #ifdef CMAKE_BUILD_DIR
  741. std::string intdir = ".";
  742. #ifdef CMAKE_INTDIR
  743. intdir = CMAKE_INTDIR;
  744. #endif
  745. this->CMakeSelf = CMAKE_BUILD_DIR;
  746. this->CMakeSelf += "/bin/";
  747. this->CMakeSelf += intdir;
  748. this->CMakeSelf += "/cmake";
  749. this->CMakeSelf += cmSystemTools::GetExecutableExtension();
  750. #endif
  751. if(!cmSystemTools::FileExists(this->CMakeSelf.c_str()))
  752. {
  753. failures.push_back(this->CMakeSelf);
  754. cmOStringStream msg;
  755. msg << "CPack can not find the command line program cmake.\n";
  756. msg << " argv[0] = \"" << arg0 << "\"\n";
  757. msg << " Attempted paths:\n";
  758. std::vector<cmStdString>::iterator i;
  759. for(i=failures.begin(); i != failures.end(); ++i)
  760. {
  761. msg << " \"" << i->c_str() << "\"\n";
  762. }
  763. cmCPackLogger(cmCPackLog::LOG_ERROR, msg.str().c_str()
  764. << std::endl);
  765. return 0;
  766. }
  767. }
  768. // do CMAKE_ROOT, look for the environment variable first
  769. std::string cMakeRoot;
  770. std::string modules;
  771. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT" << std::endl);
  772. if (getenv("CMAKE_ROOT"))
  773. {
  774. cMakeRoot = getenv("CMAKE_ROOT");
  775. modules = cMakeRoot + "/Modules/CMake.cmake";
  776. }
  777. if(modules.empty() || !cmSystemTools::FileExists(modules.c_str()))
  778. {
  779. // next try exe/..
  780. cMakeRoot = cmSystemTools::GetProgramPath(this->CMakeSelf.c_str());
  781. std::string::size_type slashPos = cMakeRoot.rfind("/");
  782. if(slashPos != std::string::npos)
  783. {
  784. cMakeRoot = cMakeRoot.substr(0, slashPos);
  785. }
  786. // is there no Modules direcory there?
  787. modules = cMakeRoot + "/Modules/CMake.cmake";
  788. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  789. << modules.c_str() << std::endl);
  790. }
  791. if (!cmSystemTools::FileExists(modules.c_str()))
  792. {
  793. // try exe/../share/cmake
  794. cMakeRoot += CMAKE_DATA_DIR;
  795. modules = cMakeRoot + "/Modules/CMake.cmake";
  796. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  797. << modules.c_str() << std::endl);
  798. }
  799. #ifdef CMAKE_ROOT_DIR
  800. if (!cmSystemTools::FileExists(modules.c_str()))
  801. {
  802. // try compiled in root directory
  803. cMakeRoot = CMAKE_ROOT_DIR;
  804. modules = cMakeRoot + "/Modules/CMake.cmake";
  805. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  806. << modules.c_str() << std::endl);
  807. }
  808. #endif
  809. #ifdef CMAKE_PREFIX
  810. if (!cmSystemTools::FileExists(modules.c_str()))
  811. {
  812. // try compiled in install prefix
  813. cMakeRoot = CMAKE_PREFIX CMAKE_DATA_DIR;
  814. modules = cMakeRoot + "/Modules/CMake.cmake";
  815. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  816. << modules.c_str() << std::endl);
  817. }
  818. #endif
  819. if (!cmSystemTools::FileExists(modules.c_str()))
  820. {
  821. // try
  822. cMakeRoot = cmSystemTools::GetProgramPath(this->CMakeSelf.c_str());
  823. cMakeRoot += CMAKE_DATA_DIR;
  824. modules = cMakeRoot + "/Modules/CMake.cmake";
  825. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  826. << modules.c_str() << std::endl);
  827. }
  828. if(!cmSystemTools::FileExists(modules.c_str()))
  829. {
  830. // next try exe
  831. cMakeRoot = cmSystemTools::GetProgramPath(this->CMakeSelf.c_str());
  832. // is there no Modules direcory there?
  833. modules = cMakeRoot + "/Modules/CMake.cmake";
  834. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  835. << modules.c_str() << std::endl);
  836. }
  837. if (!cmSystemTools::FileExists(modules.c_str()))
  838. {
  839. // couldn't find modules
  840. cmCPackLogger(cmCPackLog::LOG_ERROR,
  841. "Could not find CMAKE_ROOT !!!" << std::endl
  842. << "CMake has most likely not been installed correctly." << std::endl
  843. <<"Modules directory not found in" << std::endl
  844. << cMakeRoot.c_str()
  845. << std::endl);
  846. return 0;
  847. }
  848. this->CMakeRoot = cMakeRoot;
  849. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
  850. << this->CMakeRoot.c_str() << std::endl);
  851. this->SetOption("CMAKE_ROOT", this->CMakeRoot.c_str());
  852. return 1;
  853. }
  854. //----------------------------------------------------------------------
  855. int cmCPackGenericGenerator::CompressFiles(const char* outFileName,
  856. const char* toplevel, const std::vector<std::string>& files)
  857. {
  858. (void)outFileName;
  859. (void)toplevel;
  860. (void)files;
  861. return 0;
  862. }
  863. //----------------------------------------------------------------------
  864. const char* cmCPackGenericGenerator::GetInstallPath()
  865. {
  866. if ( !this->InstallPath.empty() )
  867. {
  868. return this->InstallPath.c_str();
  869. }
  870. #if defined(_WIN32) && !defined(__CYGWIN__)
  871. const char* prgfiles = cmsys::SystemTools::GetEnv("ProgramFiles");
  872. const char* sysDrive = cmsys::SystemTools::GetEnv("SystemDrive");
  873. if ( prgfiles )
  874. {
  875. this->InstallPath = prgfiles;
  876. }
  877. else if ( sysDrive )
  878. {
  879. this->InstallPath = sysDrive;
  880. this->InstallPath += "/Program Files";
  881. }
  882. else
  883. {
  884. this->InstallPath = "c:/Program Files";
  885. }
  886. this->InstallPath += "/";
  887. this->InstallPath += this->GetOption("CPACK_PACKAGE_NAME");
  888. this->InstallPath += "-";
  889. this->InstallPath += this->GetOption("CPACK_PACKAGE_VERSION");
  890. #else
  891. this->InstallPath = "/usr/local/";
  892. #endif
  893. return this->InstallPath.c_str();
  894. }
  895. //----------------------------------------------------------------------
  896. std::string cmCPackGenericGenerator::FindTemplate(const char* name)
  897. {
  898. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for template: "
  899. << (name ? name : "(NULL)") << std::endl);
  900. std::string ffile = this->MakefileMap->GetModulesFile(name);
  901. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Found template: "
  902. << ffile.c_str() << std::endl);
  903. return ffile;
  904. }
  905. //----------------------------------------------------------------------
  906. bool cmCPackGenericGenerator::ConfigureString(const std::string& inString,
  907. std::string& outString)
  908. {
  909. this->MakefileMap->ConfigureString(inString,
  910. outString, true, false);
  911. return true;
  912. }
  913. //----------------------------------------------------------------------
  914. bool cmCPackGenericGenerator::ConfigureFile(const char* inName,
  915. const char* outName, bool copyOnly /* = false */)
  916. {
  917. return this->MakefileMap->ConfigureFile(inName, outName,
  918. copyOnly, true, false) == 1;
  919. }
  920. //----------------------------------------------------------------------
  921. int cmCPackGenericGenerator::CleanTemporaryDirectory()
  922. {
  923. std::string tempInstallDirectoryWithPostfix
  924. = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
  925. tempInstallDirectoryWithPostfix
  926. += this->GetTemporaryInstallDirectoryPostfix();
  927. const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str();
  928. if(cmsys::SystemTools::FileExists(tempInstallDirectory))
  929. {
  930. cmCPackLogger(cmCPackLog::LOG_OUTPUT,
  931. "- Clean temporary : "
  932. << tempInstallDirectory << std::endl);
  933. if(!cmsys::SystemTools::RemoveADirectory(tempInstallDirectory))
  934. {
  935. cmCPackLogger(cmCPackLog::LOG_ERROR,
  936. "Problem removing temporary directory: " <<
  937. tempInstallDirectory
  938. << std::endl);
  939. return 0;
  940. }
  941. }
  942. return 1;
  943. }