1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCPackGenerator.cxx,v $
6 Date: $Date: 2009-02-05 21:31:37 $
7 Version: $Revision: 1.17 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
18 #include "cmCPackGenerator.h"
20 #include "cmMakefile.h"
21 #include "cmCPackLog.h"
23 #include "cmGlobalGenerator.h"
24 #include "cmLocalGenerator.h"
25 #include "cmGeneratedFileStream.h"
26 #include "cmCPackComponentGroup.h"
27 #include "cmXMLSafe.h"
29 #include <cmsys/SystemTools.hxx>
30 #include <cmsys/Glob.hxx>
31 #include <memory> // auto_ptr
33 //----------------------------------------------------------------------
34 cmCPackGenerator::cmCPackGenerator()
36 this->GeneratorVerbose
= false;
37 this->MakefileMap
= 0;
41 //----------------------------------------------------------------------
42 cmCPackGenerator::~cmCPackGenerator()
44 this->MakefileMap
= 0;
47 //----------------------------------------------------------------------
48 void cmCPackGeneratorProgress(const char *msg
, float prog
, void* ptr
)
50 cmCPackGenerator
* self
= static_cast<cmCPackGenerator
*>(ptr
);
51 self
->DisplayVerboseOutput(msg
, prog
);
54 //----------------------------------------------------------------------
55 void cmCPackGenerator::DisplayVerboseOutput(const char* msg
,
59 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "" << msg
<< std::endl
);
62 //----------------------------------------------------------------------
63 int cmCPackGenerator::PrepareNames()
65 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
66 "Create temp directory." << std::endl
);
68 std::string tempDirectory
= this->GetOption("CPACK_PACKAGE_DIRECTORY");
69 tempDirectory
+= "/_CPack_Packages/";
70 const char* toplevelTag
= this->GetOption("CPACK_TOPLEVEL_TAG");
73 tempDirectory
+= toplevelTag
;
76 tempDirectory
+= this->GetOption("CPACK_GENERATOR");
77 std::string topDirectory
= tempDirectory
;
78 this->GetOption("CPACK_PACKAGE_FILE_NAME");
79 const char* pfname
= this->GetOption("CPACK_PACKAGE_FILE_NAME");
82 cmCPackLogger(cmCPackLog::LOG_ERROR
,
83 "CPACK_PACKAGE_FILE_NAME not specified" << std::endl
);
86 std::string outName
= pfname
;
87 tempDirectory
+= "/" + outName
;
88 if(!this->GetOutputExtension())
90 cmCPackLogger(cmCPackLog::LOG_ERROR
,
91 "No output extension specified" << std::endl
);
94 outName
+= this->GetOutputExtension();
95 const char* pdir
= this->GetOption("CPACK_PACKAGE_DIRECTORY");
98 cmCPackLogger(cmCPackLog::LOG_ERROR
,
99 "CPACK_PACKAGE_DIRECTORY not specified" << std::endl
);
103 std::string destFile
= pdir
;
104 destFile
+= "/" + outName
;
105 std::string outFile
= topDirectory
+ "/" + outName
;
106 this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory
.c_str());
107 this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory
.c_str());
108 this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName
.c_str());
109 this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile
.c_str());
110 this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
112 this->SetOptionIfNotSet("CPACK_INSTALL_DIRECTORY", this->GetInstallPath());
113 this->SetOptionIfNotSet("CPACK_NATIVE_INSTALL_DIRECTORY",
114 cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath()).c_str());
115 this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY",
116 tempDirectory
.c_str());
118 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
119 "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl
);
120 const char* descFileName
121 = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
124 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
125 "Look for: " << descFileName
<< std::endl
);
126 if ( !cmSystemTools::FileExists(descFileName
) )
128 cmCPackLogger(cmCPackLog::LOG_ERROR
,
129 "Cannot find description file name: ["
130 << descFileName
<< "]" << std::endl
);
133 std::ifstream
ifs(descFileName
);
136 cmCPackLogger(cmCPackLog::LOG_ERROR
,
137 "Cannot open description file name: " << descFileName
<< std::endl
);
140 cmOStringStream ostr
;
143 cmCPackLogger(cmCPackLog::LOG_VERBOSE
,
144 "Read description file: " << descFileName
<< std::endl
);
145 while ( ifs
&& cmSystemTools::GetLineFromStream(ifs
, line
) )
147 ostr
<< cmXMLSafe(line
) << std::endl
;
149 this->SetOptionIfNotSet("CPACK_PACKAGE_DESCRIPTION", ostr
.str().c_str());
151 if ( !this->GetOption("CPACK_PACKAGE_DESCRIPTION") )
153 cmCPackLogger(cmCPackLog::LOG_ERROR
,
154 "Project description not specified. Please specify "
155 "CPACK_PACKAGE_DESCRIPTION or CPACK_PACKAGE_DESCRIPTION_FILE."
160 this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1");
165 //----------------------------------------------------------------------
166 int cmCPackGenerator::InstallProject()
168 cmCPackLogger(cmCPackLog::LOG_OUTPUT
, "Install projects" << std::endl
);
169 this->CleanTemporaryDirectory();
171 std::string bareTempInstallDirectory
172 = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
173 std::string tempInstallDirectoryStr
= bareTempInstallDirectory
;
174 bool setDestDir
= cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR"));
177 tempInstallDirectoryStr
+= this->GetPackagingInstallPrefix();
180 const char* tempInstallDirectory
= tempInstallDirectoryStr
.c_str();
182 if ( !cmsys::SystemTools::MakeDirectory(bareTempInstallDirectory
.c_str()))
184 cmCPackLogger(cmCPackLog::LOG_ERROR
,
185 "Problem creating temporary directory: "
186 << (tempInstallDirectory
? tempInstallDirectory
: "(NULL}")
193 std::string destDir
= "DESTDIR=";
194 destDir
+= tempInstallDirectory
;
195 cmSystemTools::PutEnv(destDir
.c_str());
199 // Make sure there is no destdir
200 cmSystemTools::PutEnv("DESTDIR=");
203 // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them
205 if ( !this->InstallProjectViaInstallCommands(
206 setDestDir
, tempInstallDirectory
) )
211 // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
213 if ( !this->InstallProjectViaInstallScript(
214 setDestDir
, tempInstallDirectory
) )
219 // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES
220 // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY
221 // This is used in Source packageing
222 if ( !this->InstallProjectViaInstalledDirectories(
223 setDestDir
, tempInstallDirectory
) )
229 // If the project is a CMAKE project then run pre-install
230 // and then read the cmake_install script to run it
231 if ( !this->InstallProjectViaInstallCMakeProjects(
232 setDestDir
, bareTempInstallDirectory
.c_str()) )
239 cmSystemTools::PutEnv("DESTDIR=");
245 //----------------------------------------------------------------------
246 int cmCPackGenerator::InstallProjectViaInstallCommands(
247 bool setDestDir
, const char* tempInstallDirectory
)
250 const char* installCommands
= this->GetOption("CPACK_INSTALL_COMMANDS");
251 if ( installCommands
&& *installCommands
)
253 std::string tempInstallDirectoryEnv
= "CMAKE_INSTALL_PREFIX=";
254 tempInstallDirectoryEnv
+= tempInstallDirectory
;
255 cmSystemTools::PutEnv(tempInstallDirectoryEnv
.c_str());
256 std::vector
<std::string
> installCommandsVector
;
257 cmSystemTools::ExpandListArgument(installCommands
,installCommandsVector
);
258 std::vector
<std::string
>::iterator it
;
259 for ( it
= installCommandsVector
.begin();
260 it
!= installCommandsVector
.end();
263 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Execute: " << it
->c_str()
267 bool resB
= cmSystemTools::RunSingleCommand(it
->c_str(), &output
,
268 &retVal
, 0, this->GeneratorVerbose
, 0);
269 if ( !resB
|| retVal
)
271 std::string tmpFile
= this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
272 tmpFile
+= "/InstallOutput.log";
273 cmGeneratedFileStream
ofs(tmpFile
.c_str());
274 ofs
<< "# Run command: " << it
->c_str() << std::endl
275 << "# Output:" << std::endl
276 << output
.c_str() << std::endl
;
277 cmCPackLogger(cmCPackLog::LOG_ERROR
,
278 "Problem running install command: " << it
->c_str() << std::endl
279 << "Please check " << tmpFile
.c_str() << " for errors"
288 //----------------------------------------------------------------------
289 int cmCPackGenerator::InstallProjectViaInstalledDirectories(
290 bool setDestDir
, const char* tempInstallDirectory
)
293 (void)tempInstallDirectory
;
294 std::vector
<cmsys::RegularExpression
> ignoreFilesRegex
;
295 const char* cpackIgnoreFiles
= this->GetOption("CPACK_IGNORE_FILES");
296 if ( cpackIgnoreFiles
)
298 std::vector
<std::string
> ignoreFilesRegexString
;
299 cmSystemTools::ExpandListArgument(cpackIgnoreFiles
,
300 ignoreFilesRegexString
);
301 std::vector
<std::string
>::iterator it
;
302 for ( it
= ignoreFilesRegexString
.begin();
303 it
!= ignoreFilesRegexString
.end();
306 cmCPackLogger(cmCPackLog::LOG_VERBOSE
,
307 "Create ignore files regex for: " << it
->c_str() << std::endl
);
308 ignoreFilesRegex
.push_back(it
->c_str());
311 const char* installDirectories
312 = this->GetOption("CPACK_INSTALLED_DIRECTORIES");
313 if ( installDirectories
&& *installDirectories
)
315 std::vector
<std::string
> installDirectoriesVector
;
316 cmSystemTools::ExpandListArgument(installDirectories
,
317 installDirectoriesVector
);
318 if ( installDirectoriesVector
.size() % 2 != 0 )
320 cmCPackLogger(cmCPackLog::LOG_ERROR
,
321 "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
322 "<subdirectory>. The <subdirectory> can be '.' to be installed in "
323 "the toplevel directory of installation." << std::endl
);
326 std::vector
<std::string
>::iterator it
;
327 const char* tempDir
= tempInstallDirectory
;
328 for ( it
= installDirectoriesVector
.begin();
329 it
!= installDirectoriesVector
.end();
332 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "Find files" << std::endl
);
334 std::string toplevel
= it
->c_str();
336 std::string subdir
= it
->c_str();
337 std::string findExpr
= toplevel
;
339 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
340 "- Install directory: " << toplevel
<< std::endl
);
342 if ( !gl
.FindFiles(findExpr
) )
344 cmCPackLogger(cmCPackLog::LOG_ERROR
,
345 "Cannot find any files in the installed directory" << std::endl
);
348 std::vector
<std::string
>& files
= gl
.GetFiles();
349 std::vector
<std::string
>::iterator gfit
;
350 std::vector
<cmsys::RegularExpression
>::iterator regIt
;
351 for ( gfit
= files
.begin(); gfit
!= files
.end(); ++ gfit
)
354 std::string
&inFile
= *gfit
;
355 for ( regIt
= ignoreFilesRegex
.begin();
356 regIt
!= ignoreFilesRegex
.end();
359 if ( regIt
->find(inFile
.c_str()) )
361 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Ignore file: "
362 << inFile
.c_str() << std::endl
);
370 std::string filePath
= tempDir
;
371 filePath
+= "/" + subdir
+ "/"
372 + cmSystemTools::RelativePath(toplevel
.c_str(), gfit
->c_str());
373 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "Copy file: "
374 << inFile
.c_str() << " -> " << filePath
.c_str() << std::endl
);
375 if ( !cmSystemTools::CopyFileIfDifferent(inFile
.c_str(),
378 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem copying file: "
379 << inFile
.c_str() << " -> " << filePath
.c_str() << std::endl
);
388 //----------------------------------------------------------------------
389 int cmCPackGenerator::InstallProjectViaInstallScript(
390 bool setDestDir
, const char* tempInstallDirectory
)
392 const char* cmakeScripts
393 = this->GetOption("CPACK_INSTALL_SCRIPT");
394 std::string currentWorkingDirectory
=
395 cmSystemTools::GetCurrentWorkingDirectory();
396 if ( cmakeScripts
&& *cmakeScripts
)
398 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
399 "- Install scripts: " << cmakeScripts
<< std::endl
);
400 std::vector
<std::string
> cmakeScriptsVector
;
401 cmSystemTools::ExpandListArgument(cmakeScripts
,
403 std::vector
<std::string
>::iterator it
;
404 for ( it
= cmakeScriptsVector
.begin();
405 it
!= cmakeScriptsVector
.end();
408 std::string installScript
= it
->c_str();
410 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
411 "- Install script: " << installScript
<< std::endl
);
415 // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
416 // underneath the tempInstallDirectory. The value of the project's
417 // CMAKE_INSTALL_PREFIX is sent in here as the value of the
418 // CPACK_INSTALL_PREFIX variable.
420 if (this->GetOption("CPACK_INSTALL_PREFIX"))
422 dir
+= this->GetOption("CPACK_INSTALL_PREFIX");
424 this->SetOption("CMAKE_INSTALL_PREFIX", dir
.c_str());
425 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
426 "- Using DESTDIR + CPACK_INSTALL_PREFIX... (this->SetOption)"
428 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
429 "- Setting CMAKE_INSTALL_PREFIX to '" << dir
<< "'" << std::endl
);
433 this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory
);
435 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
436 "- Using non-DESTDIR install... (this->SetOption)" << std::endl
);
437 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
438 "- Setting CMAKE_INSTALL_PREFIX to '" << tempInstallDirectory
439 << "'" << std::endl
);
442 this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR",
443 tempInstallDirectory
);
444 this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR",
445 tempInstallDirectory
);
446 int res
= this->MakefileMap
->ReadListFile(0, installScript
.c_str());
447 if ( cmSystemTools::GetErrorOccuredFlag() || !res
)
456 //----------------------------------------------------------------------
457 int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
458 bool setDestDir
, const char* baseTempInstallDirectory
)
460 const char* cmakeProjects
461 = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
462 const char* cmakeGenerator
463 = this->GetOption("CPACK_CMAKE_GENERATOR");
464 std::string currentWorkingDirectory
=
465 cmSystemTools::GetCurrentWorkingDirectory();
466 if ( cmakeProjects
&& *cmakeProjects
)
468 if ( !cmakeGenerator
)
470 cmCPackLogger(cmCPackLog::LOG_ERROR
,
471 "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
472 "CPACK_CMAKE_GENERATOR is not. CPACK_CMAKE_GENERATOR "
473 "is required to install the project."
477 std::vector
<std::string
> cmakeProjectsVector
;
478 cmSystemTools::ExpandListArgument(cmakeProjects
,
479 cmakeProjectsVector
);
480 std::vector
<std::string
>::iterator it
;
481 for ( it
= cmakeProjectsVector
.begin();
482 it
!= cmakeProjectsVector
.end();
485 if ( it
+1 == cmakeProjectsVector
.end() ||
486 it
+2 == cmakeProjectsVector
.end() ||
487 it
+3 == cmakeProjectsVector
.end() )
489 cmCPackLogger(cmCPackLog::LOG_ERROR
,
490 "Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. "
491 "CPACK_INSTALL_CMAKE_PROJECTS should hold quadruplet of install "
492 "directory, install project name, install component, and install "
497 std::string installDirectory
= it
->c_str();
499 std::string installProjectName
= it
->c_str();
501 std::string installComponent
= it
->c_str();
503 std::string installSubDirectory
= it
->c_str();
504 std::string installFile
= installDirectory
+ "/cmake_install.cmake";
506 std::vector
<std::string
> componentsVector
;
508 bool componentInstall
= false;
509 if (this->SupportsComponentInstallation())
511 // Determine the installation types for this project (if provided).
512 std::string installTypesVar
= "CPACK_"
513 + cmSystemTools::UpperCase(installComponent
) + "_INSTALL_TYPES";
514 const char *installTypes
= this->GetOption(installTypesVar
.c_str());
515 if (installTypes
&& *installTypes
)
517 std::vector
<std::string
> installTypesVector
;
518 cmSystemTools::ExpandListArgument(installTypes
, installTypesVector
);
519 std::vector
<std::string
>::iterator installTypeIt
;
520 for (installTypeIt
= installTypesVector
.begin();
521 installTypeIt
!= installTypesVector
.end();
524 this->GetInstallationType(installProjectName
.c_str(),
525 installTypeIt
->c_str());
529 // Determine the set of components that will be used in this project
530 std::string componentsVar
531 = "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent
);
532 const char *components
= this->GetOption(componentsVar
.c_str());
533 if (components
&& *components
)
535 cmSystemTools::ExpandListArgument(components
, componentsVector
);
536 std::vector
<std::string
>::iterator compIt
;
537 for (compIt
= componentsVector
.begin();
538 compIt
!= componentsVector
.end();
541 GetComponent(installProjectName
.c_str(), compIt
->c_str());
543 componentInstall
= true;
546 if (componentsVector
.empty())
548 componentsVector
.push_back(installComponent
);
551 const char* buildConfig
= this->GetOption("CPACK_BUILD_CONFIG");
552 cmGlobalGenerator
* globalGenerator
553 = this->MakefileMap
->GetCMakeInstance()->CreateGlobalGenerator(
555 // set the global flag for unix style paths on cmSystemTools as
556 // soon as the generator is set. This allows gmake to be used
558 cmSystemTools::SetForceUnixPaths(globalGenerator
->GetForceUnixPaths());
560 // Does this generator require pre-install?
561 if ( globalGenerator
->GetPreinstallTargetName() )
563 globalGenerator
->FindMakeProgram(this->MakefileMap
);
564 const char* cmakeMakeProgram
565 = this->MakefileMap
->GetDefinition("CMAKE_MAKE_PROGRAM");
566 std::string buildCommand
567 = globalGenerator
->GenerateBuildCommand(cmakeMakeProgram
,
568 installProjectName
.c_str(), 0,
569 globalGenerator
->GetPreinstallTargetName(),
570 buildConfig
, false, false);
571 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
572 "- Install command: " << buildCommand
<< std::endl
);
573 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
574 "- Run preinstall target for: " << installProjectName
<< std::endl
);
578 cmSystemTools::RunSingleCommand(buildCommand
.c_str(),
581 installDirectory
.c_str(),
582 this->GeneratorVerbose
, 0);
583 if ( !resB
|| retVal
)
585 std::string tmpFile
= this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
586 tmpFile
+= "/PreinstallOutput.log";
587 cmGeneratedFileStream
ofs(tmpFile
.c_str());
588 ofs
<< "# Run command: " << buildCommand
.c_str() << std::endl
589 << "# Directory: " << installDirectory
.c_str() << std::endl
590 << "# Output:" << std::endl
591 << output
.c_str() << std::endl
;
592 cmCPackLogger(cmCPackLog::LOG_ERROR
,
593 "Problem running install command: " << buildCommand
.c_str()
595 << "Please check " << tmpFile
.c_str() << " for errors"
600 delete globalGenerator
;
602 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
603 "- Install project: " << installProjectName
<< std::endl
);
605 // Run the installation for each component
606 std::vector
<std::string
>::iterator componentIt
;
607 for (componentIt
= componentsVector
.begin();
608 componentIt
!= componentsVector
.end();
611 std::string tempInstallDirectory
= baseTempInstallDirectory
;
612 installComponent
= *componentIt
;
613 if (componentInstall
)
615 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
616 "- Install component: " << installComponent
622 cm
.SetProgressCallback(cmCPackGeneratorProgress
, this);
623 cmGlobalGenerator gg
;
624 gg
.SetCMakeInstance(&cm
);
625 std::auto_ptr
<cmLocalGenerator
> lg(gg
.CreateLocalGenerator());
626 lg
->SetGlobalGenerator(&gg
);
627 cmMakefile
*mf
= lg
->GetMakefile();
628 std::string realInstallDirectory
= tempInstallDirectory
;
629 if ( !installSubDirectory
.empty() && installSubDirectory
!= "/" )
631 realInstallDirectory
+= installSubDirectory
;
633 if (componentInstall
)
635 tempInstallDirectory
+= "/";
636 tempInstallDirectory
+= installComponent
;
641 tempInstallDirectory
+= this->GetPackagingInstallPrefix();
646 // For DESTDIR based packaging, use the *project*
647 // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
648 // value of the project's CMAKE_INSTALL_PREFIX is sent in here as
649 // the value of the CPACK_INSTALL_PREFIX variable.
652 if (this->GetOption("CPACK_INSTALL_PREFIX"))
654 dir
+= this->GetOption("CPACK_INSTALL_PREFIX");
656 mf
->AddDefinition("CMAKE_INSTALL_PREFIX", dir
.c_str());
659 cmCPackLog::LOG_DEBUG
,
660 "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf->AddDefinition)"
662 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
663 "- Setting CMAKE_INSTALL_PREFIX to '" << dir
<< "'"
666 // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
669 if (cmSystemTools::StringStartsWith(dir
.c_str(), "/"))
671 dir
= tempInstallDirectory
+ dir
;
675 dir
= tempInstallDirectory
+ "/" + dir
;
678 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
679 "- Creating directory: '" << dir
<< "'" << std::endl
);
681 if ( !cmsys::SystemTools::MakeDirectory(dir
.c_str()))
683 cmCPackLogger(cmCPackLog::LOG_ERROR
,
684 "Problem creating temporary directory: "
685 << dir
<< std::endl
);
691 mf
->AddDefinition("CMAKE_INSTALL_PREFIX",
692 tempInstallDirectory
.c_str());
694 if ( !cmsys::SystemTools::MakeDirectory(
695 tempInstallDirectory
.c_str()))
697 cmCPackLogger(cmCPackLog::LOG_ERROR
,
698 "Problem creating temporary directory: "
699 << tempInstallDirectory
<< std::endl
);
703 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
704 "- Using non-DESTDIR install... (mf->AddDefinition)"
706 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
707 "- Setting CMAKE_INSTALL_PREFIX to '"
708 << tempInstallDirectory
709 << "'" << std::endl
);
712 if ( buildConfig
&& *buildConfig
)
714 mf
->AddDefinition("BUILD_TYPE", buildConfig
);
716 std::string installComponentLowerCase
717 = cmSystemTools::LowerCase(installComponent
);
718 if ( installComponentLowerCase
!= "all" )
720 mf
->AddDefinition("CMAKE_INSTALL_COMPONENT",
721 installComponent
.c_str());
724 // strip on TRUE, ON, 1, one or several file names, but not on
725 // FALSE, OFF, 0 and an empty string
726 if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES")))
728 mf
->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
730 int res
= mf
->ReadListFile(0, installFile
.c_str());
731 if ( cmSystemTools::GetErrorOccuredFlag() || !res
)
741 //----------------------------------------------------------------------
742 bool cmCPackGenerator::ReadListFile(const char* moduleName
)
744 std::string fullPath
= this->MakefileMap
->GetModulesFile(moduleName
);
745 return this->MakefileMap
->ReadListFile(0, fullPath
.c_str());
748 //----------------------------------------------------------------------
749 void cmCPackGenerator::SetOptionIfNotSet(const char* op
,
752 const char* def
= this->MakefileMap
->GetDefinition(op
);
757 this->SetOption(op
, value
);
760 //----------------------------------------------------------------------
761 void cmCPackGenerator::SetOption(const char* op
, const char* value
)
769 this->MakefileMap
->RemoveDefinition(op
);
772 cmCPackLogger(cmCPackLog::LOG_DEBUG
, this->GetNameOfClass()
773 << "::SetOption(" << op
<< ", " << value
<< ")" << std::endl
);
774 this->MakefileMap
->AddDefinition(op
, value
);
777 //----------------------------------------------------------------------
778 int cmCPackGenerator::DoPackage()
780 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
781 "Create package using " << this->Name
.c_str() << std::endl
);
783 if ( !this->PrepareNames() )
788 if ( cmSystemTools::IsOn(
789 this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) )
791 const char* toplevelDirectory
792 = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
793 if ( cmSystemTools::FileExists(toplevelDirectory
) )
795 cmCPackLogger(cmCPackLog::LOG_VERBOSE
,
796 "Remove toplevel directory: "
797 << toplevelDirectory
<< std::endl
);
798 if ( !cmSystemTools::RemoveADirectory(toplevelDirectory
) )
800 cmCPackLogger(cmCPackLog::LOG_ERROR
,
801 "Problem removing toplevel directory: "
808 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
809 "About to install project " << std::endl
);
811 if ( !this->InstallProject() )
815 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
816 "Done install project " << std::endl
);
819 const char* tempPackageFileName
= this->GetOption(
820 "CPACK_TEMPORARY_PACKAGE_FILE_NAME");
821 const char* packageFileName
= this->GetOption("CPACK_OUTPUT_FILE_PATH");
822 const char* tempDirectory
= this->GetOption("CPACK_TEMPORARY_DIRECTORY");
824 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "Find files" << std::endl
);
826 std::string findExpr
= tempDirectory
;
829 if ( !gl
.FindFiles(findExpr
) )
831 cmCPackLogger(cmCPackLog::LOG_ERROR
,
832 "Cannot find any files in the packaging tree" << std::endl
);
836 cmCPackLogger(cmCPackLog::LOG_OUTPUT
, "Compress package" << std::endl
);
837 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Compress files to: "
838 << (tempPackageFileName
? tempPackageFileName
: "(NULL)") << std::endl
);
839 if ( cmSystemTools::FileExists(tempPackageFileName
) )
841 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Remove old package file"
843 cmSystemTools::RemoveFile(tempPackageFileName
);
845 if ( cmSystemTools::IsOn(this->GetOption(
846 "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) )
848 tempDirectory
= this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
851 // The files to be installed
852 std::vector
<std::string
> files
= gl
.GetFiles();
854 // For component installations, determine which files go into which
856 if (!this->Components
.empty())
858 std::vector
<std::string
>::const_iterator it
;
859 for ( it
= files
.begin(); it
!= files
.end(); ++ it
)
861 std::string fileN
= cmSystemTools::RelativePath(tempDirectory
,
864 // Determine which component we are in.
865 std::string componentName
= fileN
.substr(0, fileN
.find('/'));
867 // Strip off the component part of the path.
868 fileN
= fileN
.substr(fileN
.find('/')+1, std::string::npos
);
870 // Add this file to the list of files for the component.
871 this->Components
[componentName
].Files
.push_back(fileN
);
875 if ( !this->CompressFiles(tempPackageFileName
,
876 tempDirectory
, files
) || cmSystemTools::GetErrorOccuredFlag())
878 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem compressing the directory"
883 cmCPackLogger(cmCPackLog::LOG_OUTPUT
, "Finalize package" << std::endl
);
884 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Copy final package: "
885 << (tempPackageFileName
? tempPackageFileName
: "(NULL)" )
887 << (packageFileName
? packageFileName
: "(NULL)")
889 if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName
,
892 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem copying the package: "
893 << (tempPackageFileName
? tempPackageFileName
: "(NULL)" )
895 << (packageFileName
? packageFileName
: "(NULL)")
900 cmCPackLogger(cmCPackLog::LOG_OUTPUT
, "Package "
901 << (packageFileName
? packageFileName
: "(NULL)")
902 << " generated." << std::endl
);
906 //----------------------------------------------------------------------
907 int cmCPackGenerator::Initialize(const char* name
, cmMakefile
* mf
)
909 this->MakefileMap
= mf
;
911 if ( !this->SetCMakeRoot() )
913 cmCPackLogger(cmCPackLog::LOG_ERROR
,
914 "Cannot initialize the generator" << std::endl
);
917 // set the running generator name
918 this->SetOption("CPACK_GENERATOR", this->Name
.c_str());
919 // Load the project specific config file
921 this->GetOption("CPACK_PROJECT_CONFIG_FILE");
924 mf
->ReadListFile(config
);
926 int result
= this->InitializeInternal();
927 if (cmSystemTools::GetErrorOccuredFlag())
932 // If a generator subclass did not already set this option in its
933 // InitializeInternal implementation, and the project did not already set
934 // it, the default value should be:
935 this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/");
940 //----------------------------------------------------------------------
941 int cmCPackGenerator::InitializeInternal()
946 //----------------------------------------------------------------------
947 bool cmCPackGenerator::IsSet(const char* name
) const
949 return this->MakefileMap
->IsSet(name
);
952 //----------------------------------------------------------------------
953 const char* cmCPackGenerator::GetOption(const char* op
)
955 const char* ret
= this->MakefileMap
->GetDefinition(op
);
958 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
959 "Warning, GetOption return NULL for: "
966 //----------------------------------------------------------------------
967 int cmCPackGenerator::SetCMakeRoot()
969 // use the CMAKE_ROOT from cmake which should have been
972 this->MakefileMap
->GetDefinition("CMAKE_ROOT");
976 this->CMakeRoot
= root
;
977 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "Looking for CMAKE_ROOT: "
978 << this->CMakeRoot
.c_str() << std::endl
);
979 this->SetOption("CMAKE_ROOT", this->CMakeRoot
.c_str());
982 cmCPackLogger(cmCPackLog::LOG_ERROR
,
983 "Could not find CMAKE_ROOT !!!"
985 << "CMake has most likely not been installed correctly."
987 <<"Modules directory not found in"
992 //----------------------------------------------------------------------
993 int cmCPackGenerator::CompressFiles(const char* outFileName
,
994 const char* toplevel
, const std::vector
<std::string
>& files
)
1002 //----------------------------------------------------------------------
1003 const char* cmCPackGenerator::GetInstallPath()
1005 if ( !this->InstallPath
.empty() )
1007 return this->InstallPath
.c_str();
1009 #if defined(_WIN32) && !defined(__CYGWIN__)
1010 const char* prgfiles
= cmsys::SystemTools::GetEnv("ProgramFiles");
1011 const char* sysDrive
= cmsys::SystemTools::GetEnv("SystemDrive");
1014 this->InstallPath
= prgfiles
;
1016 else if ( sysDrive
)
1018 this->InstallPath
= sysDrive
;
1019 this->InstallPath
+= "/Program Files";
1023 this->InstallPath
= "c:/Program Files";
1025 this->InstallPath
+= "/";
1026 this->InstallPath
+= this->GetOption("CPACK_PACKAGE_NAME");
1027 this->InstallPath
+= "-";
1028 this->InstallPath
+= this->GetOption("CPACK_PACKAGE_VERSION");
1030 this->InstallPath
= "/usr/local/";
1032 return this->InstallPath
.c_str();
1035 //----------------------------------------------------------------------
1036 const char* cmCPackGenerator::GetPackagingInstallPrefix()
1038 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "GetPackagingInstallPrefix: '"
1039 << this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX") << "'" << std::endl
);
1041 return this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
1044 //----------------------------------------------------------------------
1045 std::string
cmCPackGenerator::FindTemplate(const char* name
)
1047 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "Look for template: "
1048 << (name
? name
: "(NULL)") << std::endl
);
1049 std::string ffile
= this->MakefileMap
->GetModulesFile(name
);
1050 cmCPackLogger(cmCPackLog::LOG_DEBUG
, "Found template: "
1051 << ffile
.c_str() << std::endl
);
1055 //----------------------------------------------------------------------
1056 bool cmCPackGenerator::ConfigureString(const std::string
& inString
,
1057 std::string
& outString
)
1059 this->MakefileMap
->ConfigureString(inString
,
1060 outString
, true, false);
1064 //----------------------------------------------------------------------
1065 bool cmCPackGenerator::ConfigureFile(const char* inName
,
1066 const char* outName
, bool copyOnly
/* = false */)
1068 return this->MakefileMap
->ConfigureFile(inName
, outName
,
1069 copyOnly
, true, false) == 1;
1072 //----------------------------------------------------------------------
1073 int cmCPackGenerator::CleanTemporaryDirectory()
1075 std::string tempInstallDirectoryWithPostfix
1076 = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
1077 const char* tempInstallDirectory
= tempInstallDirectoryWithPostfix
.c_str();
1078 if(cmsys::SystemTools::FileExists(tempInstallDirectory
))
1080 cmCPackLogger(cmCPackLog::LOG_OUTPUT
,
1081 "- Clean temporary : "
1082 << tempInstallDirectory
<< std::endl
);
1083 if(!cmsys::SystemTools::RemoveADirectory(tempInstallDirectory
))
1085 cmCPackLogger(cmCPackLog::LOG_ERROR
,
1086 "Problem removing temporary directory: " <<
1087 tempInstallDirectory
1095 //----------------------------------------------------------------------
1096 bool cmCPackGenerator::SupportsComponentInstallation() const
1101 //----------------------------------------------------------------------
1102 cmCPackInstallationType
*
1103 cmCPackGenerator::GetInstallationType(const char *projectName
,
1107 bool hasInstallationType
= this->InstallationTypes
.count(name
) != 0;
1108 cmCPackInstallationType
*installType
= &this->InstallationTypes
[name
];
1109 if (!hasInstallationType
)
1111 // Define the installation type
1112 std::string macroPrefix
= "CPACK_INSTALL_TYPE_"
1113 + cmsys::SystemTools::UpperCase(name
);
1114 installType
->Name
= name
;
1116 const char* displayName
1117 = this->GetOption((macroPrefix
+ "_DISPLAY_NAME").c_str());
1118 if (displayName
&& *displayName
)
1120 installType
->DisplayName
= displayName
;
1124 installType
->DisplayName
= installType
->Name
;
1127 installType
->Index
= static_cast<unsigned>(
1128 this->InstallationTypes
.size());
1133 //----------------------------------------------------------------------
1135 cmCPackGenerator::GetComponent(const char *projectName
, const char *name
)
1137 bool hasComponent
= this->Components
.count(name
) != 0;
1138 cmCPackComponent
*component
= &this->Components
[name
];
1141 // Define the component
1142 std::string macroPrefix
= "CPACK_COMPONENT_"
1143 + cmsys::SystemTools::UpperCase(name
);
1144 component
->Name
= name
;
1145 const char* displayName
1146 = this->GetOption((macroPrefix
+ "_DISPLAY_NAME").c_str());
1147 if (displayName
&& *displayName
)
1149 component
->DisplayName
= displayName
;
1153 component
->DisplayName
= component
->Name
;
1156 = this->IsSet((macroPrefix
+ "_HIDDEN").c_str());
1157 component
->IsRequired
1158 = this->IsSet((macroPrefix
+ "_REQUIRED").c_str());
1159 component
->IsDisabledByDefault
1160 = this->IsSet((macroPrefix
+ "_DISABLED").c_str());
1161 component
->IsDownloaded
1162 = this->IsSet((macroPrefix
+ "_DOWNLOADED").c_str())
1163 || cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
1165 const char* archiveFile
= this->GetOption((macroPrefix
+
1166 "_ARCHIVE_FILE").c_str());
1167 if (archiveFile
&& *archiveFile
)
1169 component
->ArchiveFile
= archiveFile
;
1172 const char* groupName
= this->GetOption((macroPrefix
+ "_GROUP").c_str());
1173 if (groupName
&& *groupName
)
1175 component
->Group
= GetComponentGroup(projectName
, groupName
);
1176 component
->Group
->Components
.push_back(component
);
1180 component
->Group
= 0;
1183 const char* description
1184 = this->GetOption((macroPrefix
+ "_DESCRIPTION").c_str());
1185 if (description
&& *description
)
1187 component
->Description
= description
;
1190 // Determine the installation types.
1191 const char *installTypes
1192 = this->GetOption((macroPrefix
+ "_INSTALL_TYPES").c_str());
1193 if (installTypes
&& *installTypes
)
1195 std::vector
<std::string
> installTypesVector
;
1196 cmSystemTools::ExpandListArgument(installTypes
, installTypesVector
);
1197 std::vector
<std::string
>::iterator installTypesIt
;
1198 for (installTypesIt
= installTypesVector
.begin();
1199 installTypesIt
!= installTypesVector
.end();
1202 component
->InstallationTypes
.push_back(
1203 this->GetInstallationType(projectName
, installTypesIt
->c_str()));
1207 // Determine the component dependencies.
1208 const char *depends
= this->GetOption((macroPrefix
+ "_DEPENDS").c_str());
1209 if (depends
&& *depends
)
1211 std::vector
<std::string
> dependsVector
;
1212 cmSystemTools::ExpandListArgument(depends
, dependsVector
);
1213 std::vector
<std::string
>::iterator dependIt
;
1214 for (dependIt
= dependsVector
.begin();
1215 dependIt
!= dependsVector
.end();
1218 cmCPackComponent
*child
= GetComponent(projectName
,
1220 component
->Dependencies
.push_back(child
);
1221 child
->ReverseDependencies
.push_back(component
);
1228 //----------------------------------------------------------------------
1229 cmCPackComponentGroup
*
1230 cmCPackGenerator::GetComponentGroup(const char *projectName
, const char *name
)
1233 std::string macroPrefix
= "CPACK_COMPONENT_GROUP_"
1234 + cmsys::SystemTools::UpperCase(name
);
1235 bool hasGroup
= this->ComponentGroups
.count(name
) != 0;
1236 cmCPackComponentGroup
*group
= &this->ComponentGroups
[name
];
1241 const char* displayName
1242 = this->GetOption((macroPrefix
+ "_DISPLAY_NAME").c_str());
1243 if (displayName
&& *displayName
)
1245 group
->DisplayName
= displayName
;
1249 group
->DisplayName
= group
->Name
;
1252 const char* description
1253 = this->GetOption((macroPrefix
+ "_DESCRIPTION").c_str());
1254 if (description
&& *description
)
1256 group
->Description
= description
;
1259 = this->IsSet((macroPrefix
+ "_BOLD_TITLE").c_str());
1260 group
->IsExpandedByDefault
1261 = this->IsSet((macroPrefix
+ "_EXPANDED").c_str());
1262 const char* parentGroupName
1263 = this->GetOption((macroPrefix
+ "_PARENT_GROUP").c_str());
1264 if (parentGroupName
&& *parentGroupName
)
1266 group
->ParentGroup
= GetComponentGroup(projectName
, parentGroupName
);
1267 group
->ParentGroup
->Subgroups
.push_back(group
);
1271 group
->ParentGroup
= 0;