/*============================================================================
  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;
}
