[Cmake-commits] [cmake-commits] david.cole committed cmCPackComponentGroup.h 1.1 1.2 cmCPackGenerator.cxx 1.9 1.10 cmCPackNSISGenerator.cxx 1.35 1.36 cmCPackNSISGenerator.h 1.12 1.13 cmCPackPackageMakerGenerator.cxx 1.25 1.26
cmake-commits at cmake.org
cmake-commits at cmake.org
Tue Jul 8 11:52:27 EDT 2008
Update of /cvsroot/CMake/CMake/Source/CPack
In directory public:/mounts/ram/cvs-serv11595/Source/CPack
Modified Files:
cmCPackComponentGroup.h cmCPackGenerator.cxx
cmCPackNSISGenerator.cxx cmCPackNSISGenerator.h
cmCPackPackageMakerGenerator.cxx
Log Message:
ENH: Further refinement of the CPack components functionality from Doug Gregor.
Details:
==========
- New cpack_add_component, cpack_add_component_group, and
cpack_add_install_type "commands" defined as macros in the CPack
module.
- Documentation for all of the variables and commands in the CPack module.
- Added get_cmake_property(... COMPONENTS) to CMake to ask for the
names of all components. Used in the CPack module to automatically
build component-based installers. (Set CPACK_MONOLITHIC_INSTALL to
turn off component-based installation).
- A group can declare its PARENT_GROUP, to build an arbitrary
hierarchy of groups.
- New CPack command cpack_configure_downloads, which creates an
installer that downloads only the selected components on-the-fly.
Those components marked DOWNLOADED will be separate packages
downloaded on-the-fly (or, all packages can be marked as such with the
ALL option to cpack_configure_downloads). Individual components are
compressed with ZIP at installer-creation time and
downloaded/uncompressed by the installer as needed. This feature is
only available on Windows with NSIS at the moment.
- NSIS installers can install themselves and enable the "Change"
button in Add/Remove programs, allowing users to go back and install
or remove components. This can be disabled through
cpack_configure_downloads, because it's only really useful is most of
the application's functionality is in downloaded components.
- Bug fix: automatically install everything whose COMPONENT was not
specified (it's a hidden, required group)
- Bug fix: fixed removal of components when re-running the NSIS
installer and unchecking components
- Bug fix: NSIS installers now only install/remove the minimal
number of files when re-run to update the installation (or by clicking
"Change" in Add/Remove programs)
Index: cmCPackNSISGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CPack/cmCPackNSISGenerator.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -C 2 -d -r1.12 -r1.13
*** cmCPackNSISGenerator.h 17 Jun 2008 15:39:26 -0000 1.12
--- cmCPackNSISGenerator.h 8 Jul 2008 15:52:24 -0000 1.13
***************
*** 54,59 ****
/// Produce a string that contains the NSIS code to describe a
! /// particular component.
! std::string CreateComponentDescription(cmCPackComponent *component) const;
/// Produce NSIS code that selects all of the components that this component
--- 54,62 ----
/// Produce a string that contains the NSIS code to describe a
! /// particular component. Any added macros will be emitted via
! /// macrosOut.
! std::string
! CreateComponentDescription(cmCPackComponent *component,
! cmOStringStream& macrosOut);
/// Produce NSIS code that selects all of the components that this component
***************
*** 61,65 ****
std::string CreateSelectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited) const;
/// Produce NSIS code that de-selects all of the components that are dependent
--- 64,68 ----
std::string CreateSelectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited);
/// Produce NSIS code that de-selects all of the components that are dependent
***************
*** 67,75 ****
std::string CreateDeselectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited) const;
/// Produce a string that contains the NSIS code to describe a
! /// particular component group, including its components.
! std::string CreateComponentGroupDescription(cmCPackComponentGroup *group) const;
/// Translations any newlines found in the string into \r\n, so that the
--- 70,81 ----
std::string CreateDeselectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited);
/// Produce a string that contains the NSIS code to describe a
! /// particular component group, including its components. Any
! /// added macros will be emitted via macrosOut.
! std::string
! CreateComponentGroupDescription(cmCPackComponentGroup *group,
! cmOStringStream& macrosOut);
/// Translations any newlines found in the string into \r\n, so that the
Index: cmCPackPackageMakerGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CPack/cmCPackPackageMakerGenerator.cxx,v
retrieving revision 1.25
retrieving revision 1.26
diff -C 2 -d -r1.25 -r1.26
*** cmCPackPackageMakerGenerator.cxx 18 Jun 2008 11:08:33 -0000 1.25
--- cmCPackPackageMakerGenerator.cxx 8 Jul 2008 15:52:24 -0000 1.26
***************
*** 581,585 ****
++groupIt)
{
! CreateChoiceOutline(groupIt->second, choiceOut);
}
--- 581,588 ----
++groupIt)
{
! if (groupIt->second.ParentGroup == 0)
! {
! CreateChoiceOutline(groupIt->second, choiceOut);
! }
}
***************
*** 623,626 ****
--- 626,636 ----
{
out << "<line choice=\"" << group.Name << "Choice\">" << std::endl;
+ std::vector<cmCPackComponentGroup*>::const_iterator groupIt;
+ for (groupIt = group.Subgroups.begin(); groupIt != group.Subgroups.end();
+ ++groupIt)
+ {
+ CreateChoiceOutline(**groupIt, out);
+ }
+
std::vector<cmCPackComponent*>::const_iterator compIt;
for (compIt = group.Components.begin(); compIt != group.Components.end();
Index: cmCPackNSISGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CPack/cmCPackNSISGenerator.cxx,v
retrieving revision 1.35
retrieving revision 1.36
diff -C 2 -d -r1.35 -r1.36
*** cmCPackNSISGenerator.cxx 18 Jun 2008 18:25:57 -0000 1.35
--- cmCPackNSISGenerator.cxx 8 Jul 2008 15:52:24 -0000 1.36
***************
*** 174,177 ****
--- 174,180 ----
std::string groupDescriptions;
std::string installTypesCode;
+ std::string defines;
+ cmOStringStream macrosOut;
+ bool anyDownloadedComponents = false;
// Create installation types. The order is significant, so we first fill
***************
*** 202,206 ****
++groupIt)
{
! componentCode += this->CreateComponentGroupDescription(&groupIt->second);
// Add the group description, if any.
--- 205,213 ----
++groupIt)
{
! if (groupIt->second.ParentGroup == 0)
! {
! componentCode +=
! this->CreateComponentGroupDescription(&groupIt->second, macrosOut);
! }
// Add the group description, if any.
***************
*** 219,225 ****
++compIt)
{
if (!compIt->second.Group)
{
! componentCode += this->CreateComponentDescription(&compIt->second);
}
--- 226,242 ----
++compIt)
{
+ if (compIt->second.Files.empty())
+ {
+ // NSIS cannot cope with components that have no files.
+ continue;
+ }
+
+ anyDownloadedComponents =
+ anyDownloadedComponents || compIt->second.IsDownloaded;
+
if (!compIt->second.Group)
{
! componentCode
! += this->CreateComponentDescription(&compIt->second, macrosOut);
}
***************
*** 229,232 ****
--- 246,250 ----
sectionList += "\"\n";
selectedVarsList += "Var " + compIt->first + "_selected\n";
+ selectedVarsList += "Var " + compIt->first + "_was_installed\n";
// Add the component description, if any.
***************
*** 239,242 ****
--- 257,262 ----
}
+ componentCode += macrosOut.str();
+
if (componentDescriptions.empty() && groupDescriptions.empty())
{
***************
*** 255,258 ****
--- 275,288 ----
componentDescriptions.c_str());
}
+
+ if (anyDownloadedComponents)
+ {
+ defines += "!define CPACK_USES_DOWNLOAD\n";
+ if (cmSystemTools::IsOn(this->GetOption("CPACK_ADD_REMOVE")))
+ {
+ defines += "!define CPACK_NSIS_ADD_REMOVE\n";
+ }
+ }
+
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", installTypesCode.c_str());
this->SetOptionIfNotSet("CPACK_NSIS_PAGE_COMPONENTS", "!insertmacro MUI_PAGE_COMPONENTS");
***************
*** 261,264 ****
--- 291,295 ----
this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST", sectionList.c_str());
this->SetOptionIfNotSet("CPACK_NSIS_SECTION_SELECTED_VARS", selectedVarsList.c_str());
+ this->SetOption("CPACK_NSIS_DEFINES", defines.c_str());
}
***************
*** 560,564 ****
std::string
cmCPackNSISGenerator::
! CreateComponentDescription(cmCPackComponent *component) const
{
// Basic description of the component
--- 591,595 ----
std::string
cmCPackNSISGenerator::
! CreateComponentDescription(cmCPackComponent *component, cmOStringStream& macrosOut)
{
// Basic description of the component
***************
*** 591,599 ****
}
componentCode += " SetOutPath \"$INSTDIR\"\n";
! componentCode += " File /r \"${INST_DIR}\\" + component->Name + "\\*.*\"\n";
componentCode += "SectionEnd\n";
// Macro used to remove the component
! componentCode += "!macro Remove_${" + component->Name + "}\n";
std::vector<std::string>::iterator pathIt;
for (pathIt = component->Files.begin();
--- 622,783 ----
}
componentCode += " SetOutPath \"$INSTDIR\"\n";
!
! componentCode += " IntCmp $" + component->Name
! + "_was_installed ${SF_SELECTED} noinstall_" + component->Name + "\n";
!
! // Create the actual installation commands
! if (component->IsDownloaded)
! {
! if (component->ArchiveFile.empty())
! {
! // Compute the name of the archive.
! std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
! packagesDir += ".dummy";
! cmOStringStream out;
! out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
! << "-" << component->Name << ".zip";
! component->ArchiveFile = out.str();
! }
!
! // Create the directory for the upload area
! const char* userUploadDirectory = this->GetOption("CPACK_UPLOAD_DIRECTORY");
! std::string uploadDirectory;
! if (userUploadDirectory && *userUploadDirectory)
! {
! uploadDirectory = userUploadDirectory;
! }
! else
! {
! uploadDirectory= this->GetOption("CPACK_PACKAGE_DIRECTORY");
! uploadDirectory += "/CPackUploads";
! }
! if(!cmSystemTools::FileExists(uploadDirectory.c_str()))
! {
! if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str()))
! {
! cmCPackLogger(cmCPackLog::LOG_ERROR,
! "Unable to create NSIS upload directory " << uploadDirectory
! << std::endl);
! return "";
! }
! }
!
! // Remove the old archive, if one exists
! std::string archiveFile = uploadDirectory + '/' + component->ArchiveFile;
! cmCPackLogger(cmCPackLog::LOG_OUTPUT,
! "- Building downloaded component archive: "
! << archiveFile << std::endl);
! if (cmSystemTools::FileExists(archiveFile.c_str(), true))
! {
! if (!cmSystemTools::RemoveFile(archiveFile.c_str()))
! {
! cmCPackLogger(cmCPackLog::LOG_ERROR,
! "Unable to remove archive file " << archiveFile
! << std::endl);
! return "";
! }
! }
!
! // Find a ZIP program
! if (!this->IsSet("ZIP_EXECUTABLE"))
! {
! this->ReadListFile("CPackZIP.cmake");
!
! if (!this->IsSet("ZIP_EXECUTABLE"))
! {
! cmCPackLogger(cmCPackLog::LOG_ERROR,
! "Unable to find ZIP program"
! << std::endl);
! return "";
! }
! }
!
! // The directory where this component's files reside
! std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
! dirName += '/';
! dirName += component->Name;
! dirName += '/';
!
! // Build the list of files to go into this archive, and determine the
! // size of the installed component.
! std::string zipListFileName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
! zipListFileName += "/winZip.filelist";
! bool needQuotesInFile
! = cmSystemTools::IsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES"));
! unsigned long totalSize = 0;
! { // the scope is needed for cmGeneratedFileStream
! cmGeneratedFileStream out(zipListFileName.c_str());
! std::vector<std::string>::iterator fileIt;
! for (fileIt = component->Files.begin();
! fileIt != component->Files.end();
! ++fileIt)
! {
! if ( needQuotesInFile )
! {
! out << "\"";
! }
! out << *fileIt;
! if ( needQuotesInFile )
! {
! out << "\"";
! }
! out << std::endl;
!
! totalSize += cmSystemTools::FileLength((dirName + *fileIt).c_str());
! }
! }
!
! // Build the archive in the upload area
! std::string cmd = this->GetOption("CPACK_ZIP_COMMAND");
! cmsys::SystemTools::ReplaceString(cmd, "<ARCHIVE>", archiveFile.c_str());
! cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>",
! zipListFileName.c_str());
! std::string output;
! int retVal = -1;
! int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retVal,
! dirName.c_str(), false, 0);
! if ( !res || retVal )
! {
! std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
! tmpFile += "/CompressZip.log";
! cmGeneratedFileStream ofs(tmpFile.c_str());
! ofs << "# Run command: " << cmd.c_str() << std::endl
! << "# Output:" << std::endl
! << output.c_str() << std::endl;
! cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running zip command: "
! << cmd.c_str() << std::endl
! << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
! return "";
! }
!
! // Create the NSIS code to download this file on-the-fly.
! unsigned totalSizeInKbytes = (totalSize + 512) / 1024;
! if (totalSizeInKbytes == 0)
! {
! totalSizeInKbytes = 1;
! }
! cmOStringStream out;
! out << " AddSize " << totalSizeInKbytes << "\n"
! << " Push \"" << component->ArchiveFile << "\"\n"
! << " Call DownloadFile\n"
! << " ZipDLL::extractall \"$INSTDIR\\"
! << component->ArchiveFile << "\" \"$INSTDIR\"\n"
! << " Pop $2 ; error message\n"
! " StrCmp $2 \"success\" +2 0\n"
! " MessageBox MB_OK \"Failed to unzip $2\"\n"
! " Delete $INSTDIR\\$0\n";
! componentCode += out.str();
! }
! else
! {
! componentCode += " File /r \"${INST_DIR}\\" + component->Name + "\\*.*\"\n";
! }
! componentCode += " noinstall_" + component->Name + ":\n";
componentCode += "SectionEnd\n";
// Macro used to remove the component
! macrosOut << "!macro Remove_${" << component->Name << "}\n";
! macrosOut << " IntCmp $" << component->Name << "_was_installed 0 noremove_"
! << component->Name << "\n";
std::vector<std::string>::iterator pathIt;
for (pathIt = component->Files.begin();
***************
*** 601,605 ****
++pathIt)
{
! componentCode += " Delete \"$INSTDIR\\" + *pathIt + "\"\n";
}
for (pathIt = component->Directories.begin();
--- 785,791 ----
++pathIt)
{
! macrosOut << " Delete \"$INSTDIR\\"
! << cmSystemTools::ConvertToWindowsOutputPath(pathIt->c_str())
! << "\"\n";
}
for (pathIt = component->Directories.begin();
***************
*** 607,627 ****
++pathIt)
{
! componentCode += " RMDir \"$INSTDIR\\" + *pathIt + "\"\n";
}
! componentCode += "!macroend\n";
// Macro used to select each of the components that this component
// depends on.
std::set<cmCPackComponent *> visited;
! componentCode += "!macro Select_" + component->Name + "_depends\n";
! componentCode += CreateSelectionDependenciesDescription(component, visited);
! componentCode += "!macroend\n";
// Macro used to deselect each of the components that depend on this
// component.
visited.clear();
! componentCode += "!macro Deselect_required_by_" + component->Name + "\n";
! componentCode += CreateDeselectionDependenciesDescription(component, visited);
! componentCode += "!macroend\n";
return componentCode;
}
--- 793,816 ----
++pathIt)
{
! macrosOut << " RMDir \"$INSTDIR\\"
! << cmSystemTools::ConvertToWindowsOutputPath(pathIt->c_str())
! << "\"\n";
}
! macrosOut << " noremove_" << component->Name << ":\n";
! macrosOut << "!macroend\n";
// Macro used to select each of the components that this component
// depends on.
std::set<cmCPackComponent *> visited;
! macrosOut << "!macro Select_" << component->Name << "_depends\n";
! macrosOut << CreateSelectionDependenciesDescription(component, visited);
! macrosOut << "!macroend\n";
// Macro used to deselect each of the components that depend on this
// component.
visited.clear();
! macrosOut << "!macro Deselect_required_by_" << component->Name << "\n";
! macrosOut << CreateDeselectionDependenciesDescription(component, visited);
! macrosOut << "!macroend\n";
return componentCode;
}
***************
*** 630,634 ****
std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited) const
{
// Don't visit a component twice
--- 819,823 ----
std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited)
{
// Don't visit a component twice
***************
*** 661,665 ****
std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited) const
{
// Don't visit a component twice
--- 850,854 ----
std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription
(cmCPackComponent *component,
! std::set<cmCPackComponent *>& visited)
{
// Don't visit a component twice
***************
*** 693,699 ****
std::string
cmCPackNSISGenerator::
! CreateComponentGroupDescription(cmCPackComponentGroup *group) const
{
! if (group->Components.empty())
{
// Silently skip empty groups. NSIS doesn't support them.
--- 882,889 ----
std::string
cmCPackNSISGenerator::
! CreateComponentGroupDescription(cmCPackComponentGroup *group,
! cmOStringStream& macrosOut)
{
! if (group->Components.empty() && group->Subgroups.empty())
{
// Silently skip empty groups. NSIS doesn't support them.
***************
*** 714,717 ****
--- 904,915 ----
code += "\"" + group->DisplayName + "\" " + group->Name + "\n";
}
+
+ std::vector<cmCPackComponentGroup*>::iterator groupIt;
+ for (groupIt = group->Subgroups.begin(); groupIt != group->Subgroups.end();
+ ++groupIt)
+ {
+ code += this->CreateComponentGroupDescription(*groupIt, macrosOut);
+ }
+
std::vector<cmCPackComponent*>::iterator comp;
for (comp = group->Components.begin();
***************
*** 719,723 ****
++comp)
{
! code += this->CreateComponentDescription(*comp);
}
code += "SectionGroupEnd\n";
--- 917,926 ----
++comp)
{
! if ((*comp)->Files.empty())
! {
! continue;
! }
!
! code += this->CreateComponentDescription(*comp, macrosOut);
}
code += "SectionGroupEnd\n";
Index: cmCPackGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CPack/cmCPackGenerator.cxx,v
retrieving revision 1.9
retrieving revision 1.10
diff -C 2 -d -r1.9 -r1.10
*** cmCPackGenerator.cxx 18 Jun 2008 20:00:05 -0000 1.9
--- cmCPackGenerator.cxx 8 Jul 2008 15:52:24 -0000 1.10
***************
*** 654,657 ****
--- 654,665 ----
mf->AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
+ if ( !cmsys::SystemTools::MakeDirectory(dir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating temporary directory: "
+ << dir << std::endl);
+ return 0;
+ }
+
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf->AddDefinition)"
***************
*** 665,668 ****
--- 673,684 ----
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);
***************
*** 1256,1259 ****
--- 1272,1285 ----
component->IsDisabledByDefault
= this->IsSet((macroPrefix + "_DISABLED").c_str());
+ component->IsDownloaded
+ = this->IsSet((macroPrefix + "_DOWNLOADED").c_str())
+ || cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
+
+ const char* archiveFile = this->GetOption((macroPrefix + "_ARCHIVE_FILE").c_str());
+ if (archiveFile && *archiveFile)
+ {
+ component->ArchiveFile = archiveFile;
+ }
+
const char* groupName = this->GetOption((macroPrefix + "_GROUP").c_str());
if (groupName && *groupName)
***************
*** 1345,1348 ****
--- 1371,1385 ----
group->IsExpandedByDefault
= this->IsSet((macroPrefix + "_EXPANDED").c_str());
+ const char* parentGroupName
+ = this->GetOption((macroPrefix + "_PARENT_GROUP").c_str());
+ if (parentGroupName && *parentGroupName)
+ {
+ group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
+ group->ParentGroup->Subgroups.push_back(group);
+ }
+ else
+ {
+ group->ParentGroup = 0;
+ }
}
return group;
Index: cmCPackComponentGroup.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CPack/cmCPackComponentGroup.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C 2 -d -r1.1 -r1.2
*** cmCPackComponentGroup.h 17 Jun 2008 15:39:26 -0000 1.1
--- cmCPackComponentGroup.h 8 Jul 2008 15:52:24 -0000 1.2
***************
*** 71,74 ****
--- 71,78 ----
bool IsDisabledByDefault : 1;
+ /// Whether this component should be downloaded on-the-fly. If false,
+ /// the component will be a part of the installation package.
+ bool IsDownloaded : 1;
+
/// A description of this component.
std::string Description;
***************
*** 77,80 ****
--- 81,88 ----
std::vector<cmCPackInstallationType *> InstallationTypes;
+ /// If IsDownloaded is true, the name of the archive file that
+ /// contains the files that are part of this component.
+ std::string ArchiveFile;
+
/// The components that this component depends on.
std::vector<cmCPackComponent *> Dependencies;
***************
*** 96,99 ****
--- 104,109 ----
{
public:
+ cmCPackComponentGroup() : ParentGroup(0) { }
+
/// The name of the group (used to reference the group).
std::string Name;
***************
*** 113,116 ****
--- 123,132 ----
/// The components within this group.
std::vector<cmCPackComponent*> Components;
+
+ /// The parent group of this component group (if any).
+ cmCPackComponentGroup *ParentGroup;
+
+ /// The subgroups of this group.
+ std::vector<cmCPackComponentGroup*> Subgroups;
};
More information about the Cmake-commits
mailing list