cmCPackGenericGenerator.cxx 34 KB

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