| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /*=========================================================================
- Program: CMake - Cross-Platform Makefile Generator
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
- Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
- See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
- =========================================================================*/
- #include "cmCPackNSISGenerator.h"
- #include "cmGlobalGenerator.h"
- #include "cmLocalGenerator.h"
- #include "cmSystemTools.h"
- #include "cmMakefile.h"
- #include "cmGeneratedFileStream.h"
- #include "cmCPackLog.h"
- #include <cmsys/SystemTools.hxx>
- #include <cmsys/Glob.hxx>
- #include <cmsys/Directory.hxx>
- #include <cmsys/RegularExpression.hxx>
- //----------------------------------------------------------------------
- cmCPackNSISGenerator::cmCPackNSISGenerator()
- {
- }
- //----------------------------------------------------------------------
- cmCPackNSISGenerator::~cmCPackNSISGenerator()
- {
- }
- //----------------------------------------------------------------------
- int cmCPackNSISGenerator::CompressFiles(const char* outFileName,
- const char* toplevel, const std::vector<std::string>& files)
- {
- (void)outFileName; // TODO: Fix nsis to force out file name
- (void)toplevel;
- std::string nsisInFileName = this->FindTemplate("NSIS.template.in");
- if ( nsisInFileName.size() == 0 )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPack error: Could not find NSIS installer template file."
- << std::endl);
- return false;
- }
- std::string nsisInInstallOptions
- = this->FindTemplate("NSIS.InstallOptions.ini.in");
- if ( nsisInInstallOptions.size() == 0 )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPack error: Could not find NSIS installer options file."
- << std::endl);
- return false;
- }
- std::string nsisFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- std::string tmpFile = nsisFileName;
- tmpFile += "/NSISOutput.log";
- std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini";
- nsisFileName += "/project.nsi";
- cmOStringStream str;
- std::vector<std::string>::const_iterator it;
- for ( it = files.begin(); it != files.end(); ++ it )
- {
- std::string fileN = cmSystemTools::RelativePath(toplevel,
- it->c_str());
- cmSystemTools::ReplaceString(fileN, "/", "\\");
- str << " Delete \"$INSTDIR\\" << fileN.c_str() << "\"" << std::endl;
- }
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Files: "
- << str.str().c_str() << std::endl);
- this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str().c_str());
- std::vector<std::string> dirs;
- this->GetListOfSubdirectories(toplevel, dirs);
- std::vector<std::string>::const_iterator sit;
- cmOStringStream dstr;
- for ( sit = dirs.begin(); sit != dirs.end(); ++ sit )
- {
- std::string fileN = cmSystemTools::RelativePath(toplevel,
- sit->c_str());
- if ( fileN.empty() )
- {
- continue;
- }
- cmSystemTools::ReplaceString(fileN, "/", "\\");
- dstr << " RMDir \"$INSTDIR\\" << fileN.c_str() << "\"" << std::endl;
- }
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Dirs: "
- << dstr.str().c_str() << std::endl);
- this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES",
- dstr.str().c_str());
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << nsisInFileName
- << " to " << nsisFileName << std::endl);
- this->ConfigureFile(nsisInInstallOptions.c_str(),
- nsisInstallOptions.c_str());
- this->ConfigureFile(nsisInFileName.c_str(), nsisFileName.c_str());
- std::string nsisCmd = "\"";
- nsisCmd += this->GetOption("CPACK_INSTALLER_PROGRAM");
- nsisCmd += "\" \"" + nsisFileName + "\"";
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd.c_str()
- << std::endl);
- std::string output;
- int retVal = 1;
- bool res = cmSystemTools::RunSingleCommand(nsisCmd.c_str(), &output,
- &retVal, 0, this->GeneratorVerbose, 0);
- if ( !res || retVal )
- {
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << nsisCmd.c_str() << std::endl
- << "# Output:" << std::endl
- << output.c_str() << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running NSIS command: "
- << nsisCmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
- return 0;
- }
- return 1;
- }
- //----------------------------------------------------------------------
- int cmCPackNSISGenerator::InitializeInternal()
- {
- if ( cmSystemTools::IsOn(this->GetOption(
- "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY. "
- "This option will be ignored."
- << std::endl);
- this->SetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", 0);
- }
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "cmCPackNSISGenerator::Initialize()"
- << std::endl);
- std::vector<std::string> path;
- std::string nsisPath;
- if ( !cmsys::SystemTools::ReadRegistryValue(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath) )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find NSIS registry value"
- << std::endl);
- return 0;
- }
- path.push_back(nsisPath);
- nsisPath = cmSystemTools::FindProgram("makensis", path, false);
- if ( nsisPath.empty() )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find NSIS compiler"
- << std::endl);
- return 0;
- }
- std::string nsisCmd = "\"" + nsisPath + "\" /VERSION";
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Test NSIS version: "
- << nsisCmd.c_str() << std::endl);
- std::string output;
- int retVal = 1;
- bool resS = cmSystemTools::RunSingleCommand(nsisCmd.c_str(),
- &output, &retVal, 0, this->GeneratorVerbose, 0);
- cmsys::RegularExpression versionRex("v([0-9]+.[0-9]+)");
- if ( !resS || retVal || !versionRex.find(output))
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/NSISOutput.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << nsisCmd.c_str() << std::endl
- << "# Output:" << std::endl
- << output.c_str() << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem checking NSIS version with command: "
- << nsisCmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
- return 0;
- }
- float nsisVersion = atof(versionRex.match(1).c_str());
- float minNSISVersion = 2.09;
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: "
- << nsisVersion << std::endl);
- if ( nsisVersion < minNSISVersion )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPack requires NSIS Version 2.09 or greater. NSIS found on the system "
- "was: "
- << nsisVersion << std::endl);
- return 0;
- }
- this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath.c_str());
- const char* cpackPackageExecutables
- = this->GetOption("CPACK_PACKAGE_EXECUTABLES");
- if ( cpackPackageExecutables )
- {
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
- << cpackPackageExecutables << "." << std::endl);
- cmOStringStream str;
- cmOStringStream deleteStr;
- std::vector<std::string> cpackPackageExecutablesVector;
- cmSystemTools::ExpandListArgument(cpackPackageExecutables,
- cpackPackageExecutablesVector);
- if ( cpackPackageExecutablesVector.size() % 2 != 0 )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
- "<icon name>." << std::endl);
- return 0;
- }
- std::vector<std::string>::iterator it;
- for ( it = cpackPackageExecutablesVector.begin();
- it != cpackPackageExecutablesVector.end();
- ++it )
- {
- std::string execName = *it;
- ++ it;
- std::string linkName = *it;
- str << " CreateShortCut \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
- << linkName << ".lnk\" \"$INSTDIR\\bin\\" << execName << ".exe\""
- << std::endl;
- deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
- << ".lnk\"" << std::endl;
- }
- this->SetOptionIfNotSet("CPACK_NSIS_CREATE_ICONS", str.str().c_str());
- this->SetOptionIfNotSet("CPACK_NSIS_DELETE_ICONS",
- deleteStr.str().c_str());
- }
- return this->Superclass::InitializeInternal();
- }
- //----------------------------------------------------------------------
- bool cmCPackNSISGenerator::GetListOfSubdirectories(const char* topdir,
- std::vector<std::string>& dirs)
- {
- cmsys::Directory dir;
- dir.Load(topdir);
- size_t fileNum;
- for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum)
- {
- if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
- strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
- {
- cmsys_stl::string fullPath = topdir;
- fullPath += "/";
- fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(cmsys::SystemTools::FileIsDirectory(fullPath.c_str()) &&
- !cmsys::SystemTools::FileIsSymlink(fullPath.c_str()))
- {
- if (!this->GetListOfSubdirectories(fullPath.c_str(), dirs))
- {
- return false;
- }
- }
- }
- }
- dirs.push_back(topdir);
- return true;
- }
|