| /*============================================================================ |
| CMake - Cross Platform Makefile Generator |
| Copyright 2000-2009 Kitware, Inc., Insight Software Consortium |
| |
| Distributed under the OSI-approved BSD License (the "License"); |
| see accompanying file Copyright.txt for details. |
| |
| This software is distributed WITHOUT ANY WARRANTY; without even the |
| implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the License for more information. |
| ============================================================================*/ |
| |
| #include "cmCPackGenerator.h" |
| |
| #include "cmMakefile.h" |
| #include "cmCPackLog.h" |
| #include "cmake.h" |
| #include "cmGlobalGenerator.h" |
| #include "cmLocalGenerator.h" |
| #include "cmGeneratedFileStream.h" |
| #include "cmCPackComponentGroup.h" |
| #include "cmXMLSafe.h" |
| |
| #include <cmsys/SystemTools.hxx> |
| #include <cmsys/Glob.hxx> |
| #include <cmsys/FStream.hxx> |
| #include <algorithm> |
| #include <list> |
| |
| #if defined(__HAIKU__) |
| #include <FindDirectory.h> |
| #include <StorageDefs.h> |
| #endif |
| |
| //---------------------------------------------------------------------- |
| cmCPackGenerator::cmCPackGenerator() |
| { |
| this->GeneratorVerbose = cmSystemTools::OUTPUT_NONE; |
| this->MakefileMap = 0; |
| this->Logger = 0; |
| this->componentPackageMethod = ONE_PACKAGE_PER_GROUP; |
| } |
| |
| //---------------------------------------------------------------------- |
| cmCPackGenerator::~cmCPackGenerator() |
| { |
| this->MakefileMap = 0; |
| } |
| |
| //---------------------------------------------------------------------- |
| void cmCPackGeneratorProgress(const char *msg, float prog, void* ptr) |
| { |
| cmCPackGenerator* self = static_cast<cmCPackGenerator*>(ptr); |
| self->DisplayVerboseOutput(msg, prog); |
| } |
| |
| //---------------------------------------------------------------------- |
| void cmCPackGenerator::DisplayVerboseOutput(const char* msg, |
| float progress) |
| { |
| (void)progress; |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl); |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::PrepareNames() |
| { |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Create temp directory." << std::endl); |
| |
| // checks CPACK_SET_DESTDIR support |
| if (IsOn("CPACK_SET_DESTDIR")) |
| { |
| if (SETDESTDIR_UNSUPPORTED==SupportsSetDestdir()) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "CPACK_SET_DESTDIR is set to ON but the '" |
| << Name << "' generator does NOT support it." |
| << std::endl); |
| return 0; |
| } |
| else if (SETDESTDIR_SHOULD_NOT_BE_USED==SupportsSetDestdir()) |
| { |
| cmCPackLogger(cmCPackLog::LOG_WARNING, |
| "CPACK_SET_DESTDIR is set to ON but it is " |
| << "usually a bad idea to do that with '" |
| << Name << "' generator. Use at your own risk." |
| << std::endl); |
| } |
| } |
| |
| std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY"); |
| tempDirectory += "/_CPack_Packages/"; |
| const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG"); |
| if ( toplevelTag ) |
| { |
| tempDirectory += toplevelTag; |
| tempDirectory += "/"; |
| } |
| tempDirectory += this->GetOption("CPACK_GENERATOR"); |
| std::string topDirectory = tempDirectory; |
| const char* pfname = this->GetOption("CPACK_PACKAGE_FILE_NAME"); |
| if(!pfname) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "CPACK_PACKAGE_FILE_NAME not specified" << std::endl); |
| return 0; |
| } |
| std::string outName = pfname; |
| tempDirectory += "/" + outName; |
| if(!this->GetOutputExtension()) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "No output extension specified" << std::endl); |
| return 0; |
| } |
| outName += this->GetOutputExtension(); |
| const char* pdir = this->GetOption("CPACK_PACKAGE_DIRECTORY"); |
| if(!pdir) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "CPACK_PACKAGE_DIRECTORY not specified" << std::endl); |
| return 0; |
| } |
| |
| std::string destFile = pdir; |
| this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PREFIX", destFile.c_str()); |
| destFile += "/" + outName; |
| std::string outFile = topDirectory + "/" + outName; |
| this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory.c_str()); |
| this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory.c_str()); |
| this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName.c_str()); |
| this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile.c_str()); |
| this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME", |
| outFile.c_str()); |
| this->SetOptionIfNotSet("CPACK_INSTALL_DIRECTORY", this->GetInstallPath()); |
| this->SetOptionIfNotSet("CPACK_NATIVE_INSTALL_DIRECTORY", |
| cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath()).c_str()); |
| this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY", |
| tempDirectory.c_str()); |
| |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl); |
| const char* descFileName |
| = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE"); |
| if ( descFileName ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Look for: " << descFileName << std::endl); |
| if ( !cmSystemTools::FileExists(descFileName) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Cannot find description file name: [" |
| << descFileName << "]" << std::endl); |
| return 0; |
| } |
| cmsys::ifstream ifs(descFileName); |
| if ( !ifs ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Cannot open description file name: " << descFileName << std::endl); |
| return 0; |
| } |
| std::ostringstream ostr; |
| std::string line; |
| |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, |
| "Read description file: " << descFileName << std::endl); |
| while ( ifs && cmSystemTools::GetLineFromStream(ifs, line) ) |
| { |
| ostr << cmXMLSafe(line) << std::endl; |
| } |
| this->SetOptionIfNotSet("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str()); |
| } |
| if ( !this->GetOption("CPACK_PACKAGE_DESCRIPTION") ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Project description not specified. Please specify " |
| "CPACK_PACKAGE_DESCRIPTION or CPACK_PACKAGE_DESCRIPTION_FILE." |
| << std::endl); |
| return 0; |
| } |
| |
| this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1"); |
| |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::InstallProject() |
| { |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Install projects" << std::endl); |
| this->CleanTemporaryDirectory(); |
| |
| std::string bareTempInstallDirectory |
| = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); |
| std::string tempInstallDirectoryStr = bareTempInstallDirectory; |
| bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR")) |
| | cmSystemTools::IsInternallyOn( |
| this->GetOption("CPACK_SET_DESTDIR")); |
| if (!setDestDir) |
| { |
| tempInstallDirectoryStr += this->GetPackagingInstallPrefix(); |
| } |
| |
| const char* tempInstallDirectory = tempInstallDirectoryStr.c_str(); |
| int res = 1; |
| if ( !cmsys::SystemTools::MakeDirectory(bareTempInstallDirectory.c_str())) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem creating temporary directory: " |
| << (tempInstallDirectory ? tempInstallDirectory : "(NULL)") |
| << std::endl); |
| return 0; |
| } |
| |
| if ( setDestDir ) |
| { |
| std::string destDir = "DESTDIR="; |
| destDir += tempInstallDirectory; |
| cmSystemTools::PutEnv(destDir); |
| } |
| else |
| { |
| // Make sure there is no destdir |
| cmSystemTools::PutEnv("DESTDIR="); |
| } |
| |
| // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them |
| // as listed |
| if ( !this->InstallProjectViaInstallCommands( |
| setDestDir, tempInstallDirectory) ) |
| { |
| return 0; |
| } |
| |
| // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them |
| // as listed |
| if ( !this->InstallProjectViaInstallScript( |
| setDestDir, tempInstallDirectory) ) |
| { |
| return 0; |
| } |
| |
| // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES |
| // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY |
| // This is used in Source packaging |
| if ( !this->InstallProjectViaInstalledDirectories( |
| setDestDir, tempInstallDirectory) ) |
| { |
| return 0; |
| } |
| |
| |
| // If the project is a CMAKE project then run pre-install |
| // and then read the cmake_install script to run it |
| if ( !this->InstallProjectViaInstallCMakeProjects( |
| setDestDir, bareTempInstallDirectory) ) |
| { |
| return 0; |
| } |
| |
| if ( setDestDir ) |
| { |
| cmSystemTools::PutEnv("DESTDIR="); |
| } |
| |
| return res; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::InstallProjectViaInstallCommands( |
| bool setDestDir, const std::string& tempInstallDirectory) |
| { |
| (void) setDestDir; |
| const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS"); |
| if ( installCommands && *installCommands ) |
| { |
| std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX="; |
| tempInstallDirectoryEnv += tempInstallDirectory; |
| cmSystemTools::PutEnv(tempInstallDirectoryEnv); |
| std::vector<std::string> installCommandsVector; |
| cmSystemTools::ExpandListArgument(installCommands,installCommandsVector); |
| std::vector<std::string>::iterator it; |
| for ( it = installCommandsVector.begin(); |
| it != installCommandsVector.end(); |
| ++it ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << *it |
| << std::endl); |
| std::string output; |
| int retVal = 1; |
| bool resB = cmSystemTools::RunSingleCommand( |
| it->c_str(), &output, &output, |
| &retVal, 0, this->GeneratorVerbose, 0); |
| if ( !resB || retVal ) |
| { |
| std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); |
| tmpFile += "/InstallOutput.log"; |
| cmGeneratedFileStream ofs(tmpFile.c_str()); |
| ofs << "# Run command: " << *it << std::endl |
| << "# Output:" << std::endl |
| << output << std::endl; |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem running install command: " << *it << std::endl |
| << "Please check " << tmpFile << " for errors" |
| << std::endl); |
| return 0; |
| } |
| } |
| } |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::InstallProjectViaInstalledDirectories( |
| bool setDestDir, const std::string& tempInstallDirectory) |
| { |
| (void)setDestDir; |
| (void)tempInstallDirectory; |
| std::vector<cmsys::RegularExpression> ignoreFilesRegex; |
| const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES"); |
| if ( cpackIgnoreFiles ) |
| { |
| std::vector<std::string> ignoreFilesRegexString; |
| cmSystemTools::ExpandListArgument(cpackIgnoreFiles, |
| ignoreFilesRegexString); |
| std::vector<std::string>::iterator it; |
| for ( it = ignoreFilesRegexString.begin(); |
| it != ignoreFilesRegexString.end(); |
| ++it ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, |
| "Create ignore files regex for: " << *it << std::endl); |
| ignoreFilesRegex.push_back(it->c_str()); |
| } |
| } |
| const char* installDirectories |
| = this->GetOption("CPACK_INSTALLED_DIRECTORIES"); |
| if ( installDirectories && *installDirectories ) |
| { |
| std::vector<std::string> installDirectoriesVector; |
| cmSystemTools::ExpandListArgument(installDirectories, |
| installDirectoriesVector); |
| if ( installDirectoriesVector.size() % 2 != 0 ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and " |
| "<subdirectory>. The <subdirectory> can be '.' to be installed in " |
| "the toplevel directory of installation." << std::endl); |
| return 0; |
| } |
| std::vector<std::string>::iterator it; |
| const std::string& tempDir = tempInstallDirectory; |
| for ( it = installDirectoriesVector.begin(); |
| it != installDirectoriesVector.end(); |
| ++it ) |
| { |
| std::list<std::pair<std::string,std::string> > symlinkedFiles; |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl); |
| cmsys::Glob gl; |
| std::string top = *it; |
| it ++; |
| std::string subdir = *it; |
| std::string findExpr = top; |
| findExpr += "/*"; |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Install directory: " << top << std::endl); |
| gl.RecurseOn(); |
| if ( !gl.FindFiles(findExpr) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Cannot find any files in the installed directory" << std::endl); |
| return 0; |
| } |
| files = gl.GetFiles(); |
| std::vector<std::string>::iterator gfit; |
| std::vector<cmsys::RegularExpression>::iterator regIt; |
| for ( gfit = files.begin(); gfit != files.end(); ++ gfit ) |
| { |
| bool skip = false; |
| std::string &inFile = *gfit; |
| for ( regIt= ignoreFilesRegex.begin(); |
| regIt!= ignoreFilesRegex.end(); |
| ++ regIt) |
| { |
| if ( regIt->find(inFile.c_str()) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Ignore file: " |
| << inFile << std::endl); |
| skip = true; |
| } |
| } |
| if ( skip ) |
| { |
| continue; |
| } |
| std::string filePath = tempDir; |
| filePath += "/" + subdir + "/" |
| + cmSystemTools::RelativePath(top.c_str(), gfit->c_str()); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: " |
| << inFile << " -> " << filePath << std::endl); |
| /* If the file is a symlink we will have to re-create it */ |
| if ( cmSystemTools::FileIsSymlink(inFile)) |
| { |
| std::string targetFile; |
| std::string inFileRelative = |
| cmSystemTools::RelativePath(top.c_str(),inFile.c_str()); |
| cmSystemTools::ReadSymlink(inFile,targetFile); |
| symlinkedFiles.push_back(std::pair<std::string, |
| std::string>(targetFile,inFileRelative)); |
| } |
| /* If it is not a symlink then do a plain copy */ |
| else if (!( |
| cmSystemTools::CopyFileIfDifferent(inFile.c_str(),filePath.c_str()) |
| && |
| cmSystemTools::CopyFileTime(inFile.c_str(),filePath.c_str()) |
| ) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying file: " |
| << inFile << " -> " << filePath << std::endl); |
| return 0; |
| } |
| } |
| /* rebuild symlinks in the installed tree */ |
| if (!symlinkedFiles.empty()) |
| { |
| std::list< std::pair<std::string,std::string> >::iterator symlinkedIt; |
| std::string curDir = cmSystemTools::GetCurrentWorkingDirectory(); |
| std::string goToDir = tempDir; |
| goToDir += "/"+subdir; |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Change dir to: " << goToDir <<std::endl); |
| cmSystemTools::ChangeDirectory(goToDir); |
| for (symlinkedIt=symlinkedFiles.begin(); |
| symlinkedIt != symlinkedFiles.end(); |
| ++symlinkedIt) |
| { |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: " |
| << symlinkedIt->second << "--> " |
| << symlinkedIt->first << std::endl); |
| // make sure directory exists for symlink |
| std::string destDir = |
| cmSystemTools::GetFilenamePath(symlinkedIt->second); |
| if(!destDir.empty() && !cmSystemTools::MakeDirectory(destDir)) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create dir: " |
| << destDir |
| << "\nTrying to create symlink: " |
| << symlinkedIt->second << "--> " |
| << symlinkedIt->first |
| << std::endl); |
| } |
| if (!cmSystemTools::CreateSymlink(symlinkedIt->first, |
| symlinkedIt->second)) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create symlink: " |
| << symlinkedIt->second << "--> " |
| << symlinkedIt->first << std::endl); |
| return 0; |
| } |
| } |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Going back to: " |
| << curDir <<std::endl); |
| cmSystemTools::ChangeDirectory(curDir); |
| } |
| } |
| } |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::InstallProjectViaInstallScript( |
| bool setDestDir, const std::string& tempInstallDirectory) |
| { |
| const char* cmakeScripts |
| = this->GetOption("CPACK_INSTALL_SCRIPT"); |
| if ( cmakeScripts && *cmakeScripts ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Install scripts: " << cmakeScripts << std::endl); |
| std::vector<std::string> cmakeScriptsVector; |
| cmSystemTools::ExpandListArgument(cmakeScripts, |
| cmakeScriptsVector); |
| std::vector<std::string>::iterator it; |
| for ( it = cmakeScriptsVector.begin(); |
| it != cmakeScriptsVector.end(); |
| ++it ) |
| { |
| std::string installScript = *it; |
| |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Install script: " << installScript << std::endl); |
| |
| if ( setDestDir ) |
| { |
| // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX |
| // underneath the tempInstallDirectory. The value of the project's |
| // CMAKE_INSTALL_PREFIX is sent in here as the value of the |
| // CPACK_INSTALL_PREFIX variable. |
| |
| std::string dir; |
| if (this->GetOption("CPACK_INSTALL_PREFIX")) |
| { |
| dir += this->GetOption("CPACK_INSTALL_PREFIX"); |
| } |
| this->SetOption("CMAKE_INSTALL_PREFIX", dir.c_str()); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Using DESTDIR + CPACK_INSTALL_PREFIX... (this->SetOption)" |
| << std::endl); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" << std::endl); |
| } |
| else |
| { |
| this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str()); |
| |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Using non-DESTDIR install... (this->SetOption)" << std::endl); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Setting CMAKE_INSTALL_PREFIX to '" << tempInstallDirectory |
| << "'" << std::endl); |
| } |
| |
| this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR", |
| tempInstallDirectory.c_str()); |
| this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR", |
| tempInstallDirectory.c_str()); |
| int res = this->MakefileMap->ReadListFile(installScript.c_str()); |
| if ( cmSystemTools::GetErrorOccuredFlag() || !res ) |
| { |
| return 0; |
| } |
| } |
| } |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( |
| bool setDestDir, const std::string& baseTempInstallDirectory) |
| { |
| const char* cmakeProjects |
| = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); |
| const char* cmakeGenerator |
| = this->GetOption("CPACK_CMAKE_GENERATOR"); |
| std::string absoluteDestFiles; |
| if ( cmakeProjects && *cmakeProjects ) |
| { |
| if ( !cmakeGenerator ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "CPACK_INSTALL_CMAKE_PROJECTS is specified, but " |
| "CPACK_CMAKE_GENERATOR is not. CPACK_CMAKE_GENERATOR " |
| "is required to install the project." |
| << std::endl); |
| return 0; |
| } |
| std::vector<std::string> cmakeProjectsVector; |
| cmSystemTools::ExpandListArgument(cmakeProjects, |
| cmakeProjectsVector); |
| std::vector<std::string>::iterator it; |
| for ( it = cmakeProjectsVector.begin(); |
| it != cmakeProjectsVector.end(); |
| ++it ) |
| { |
| if ( it+1 == cmakeProjectsVector.end() || |
| it+2 == cmakeProjectsVector.end() || |
| it+3 == cmakeProjectsVector.end() ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. " |
| "CPACK_INSTALL_CMAKE_PROJECTS should hold quadruplet of install " |
| "directory, install project name, install component, and install " |
| "subdirectory." |
| << std::endl); |
| return 0; |
| } |
| std::string installDirectory = *it; |
| ++it; |
| std::string installProjectName = *it; |
| ++it; |
| std::string installComponent = *it; |
| ++it; |
| std::string installSubDirectory = *it; |
| std::string installFile = installDirectory + "/cmake_install.cmake"; |
| |
| std::vector<std::string> componentsVector; |
| |
| bool componentInstall = false; |
| /* |
| * We do a component install iff |
| * - the CPack generator support component |
| * - the user did not request Monolithic install |
| * (this works at CPack time too) |
| */ |
| if (this->SupportsComponentInstallation() & |
| !(this->IsOn("CPACK_MONOLITHIC_INSTALL"))) |
| { |
| // Determine the installation types for this project (if provided). |
| std::string installTypesVar = "CPACK_" |
| + cmSystemTools::UpperCase(installComponent) + "_INSTALL_TYPES"; |
| const char *installTypes = this->GetOption(installTypesVar); |
| if (installTypes && *installTypes) |
| { |
| std::vector<std::string> installTypesVector; |
| cmSystemTools::ExpandListArgument(installTypes, installTypesVector); |
| std::vector<std::string>::iterator installTypeIt; |
| for (installTypeIt = installTypesVector.begin(); |
| installTypeIt != installTypesVector.end(); |
| ++installTypeIt) |
| { |
| this->GetInstallationType(installProjectName, |
| *installTypeIt); |
| } |
| } |
| |
| // Determine the set of components that will be used in this project |
| std::string componentsVar |
| = "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent); |
| const char *components = this->GetOption(componentsVar); |
| if (components && *components) |
| { |
| cmSystemTools::ExpandListArgument(components, componentsVector); |
| std::vector<std::string>::iterator compIt; |
| for (compIt = componentsVector.begin(); |
| compIt != componentsVector.end(); |
| ++compIt) |
| { |
| GetComponent(installProjectName, *compIt); |
| } |
| componentInstall = true; |
| } |
| } |
| if (componentsVector.empty()) |
| { |
| componentsVector.push_back(installComponent); |
| } |
| |
| const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG"); |
| std::string buildConfig = buildConfigCstr ? buildConfigCstr : ""; |
| cmGlobalGenerator* globalGenerator |
| = this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator( |
| cmakeGenerator); |
| if ( !globalGenerator ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Specified package generator not found. " |
| "CPACK_CMAKE_GENERATOR value is invalid." |
| << std::endl); |
| return 0; |
| } |
| // set the global flag for unix style paths on cmSystemTools as |
| // soon as the generator is set. This allows gmake to be used |
| // on windows. |
| cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths()); |
| |
| // Does this generator require pre-install? |
| if (const char* preinstall = globalGenerator->GetPreinstallTargetName()) |
| { |
| std::string buildCommand = |
| globalGenerator->GenerateCMakeBuildCommand( |
| preinstall, buildConfig, "", false); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Install command: " << buildCommand << std::endl); |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Run preinstall target for: " << installProjectName << std::endl); |
| std::string output; |
| int retVal = 1; |
| bool resB = |
| cmSystemTools::RunSingleCommand(buildCommand.c_str(), |
| &output, &output, |
| &retVal, |
| installDirectory.c_str(), |
| this->GeneratorVerbose, 0); |
| if ( !resB || retVal ) |
| { |
| std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); |
| tmpFile += "/PreinstallOutput.log"; |
| cmGeneratedFileStream ofs(tmpFile.c_str()); |
| ofs << "# Run command: " << buildCommand << std::endl |
| << "# Directory: " << installDirectory << std::endl |
| << "# Output:" << std::endl |
| << output << std::endl; |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem running install command: " << buildCommand |
| << std::endl |
| << "Please check " << tmpFile << " for errors" |
| << std::endl); |
| return 0; |
| } |
| } |
| delete globalGenerator; |
| |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Install project: " << installProjectName << std::endl); |
| |
| // Run the installation for each component |
| std::vector<std::string>::iterator componentIt; |
| for (componentIt = componentsVector.begin(); |
| componentIt != componentsVector.end(); |
| ++componentIt) |
| { |
| std::string tempInstallDirectory = baseTempInstallDirectory; |
| installComponent = *componentIt; |
| if (componentInstall) |
| { |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Install component: " << installComponent |
| << std::endl); |
| } |
| |
| cmake cm; |
| cm.SetHomeDirectory(""); |
| cm.SetHomeOutputDirectory(""); |
| cm.AddCMakePaths(); |
| cm.SetProgressCallback(cmCPackGeneratorProgress, this); |
| cmGlobalGenerator gg(&cm); |
| cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator()); |
| cmMakefile *mf = lg->GetMakefile(); |
| std::string realInstallDirectory = tempInstallDirectory; |
| if ( !installSubDirectory.empty() && installSubDirectory != "/" ) |
| { |
| realInstallDirectory += installSubDirectory; |
| } |
| if (componentInstall) |
| { |
| tempInstallDirectory += "/"; |
| // Some CPack generators would rather chose |
| // the local installation directory suffix. |
| // Some (e.g. RPM) use |
| // one install directory for each component **GROUP** |
| // instead of the default |
| // one install directory for each component. |
| tempInstallDirectory += |
| GetComponentInstallDirNameSuffix(installComponent); |
| if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) |
| { |
| tempInstallDirectory += "/"; |
| tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME"); |
| } |
| } |
| |
| if (!setDestDir) |
| { |
| tempInstallDirectory += this->GetPackagingInstallPrefix(); |
| } |
| |
| if ( setDestDir ) |
| { |
| // For DESTDIR based packaging, use the *project* |
| // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The |
| // value of the project's CMAKE_INSTALL_PREFIX is sent in here as |
| // the value of the CPACK_INSTALL_PREFIX variable. |
| // |
| // If DESTDIR has been 'internally set ON' this means that |
| // the underlying CPack specific generator did ask for that |
| // In this case we may override CPACK_INSTALL_PREFIX with |
| // CPACK_PACKAGING_INSTALL_PREFIX |
| // I know this is tricky and awkward but it's the price for |
| // CPACK_SET_DESTDIR backward compatibility. |
| if (cmSystemTools::IsInternallyOn( |
| this->GetOption("CPACK_SET_DESTDIR"))) |
| { |
| this->SetOption("CPACK_INSTALL_PREFIX", |
| this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")); |
| } |
| std::string dir; |
| if (this->GetOption("CPACK_INSTALL_PREFIX")) |
| { |
| dir += this->GetOption("CPACK_INSTALL_PREFIX"); |
| } |
| mf->AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str()); |
| |
| cmCPackLogger( |
| cmCPackLog::LOG_DEBUG, |
| "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf->AddDefinition)" |
| << std::endl); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" |
| << std::endl); |
| |
| // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory |
| // exists: |
| // |
| if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) |
| { |
| dir = tempInstallDirectory + dir; |
| } |
| else |
| { |
| dir = tempInstallDirectory + "/" + dir; |
| } |
| /* |
| * We must re-set DESTDIR for each component |
| * We must not add the CPACK_INSTALL_PREFIX part because |
| * it will be added using the override of CMAKE_INSTALL_PREFIX |
| * The main reason for this awkward trick is that |
| * are using DESTDIR for 2 different reasons: |
| * - Because it was asked by the CPack Generator or the user |
| * using CPACK_SET_DESTDIR |
| * - Because it was already used for component install |
| * in order to put things in subdirs... |
| */ |
| cmSystemTools::PutEnv( |
| std::string("DESTDIR=")+tempInstallDirectory |
| ); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Creating directory: '" << dir << "'" << std::endl); |
| |
| if ( !cmsys::SystemTools::MakeDirectory(dir.c_str())) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem creating temporary directory: " |
| << dir << std::endl); |
| return 0; |
| } |
| } |
| else |
| { |
| mf->AddDefinition("CMAKE_INSTALL_PREFIX", |
| tempInstallDirectory.c_str()); |
| |
| if ( !cmsys::SystemTools::MakeDirectory( |
| tempInstallDirectory.c_str())) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem creating temporary directory: " |
| << tempInstallDirectory << std::endl); |
| return 0; |
| } |
| |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Using non-DESTDIR install... (mf->AddDefinition)" |
| << std::endl); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "- Setting CMAKE_INSTALL_PREFIX to '" |
| << tempInstallDirectory |
| << "'" << std::endl); |
| } |
| |
| if (!buildConfig.empty()) |
| { |
| mf->AddDefinition("BUILD_TYPE", buildConfig.c_str()); |
| } |
| std::string installComponentLowerCase |
| = cmSystemTools::LowerCase(installComponent); |
| if ( installComponentLowerCase != "all" ) |
| { |
| mf->AddDefinition("CMAKE_INSTALL_COMPONENT", |
| installComponent.c_str()); |
| } |
| |
| // strip on TRUE, ON, 1, one or several file names, but not on |
| // FALSE, OFF, 0 and an empty string |
| if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) |
| { |
| mf->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1"); |
| } |
| // Remember the list of files before installation |
| // of the current component (if we are in component install) |
| const char* InstallPrefix = tempInstallDirectory.c_str(); |
| std::vector<std::string> filesBefore; |
| std::string findExpr(InstallPrefix); |
| if (componentInstall) |
| { |
| cmsys::Glob glB; |
| findExpr += "/*"; |
| glB.RecurseOn(); |
| glB.FindFiles(findExpr); |
| filesBefore = glB.GetFiles(); |
| std::sort(filesBefore.begin(),filesBefore.end()); |
| } |
| |
| // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION |
| // then forward request to cmake_install.cmake script |
| if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) |
| { |
| mf->AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", |
| "1"); |
| } |
| // If current CPack generator does support |
| // ABSOLUTE INSTALL DESTINATION or CPack has been asked for |
| // then ask cmake_install.cmake script to error out |
| // as soon as it occurs (before installing file) |
| if (!SupportsAbsoluteDestination() || |
| this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) |
| { |
| mf->AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", |
| "1"); |
| } |
| // do installation |
| int res = mf->ReadListFile(installFile.c_str()); |
| // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES |
| // to CPack (may be used by generators like CPack RPM or DEB) |
| // in order to transparently handle ABSOLUTE PATH |
| if (mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) |
| { |
| mf->AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", |
| mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")); |
| } |
| |
| // Now rebuild the list of files after installation |
| // of the current component (if we are in component install) |
| if (componentInstall) |
| { |
| cmsys::Glob glA; |
| glA.RecurseOn(); |
| glA.FindFiles(findExpr); |
| std::vector<std::string> filesAfter = glA.GetFiles(); |
| std::sort(filesAfter.begin(),filesAfter.end()); |
| std::vector<std::string>::iterator diff; |
| std::vector<std::string> result(filesAfter.size()); |
| diff = std::set_difference ( |
| filesAfter.begin(),filesAfter.end(), |
| filesBefore.begin(),filesBefore.end(), |
| result.begin()); |
| |
| std::vector<std::string>::iterator fit; |
| std::string localFileName; |
| // Populate the File field of each component |
| for (fit=result.begin();fit!=diff;++fit) |
| { |
| localFileName = |
| cmSystemTools::RelativePath(InstallPrefix, fit->c_str()); |
| localFileName = |
| localFileName.substr(localFileName.find_first_not_of('/'), |
| std::string::npos); |
| Components[installComponent].Files.push_back(localFileName); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" |
| <<localFileName<<"> to component <" |
| <<installComponent<<">"<<std::endl); |
| } |
| } |
| |
| if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { |
| if (!absoluteDestFiles.empty()) { |
| absoluteDestFiles +=";"; |
| } |
| absoluteDestFiles += |
| mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Got some ABSOLUTE DESTINATION FILES: " |
| << absoluteDestFiles << std::endl); |
| // define component specific var |
| if (componentInstall) |
| { |
| std::string absoluteDestFileComponent = |
| std::string("CPACK_ABSOLUTE_DESTINATION_FILES") |
| + "_" + GetComponentInstallDirNameSuffix(installComponent); |
| if (NULL != this->GetOption(absoluteDestFileComponent)) |
| { |
| std::string absoluteDestFilesListComponent = |
| this->GetOption(absoluteDestFileComponent); |
| absoluteDestFilesListComponent +=";"; |
| absoluteDestFilesListComponent += |
| mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); |
| this->SetOption(absoluteDestFileComponent, |
| absoluteDestFilesListComponent.c_str()); |
| } |
| else |
| { |
| this->SetOption(absoluteDestFileComponent, |
| mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")); |
| } |
| } |
| } |
| if ( cmSystemTools::GetErrorOccuredFlag() || !res ) |
| { |
| return 0; |
| } |
| } |
| } |
| } |
| this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES", |
| absoluteDestFiles.c_str()); |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::ReadListFile(const char* moduleName) |
| { |
| bool retval; |
| std::string fullPath = this->MakefileMap->GetModulesFile(moduleName); |
| retval = this->MakefileMap->ReadListFile(fullPath.c_str()); |
| // include FATAL_ERROR and ERROR in the return status |
| retval = retval && (! cmSystemTools::GetErrorOccuredFlag()); |
| return retval; |
| } |
| |
| //---------------------------------------------------------------------- |
| void cmCPackGenerator::SetOptionIfNotSet(const std::string& op, |
| const char* value) |
| { |
| const char* def = this->MakefileMap->GetDefinition(op); |
| if ( def && *def ) |
| { |
| return; |
| } |
| this->SetOption(op, value); |
| } |
| |
| //---------------------------------------------------------------------- |
| void cmCPackGenerator::SetOption(const std::string& op, const char* value) |
| { |
| if ( !value ) |
| { |
| this->MakefileMap->RemoveDefinition(op); |
| return; |
| } |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, this->GetNameOfClass() |
| << "::SetOption(" << op << ", " << value << ")" << std::endl); |
| this->MakefileMap->AddDefinition(op, value); |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::DoPackage() |
| { |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "Create package using " << this->Name << std::endl); |
| |
| // Prepare CPack internal name and check |
| // values for many CPACK_xxx vars |
| if ( !this->PrepareNames() ) |
| { |
| return 0; |
| } |
| |
| // Digest Component grouping specification |
| if ( !this->PrepareGroupingKind() ) |
| { |
| return 0; |
| } |
| |
| if ( cmSystemTools::IsOn( |
| this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) ) |
| { |
| const char* toplevelDirectory |
| = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); |
| if ( cmSystemTools::FileExists(toplevelDirectory) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, |
| "Remove toplevel directory: " |
| << toplevelDirectory << std::endl); |
| if ( !cmSystemTools::RepeatedRemoveDirectory(toplevelDirectory) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem removing toplevel directory: " |
| << toplevelDirectory |
| << std::endl); |
| return 0; |
| } |
| } |
| } |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "About to install project " << std::endl); |
| |
| if ( !this->InstallProject() ) |
| { |
| return 0; |
| } |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Done install project " << std::endl); |
| |
| |
| const char* tempPackageFileName = this->GetOption( |
| "CPACK_TEMPORARY_PACKAGE_FILE_NAME"); |
| const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); |
| |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl); |
| cmsys::Glob gl; |
| std::string findExpr = tempDirectory; |
| findExpr += "/*"; |
| gl.RecurseOn(); |
| gl.SetRecurseThroughSymlinks(false); |
| if ( !gl.FindFiles(findExpr) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Cannot find any files in the packaging tree" << std::endl); |
| return 0; |
| } |
| |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package" << std::endl); |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Package files to: " |
| << (tempPackageFileName ? tempPackageFileName : "(NULL)") << std::endl); |
| if ( cmSystemTools::FileExists(tempPackageFileName) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove old package file" |
| << std::endl); |
| cmSystemTools::RemoveFile(tempPackageFileName); |
| } |
| if ( cmSystemTools::IsOn(this->GetOption( |
| "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) ) |
| { |
| tempDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); |
| } |
| |
| // The files to be installed |
| files = gl.GetFiles(); |
| |
| packageFileNames.clear(); |
| /* Put at least one file name into the list of |
| * wanted packageFileNames. The specific generator |
| * may update this during PackageFiles. |
| * (either putting several names or updating the provided one) |
| */ |
| packageFileNames.push_back(tempPackageFileName ? tempPackageFileName : ""); |
| toplevel = tempDirectory; |
| if ( !this->PackageFiles() || cmSystemTools::GetErrorOccuredFlag()) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory" |
| << std::endl); |
| return 0; |
| } |
| |
| /* |
| * Copy the generated packages to final destination |
| * - there may be several of them |
| * - the initially provided name may have changed |
| * (because the specific generator did 'normalize' it) |
| */ |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copying final package(s) [" |
| <<packageFileNames.size() |
| <<"]:"<<std::endl); |
| std::vector<std::string>::iterator it; |
| /* now copy package one by one */ |
| for (it=packageFileNames.begin();it!=packageFileNames.end();++it) |
| { |
| std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX")); |
| tempPackageFileName = it->c_str(); |
| tmpPF += "/"+cmSystemTools::GetFilenameName(*it); |
| const char* packageFileName = tmpPF.c_str(); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): " |
| << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) |
| << " to " |
| << (packageFileName ? packageFileName : "(NULL)") |
| << std::endl); |
| if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName, |
| packageFileName) ) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: " |
| << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) |
| << " to " |
| << (packageFileName ? packageFileName : "(NULL)") |
| << std::endl); |
| return 0; |
| } |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- package: " |
| << packageFileName |
| << " generated." << std::endl); |
| } |
| |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::Initialize(const std::string& name, cmMakefile* mf) |
| { |
| this->MakefileMap = mf; |
| this->Name = name; |
| // set the running generator name |
| this->SetOption("CPACK_GENERATOR", this->Name.c_str()); |
| // Load the project specific config file |
| const char* config = |
| this->GetOption("CPACK_PROJECT_CONFIG_FILE"); |
| if(config) |
| { |
| mf->ReadListFile(config); |
| } |
| int result = this->InitializeInternal(); |
| if (cmSystemTools::GetErrorOccuredFlag()) |
| { |
| return 0; |
| } |
| |
| // If a generator subclass did not already set this option in its |
| // InitializeInternal implementation, and the project did not already set |
| // it, the default value should be: |
| this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/"); |
| |
| return result; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::InitializeInternal() |
| { |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::IsSet(const std::string& name) const |
| { |
| return this->MakefileMap->IsSet(name); |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::IsOn(const std::string& name) const |
| { |
| return cmSystemTools::IsOn(GetOption(name)); |
| } |
| |
| //---------------------------------------------------------------------- |
| const char* cmCPackGenerator::GetOption(const std::string& op) const |
| { |
| const char* ret = this->MakefileMap->GetDefinition(op); |
| if(!ret) |
| { |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, |
| "Warning, GetOption return NULL for: " |
| << op |
| << std::endl); |
| } |
| return ret; |
| } |
| |
| //---------------------------------------------------------------------- |
| std::vector<std::string> cmCPackGenerator::GetOptions() const |
| { |
| return this->MakefileMap->GetDefinitions(); |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::PackageFiles() |
| { |
| return 0; |
| } |
| |
| //---------------------------------------------------------------------- |
| const char* cmCPackGenerator::GetInstallPath() |
| { |
| if ( !this->InstallPath.empty() ) |
| { |
| return this->InstallPath.c_str(); |
| } |
| #if defined(_WIN32) && !defined(__CYGWIN__) |
| const char* prgfiles = cmsys::SystemTools::GetEnv("ProgramFiles"); |
| const char* sysDrive = cmsys::SystemTools::GetEnv("SystemDrive"); |
| if ( prgfiles ) |
| { |
| this->InstallPath = prgfiles; |
| } |
| else if ( sysDrive ) |
| { |
| this->InstallPath = sysDrive; |
| this->InstallPath += "/Program Files"; |
| } |
| else |
| { |
| this->InstallPath = "c:/Program Files"; |
| } |
| this->InstallPath += "/"; |
| this->InstallPath += this->GetOption("CPACK_PACKAGE_NAME"); |
| this->InstallPath += "-"; |
| this->InstallPath += this->GetOption("CPACK_PACKAGE_VERSION"); |
| #elif defined(__HAIKU__) |
| char dir[B_PATH_NAME_LENGTH]; |
| if (find_directory(B_SYSTEM_DIRECTORY, -1, false, dir, sizeof(dir)) == B_OK) |
| { |
| this->InstallPath = dir; |
| } |
| else |
| { |
| this->InstallPath = "/boot/system"; |
| } |
| #else |
| this->InstallPath = "/usr/local/"; |
| #endif |
| return this->InstallPath.c_str(); |
| } |
| |
| //---------------------------------------------------------------------- |
| const char* cmCPackGenerator::GetPackagingInstallPrefix() |
| { |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "GetPackagingInstallPrefix: '" |
| << this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX") << "'" << std::endl); |
| |
| return this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); |
| } |
| |
| //---------------------------------------------------------------------- |
| std::string cmCPackGenerator::FindTemplate(const char* name) |
| { |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for template: " |
| << (name ? name : "(NULL)") << std::endl); |
| std::string ffile = this->MakefileMap->GetModulesFile(name); |
| cmCPackLogger(cmCPackLog::LOG_DEBUG, "Found template: " |
| << ffile << std::endl); |
| return ffile; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::ConfigureString(const std::string& inString, |
| std::string& outString) |
| { |
| this->MakefileMap->ConfigureString(inString, |
| outString, true, false); |
| return true; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::ConfigureFile(const char* inName, |
| const char* outName, bool copyOnly /* = false */) |
| { |
| return this->MakefileMap->ConfigureFile(inName, outName, |
| copyOnly, true, false) == 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::CleanTemporaryDirectory() |
| { |
| std::string tempInstallDirectoryWithPostfix |
| = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); |
| const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str(); |
| if(cmsys::SystemTools::FileExists(tempInstallDirectory)) |
| { |
| cmCPackLogger(cmCPackLog::LOG_OUTPUT, |
| "- Clean temporary : " |
| << tempInstallDirectory << std::endl); |
| if(!cmSystemTools::RepeatedRemoveDirectory(tempInstallDirectory)) |
| { |
| cmCPackLogger(cmCPackLog::LOG_ERROR, |
| "Problem removing temporary directory: " << |
| tempInstallDirectory |
| << std::endl); |
| return 0; |
| } |
| } |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| cmInstalledFile const* cmCPackGenerator::GetInstalledFile( |
| std::string const& name) const |
| { |
| cmake const* cm = this->MakefileMap->GetCMakeInstance(); |
| return cm->GetInstalledFile(name); |
| } |
| |
| //---------------------------------------------------------------------- |
| int cmCPackGenerator::PrepareGroupingKind() |
| { |
| // find a component package method specified by the user |
| ComponentPackageMethod method = UNKNOWN_COMPONENT_PACKAGE_METHOD; |
| |
| if(this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE")) |
| { |
| method = ONE_PACKAGE; |
| } |
| |
| if(this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS")) |
| { |
| method = ONE_PACKAGE_PER_COMPONENT; |
| } |
| |
| if(this->GetOption("CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP")) |
| { |
| method = ONE_PACKAGE_PER_GROUP; |
| } |
| |
| std::string groupingType; |
| |
| // Second way to specify grouping |
| if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) { |
| groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); |
| } |
| |
| if (!groupingType.empty()) |
| { |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" |
| << this->Name << "]" |
| << " requested component grouping = "<< groupingType <<std::endl); |
| if (groupingType == "ALL_COMPONENTS_IN_ONE") |
| { |
| method = ONE_PACKAGE; |
| } |
| else if (groupingType == "IGNORE") |
| { |
| method = ONE_PACKAGE_PER_COMPONENT; |
| } |
| else if (groupingType == "ONE_PER_GROUP") |
| { |
| method = ONE_PACKAGE_PER_GROUP; |
| } |
| else |
| { |
| cmCPackLogger(cmCPackLog::LOG_WARNING, "[" |
| << this->Name << "]" |
| << " requested component grouping type <"<< groupingType |
| << "> UNKNOWN not in (ALL_COMPONENTS_IN_ONE,IGNORE,ONE_PER_GROUP)" |
| << std::endl); |
| } |
| } |
| |
| // Some components were defined but NO group |
| // fallback to default if not group based |
| if(method == ONE_PACKAGE_PER_GROUP && |
| this->ComponentGroups.empty() && !this->Components.empty()) |
| { |
| if(componentPackageMethod == ONE_PACKAGE) |
| { |
| method = ONE_PACKAGE; |
| } |
| else |
| { |
| method = ONE_PACKAGE_PER_COMPONENT; |
| } |
| cmCPackLogger(cmCPackLog::LOG_WARNING, "[" |
| << this->Name << "]" |
| << " One package per component group requested, " |
| << "but NO component groups exist: Ignoring component group." |
| << std::endl); |
| } |
| |
| // if user specified packaging method, override the default packaging method |
| if(method != UNKNOWN_COMPONENT_PACKAGE_METHOD) |
| { |
| componentPackageMethod = method; |
| } |
| |
| const char* method_names[] = |
| { |
| "ALL_COMPONENTS_IN_ONE", |
| "IGNORE_GROUPS", |
| "ONE_PER_GROUP" |
| }; |
| |
| cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" |
| << this->Name << "]" |
| << " requested component grouping = " |
| << method_names[componentPackageMethod] |
| << std::endl); |
| |
| return 1; |
| } |
| |
| //---------------------------------------------------------------------- |
| std::string cmCPackGenerator::GetComponentInstallDirNameSuffix( |
| const std::string& componentName) { |
| return componentName; |
| } |
| //---------------------------------------------------------------------- |
| std::string cmCPackGenerator::GetComponentPackageFileName( |
| const std::string& initialPackageFileName, |
| const std::string& groupOrComponentName, |
| bool isGroupName) { |
| |
| /* |
| * the default behavior is to use the |
| * component [group] name as a suffix |
| */ |
| std::string suffix="-"+groupOrComponentName; |
| /* check if we should use DISPLAY name */ |
| std::string dispNameVar = "CPACK_"+Name+"_USE_DISPLAY_NAME_IN_FILENAME"; |
| if (IsOn(dispNameVar)) |
| { |
| /* the component Group case */ |
| if (isGroupName) |
| { |
| std::string groupDispVar = "CPACK_COMPONENT_GROUP_" |
| + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; |
| const char* groupDispName = GetOption(groupDispVar); |
| if (groupDispName) |
| { |
| suffix = "-"+std::string(groupDispName); |
| } |
| } |
| /* the [single] component case */ |
| else |
| { |
| std::string dispVar = "CPACK_COMPONENT_" |
| + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; |
| const char* dispName = GetOption(dispVar); |
| if(dispName) |
| { |
| suffix = "-"+std::string(dispName); |
| } |
| } |
| } |
| return initialPackageFileName + suffix; |
| } |
| |
| //---------------------------------------------------------------------- |
| enum cmCPackGenerator::CPackSetDestdirSupport |
| cmCPackGenerator::SupportsSetDestdir() const |
| { |
| return cmCPackGenerator::SETDESTDIR_SUPPORTED; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::SupportsAbsoluteDestination() const |
| { |
| return true; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::SupportsComponentInstallation() const |
| { |
| return false; |
| } |
| |
| //---------------------------------------------------------------------- |
| bool cmCPackGenerator::WantsComponentInstallation() const |
| { |
| return (!IsOn("CPACK_MONOLITHIC_INSTALL") |
| && SupportsComponentInstallation() |
| // check that we have at least one group or component |
| && (!this->ComponentGroups.empty() || !this->Components.empty())); |
| } |
| |
| //---------------------------------------------------------------------- |
| cmCPackInstallationType* |
| cmCPackGenerator::GetInstallationType(const std::string& projectName, |
| const std::string& name) |
| { |
| (void) projectName; |
| bool hasInstallationType = this->InstallationTypes.count(name) != 0; |
| cmCPackInstallationType *installType = &this->InstallationTypes[name]; |
| if (!hasInstallationType) |
| { |
| // Define the installation type |
| std::string macroPrefix = "CPACK_INSTALL_TYPE_" |
| + cmsys::SystemTools::UpperCase(name); |
| installType->Name = name; |
| |
| const char* displayName |
| = this->GetOption(macroPrefix + "_DISPLAY_NAME"); |
| if (displayName && *displayName) |
| { |
| installType->DisplayName = displayName; |
| } |
| else |
| { |
| installType->DisplayName = installType->Name; |
| } |
| |
| installType->Index = static_cast<unsigned>( |
| this->InstallationTypes.size()); |
| } |
| return installType; |
| } |
| |
| //---------------------------------------------------------------------- |
| cmCPackComponent* |
| cmCPackGenerator::GetComponent(const std::string& projectName, |
| const std::string& name) |
| { |
| bool hasComponent = this->Components.count(name) != 0; |
| cmCPackComponent *component = &this->Components[name]; |
| if (!hasComponent) |
| { |
| // Define the component |
| std::string macroPrefix = "CPACK_COMPONENT_" |
| + cmsys::SystemTools::UpperCase(name); |
| component->Name = name; |
| const char* displayName |
| = this->GetOption(macroPrefix + "_DISPLAY_NAME"); |
| if (displayName && *displayName) |
| { |
| component->DisplayName = displayName; |
| } |
| else |
| { |
| component->DisplayName = component->Name; |
| } |
| component->IsHidden |
| = this->IsOn(macroPrefix + "_HIDDEN"); |
| component->IsRequired |
| = this->IsOn(macroPrefix + "_REQUIRED"); |
| component->IsDisabledByDefault |
| = this->IsOn(macroPrefix + "_DISABLED"); |
| component->IsDownloaded |
| = this->IsOn(macroPrefix + "_DOWNLOADED") |
| || cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL")); |
| |
| const char* archiveFile = this->GetOption(macroPrefix + |
| "_ARCHIVE_FILE"); |
| if (archiveFile && *archiveFile) |
| { |
| component->ArchiveFile = archiveFile; |
| } |
| |
| const char* groupName = this->GetOption(macroPrefix + "_GROUP"); |
| if (groupName && *groupName) |
| { |
| component->Group = GetComponentGroup(projectName, groupName); |
| component->Group->Components.push_back(component); |
| } |
| else |
| { |
| component->Group = 0; |
| } |
| |
| const char* description |
| = this->GetOption(macroPrefix + "_DESCRIPTION"); |
| if (description && *description) |
| { |
| component->Description = description; |
| } |
| |
| // Determine the installation types. |
| const char *installTypes |
| = this->GetOption(macroPrefix + "_INSTALL_TYPES"); |
| if (installTypes && *installTypes) |
| { |
| std::vector<std::string> installTypesVector; |
| cmSystemTools::ExpandListArgument(installTypes, installTypesVector); |
| std::vector<std::string>::iterator installTypesIt; |
| for (installTypesIt = installTypesVector.begin(); |
| installTypesIt != installTypesVector.end(); |
| ++installTypesIt) |
| { |
| component->InstallationTypes.push_back( |
| this->GetInstallationType(projectName, *installTypesIt)); |
| } |
| } |
| |
| // Determine the component dependencies. |
| const char *depends = this->GetOption(macroPrefix + "_DEPENDS"); |
| if (depends && *depends) |
| { |
| std::vector<std::string> dependsVector; |
| cmSystemTools::ExpandListArgument(depends, dependsVector); |
| std::vector<std::string>::iterator dependIt; |
| for (dependIt = dependsVector.begin(); |
| dependIt != dependsVector.end(); |
| ++dependIt) |
| { |
| cmCPackComponent *child = GetComponent(projectName, |
| *dependIt); |
| component->Dependencies.push_back(child); |
| child->ReverseDependencies.push_back(component); |
| } |
| } |
| } |
| return component; |
| } |
| |
| //---------------------------------------------------------------------- |
| cmCPackComponentGroup* |
| cmCPackGenerator::GetComponentGroup(const std::string& projectName, |
| const std::string& name) |
| { |
| (void) projectName; |
| std::string macroPrefix = "CPACK_COMPONENT_GROUP_" |
| + cmsys::SystemTools::UpperCase(name); |
| bool hasGroup = this->ComponentGroups.count(name) != 0; |
| cmCPackComponentGroup *group = &this->ComponentGroups[name]; |
| if (!hasGroup) |
| { |
| // Define the group |
| group->Name = name; |
| const char* displayName |
| = this->GetOption(macroPrefix + "_DISPLAY_NAME"); |
| if (displayName && *displayName) |
| { |
| group->DisplayName = displayName; |
| } |
| else |
| { |
| group->DisplayName = group->Name; |
| } |
| |
| const char* description |
| = this->GetOption(macroPrefix + "_DESCRIPTION"); |
| if (description && *description) |
| { |
| group->Description = description; |
| } |
| group->IsBold |
| = this->IsOn(macroPrefix + "_BOLD_TITLE"); |
| group->IsExpandedByDefault |
| = this->IsOn(macroPrefix + "_EXPANDED"); |
| const char* parentGroupName |
| = this->GetOption(macroPrefix + "_PARENT_GROUP"); |
| if (parentGroupName && *parentGroupName) |
| { |
| group->ParentGroup = GetComponentGroup(projectName, parentGroupName); |
| group->ParentGroup->Subgroups.push_back(group); |
| } |
| else |
| { |
| group->ParentGroup = 0; |
| } |
| } |
| return group; |
| } |