summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClinton Stimpson <clinton@elemtech.com>2016-04-05 00:53:05 (GMT)
committerClinton Stimpson <clinton@elemtech.com>2016-06-02 03:56:50 (GMT)
commit50a3d34005ec923db3d76d0a5d118437a7632617 (patch)
tree76b0252c51ae9071b5e83d05e5e03512d65d6a7b
parentd6754d37d593a0189809dcf98bc4fdf3a609f0a3 (diff)
downloadCMake-50a3d34005ec923db3d76d0a5d118437a7632617.zip
CMake-50a3d34005ec923db3d76d0a5d118437a7632617.tar.gz
CMake-50a3d34005ec923db3d76d0a5d118437a7632617.tar.bz2
PackageMaker: factor out common code for creating pkg files.
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx368
-rw-r--r--Source/CPack/cmCPackPKGGenerator.h103
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx324
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.h68
5 files changed, 476 insertions, 388 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 3223831..f85f143 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -717,6 +717,7 @@ if(APPLE)
CPack/cmCPackBundleGenerator.cxx
CPack/cmCPackDragNDropGenerator.cxx
CPack/cmCPackOSXX11Generator.cxx
+ CPack/cmCPackPKGGenerator.cxx
CPack/cmCPackPackageMakerGenerator.cxx
)
endif()
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
new file mode 100644
index 0000000..8282714
--- /dev/null
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -0,0 +1,368 @@
+/*============================================================================
+ 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 "cmCPackPKGGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+
+cmCPackPKGGenerator::cmCPackPKGGenerator()
+{
+ this->componentPackageMethod = ONE_PACKAGE;
+}
+
+cmCPackPKGGenerator::~cmCPackPKGGenerator()
+{
+}
+
+bool cmCPackPKGGenerator::SupportsComponentInstallation() const
+{
+ return true;
+}
+
+int cmCPackPKGGenerator::InitializeInternal()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "cmCPackPKGGenerator::Initialize()" << std::endl);
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
+
+ return this->Superclass::InitializeInternal();
+}
+
+
+std::string cmCPackPKGGenerator::GetPackageName(
+ const cmCPackComponent& component)
+{
+ if (component.ArchiveFile.empty()) {
+ std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ packagesDir += ".dummy";
+ std::ostringstream out;
+ out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
+ << "-" << component.Name << ".pkg";
+ return out.str();
+ } else {
+ return component.ArchiveFile + ".pkg";
+ }
+}
+
+void cmCPackPKGGenerator::WriteDistributionFile(
+ const char* metapackageFile)
+{
+ std::string distributionTemplate =
+ this->FindTemplate("CPack.distribution.dist.in");
+ if (distributionTemplate.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
+ << distributionTemplate << std::endl);
+ return;
+ }
+
+ std::string distributionFile = metapackageFile;
+ distributionFile += "/Contents/distribution.dist";
+
+ // Create the choice outline, which provides a tree-based view of
+ // the components in their groups.
+ std::ostringstream choiceOut;
+ choiceOut << "<choices-outline>" << std::endl;
+
+ // Emit the outline for the groups
+ std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
+ for (groupIt = this->ComponentGroups.begin();
+ groupIt != this->ComponentGroups.end(); ++groupIt) {
+ if (groupIt->second.ParentGroup == 0) {
+ CreateChoiceOutline(groupIt->second, choiceOut);
+ }
+ }
+
+ // Emit the outline for the non-grouped components
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ if (!compIt->second.Group) {
+ choiceOut << "<line choice=\"" << compIt->first << "Choice\"></line>"
+ << std::endl;
+ }
+ }
+ if (!this->PostFlightComponent.Name.empty()) {
+ choiceOut << "<line choice=\"" << PostFlightComponent.Name
+ << "Choice\"></line>" << std::endl;
+ }
+ choiceOut << "</choices-outline>" << std::endl;
+
+ // Create the actual choices
+ for (groupIt = this->ComponentGroups.begin();
+ groupIt != this->ComponentGroups.end(); ++groupIt) {
+ CreateChoice(groupIt->second, choiceOut);
+ }
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ CreateChoice(compIt->second, choiceOut);
+ }
+
+ if (!this->PostFlightComponent.Name.empty()) {
+ CreateChoice(PostFlightComponent, choiceOut);
+ }
+
+ this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
+
+ // Create the distribution.dist file in the metapackage to turn it
+ // into a distribution package.
+ this->ConfigureFile(distributionTemplate.c_str(), distributionFile.c_str());
+}
+
+void cmCPackPKGGenerator::CreateChoiceOutline(
+ const cmCPackComponentGroup& group, std::ostringstream& out)
+{
+ 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();
+ ++compIt) {
+ out << " <line choice=\"" << (*compIt)->Name << "Choice\"></line>"
+ << std::endl;
+ }
+ out << "</line>" << std::endl;
+}
+
+void cmCPackPKGGenerator::CreateChoice(
+ const cmCPackComponentGroup& group, std::ostringstream& out)
+{
+ out << "<choice id=\"" << group.Name << "Choice\" "
+ << "title=\"" << group.DisplayName << "\" "
+ << "start_selected=\"true\" "
+ << "start_enabled=\"true\" "
+ << "start_visible=\"true\" ";
+ if (!group.Description.empty()) {
+ out << "description=\"" << EscapeForXML(group.Description) << "\"";
+ }
+ out << "></choice>" << std::endl;
+}
+
+void cmCPackPKGGenerator::CreateChoice(
+ const cmCPackComponent& component, std::ostringstream& out)
+{
+ std::string packageId = "com.";
+ packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
+ packageId += '.';
+ packageId += this->GetOption("CPACK_PACKAGE_NAME");
+ packageId += '.';
+ packageId += component.Name;
+
+ out << "<choice id=\"" << component.Name << "Choice\" "
+ << "title=\"" << component.DisplayName << "\" "
+ << "start_selected=\""
+ << (component.IsDisabledByDefault && !component.IsRequired ? "false"
+ : "true")
+ << "\" "
+ << "start_enabled=\"" << (component.IsRequired ? "false" : "true")
+ << "\" "
+ << "start_visible=\"" << (component.IsHidden ? "false" : "true")
+ << "\" ";
+ if (!component.Description.empty()) {
+ out << "description=\"" << EscapeForXML(component.Description) << "\" ";
+ }
+ if (!component.Dependencies.empty() ||
+ !component.ReverseDependencies.empty()) {
+ // The "selected" expression is evaluated each time any choice is
+ // selected, for all choices *except* the one that the user
+ // selected. A component is marked selected if it has been
+ // selected (my.choice.selected in Javascript) and all of the
+ // components it depends on have been selected (transitively) or
+ // if any of the components that depend on it have been selected
+ // (transitively). Assume that we have components A, B, C, D, and
+ // E, where each component depends on the previous component (B
+ // depends on A, C depends on B, D depends on C, and E depends on
+ // D). The expression we build for the component C will be
+ // my.choice.selected && B && A || D || E
+ // This way, selecting C will automatically select everything it depends
+ // on (B and A), while selecting something that depends on C--either D
+ // or E--will automatically cause C to get selected.
+ out << "selected=\"my.choice.selected";
+ std::set<const cmCPackComponent*> visited;
+ AddDependencyAttributes(component, visited, out);
+ visited.clear();
+ AddReverseDependencyAttributes(component, visited, out);
+ out << "\"";
+ }
+ out << ">" << std::endl;
+ out << " <pkg-ref id=\"" << packageId << "\"></pkg-ref>" << std::endl;
+ out << "</choice>" << std::endl;
+
+ // Create a description of the package associated with this
+ // component.
+ std::string relativePackageLocation = "Contents/Packages/";
+ relativePackageLocation += this->GetPackageName(component);
+
+ // Determine the installed size of the package.
+ std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ dirName += '/';
+ dirName += component.Name;
+ dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
+ unsigned long installedSize =
+ component.GetInstalledSizeInKbytes(dirName.c_str());
+
+ out << "<pkg-ref id=\"" << packageId << "\" "
+ << "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" "
+ << "installKBytes=\"" << installedSize << "\" "
+ << ">";
+ if (component.IsDownloaded) {
+ out << this->GetOption("CPACK_DOWNLOAD_SITE")
+ << this->GetPackageName(component);
+ } else {
+ out << "file:./" << relativePackageLocation;
+ }
+ out << "</pkg-ref>" << std::endl;
+}
+
+void cmCPackPKGGenerator::AddDependencyAttributes(
+ const cmCPackComponent& component,
+ std::set<const cmCPackComponent*>& visited, std::ostringstream& out)
+{
+ if (visited.find(&component) != visited.end()) {
+ return;
+ }
+ visited.insert(&component);
+
+ std::vector<cmCPackComponent*>::const_iterator dependIt;
+ for (dependIt = component.Dependencies.begin();
+ dependIt != component.Dependencies.end(); ++dependIt) {
+ out << " &amp;&amp; choices['" << (*dependIt)->Name << "Choice'].selected";
+ AddDependencyAttributes(**dependIt, visited, out);
+ }
+}
+
+void cmCPackPKGGenerator::AddReverseDependencyAttributes(
+ const cmCPackComponent& component,
+ std::set<const cmCPackComponent*>& visited, std::ostringstream& out)
+{
+ if (visited.find(&component) != visited.end()) {
+ return;
+ }
+ visited.insert(&component);
+
+ std::vector<cmCPackComponent*>::const_iterator dependIt;
+ for (dependIt = component.ReverseDependencies.begin();
+ dependIt != component.ReverseDependencies.end(); ++dependIt) {
+ out << " || choices['" << (*dependIt)->Name << "Choice'].selected";
+ AddReverseDependencyAttributes(**dependIt, visited, out);
+ }
+}
+
+std::string cmCPackPKGGenerator::EscapeForXML(std::string str)
+{
+ cmSystemTools::ReplaceString(str, "&", "&amp;");
+ cmSystemTools::ReplaceString(str, "<", "&lt;");
+ cmSystemTools::ReplaceString(str, ">", "&gt;");
+ cmSystemTools::ReplaceString(str, "\"", "&quot;");
+ return str;
+}
+
+bool cmCPackPKGGenerator::CopyCreateResourceFile(
+ const std::string& name, const std::string& dirName)
+{
+ std::string uname = cmSystemTools::UpperCase(name);
+ std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
+ const char* inFileName = this->GetOption(cpackVar.c_str());
+ if (!inFileName) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: "
+ << cpackVar.c_str()
+ << " not specified. It should point to "
+ << (!name.empty() ? name : "<empty>") << ".rtf, " << name
+ << ".html, or " << name << ".txt file" << std::endl);
+ return false;
+ }
+ if (!cmSystemTools::FileExists(inFileName)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
+ << (!name.empty() ? name : "<empty>")
+ << " resource file: " << inFileName << std::endl);
+ return false;
+ }
+ std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
+ if (ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt") {
+ cmCPackLogger(
+ cmCPackLog::LOG_ERROR, "Bad file extension specified: "
+ << ext
+ << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
+ << std::endl);
+ return false;
+ }
+
+ std::string destFileName = dirName;
+ destFileName += '/';
+ destFileName += name + ext;
+
+ // Set this so that distribution.dist gets the right name (without
+ // the path).
+ this->SetOption(("CPACK_RESOURCE_FILE_" + uname + "_NOPATH").c_str(),
+ (name + ext).c_str());
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
+ << (inFileName ? inFileName : "(NULL)") << " to "
+ << destFileName.c_str() << std::endl);
+ this->ConfigureFile(inFileName, destFileName.c_str());
+ return true;
+}
+
+bool cmCPackPKGGenerator::CopyResourcePlistFile(
+ const std::string& name, const char* outName)
+{
+ if (!outName) {
+ outName = name.c_str();
+ }
+
+ std::string inFName = "CPack.";
+ inFName += name;
+ inFName += ".in";
+ std::string inFileName = this->FindTemplate(inFName.c_str());
+ if (inFileName.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find input file: " << inFName << std::endl);
+ return false;
+ }
+
+ std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ destFileName += "/";
+ destFileName += outName;
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Configure file: " << inFileName.c_str() << " to "
+ << destFileName.c_str() << std::endl);
+ this->ConfigureFile(inFileName.c_str(), destFileName.c_str());
+ return true;
+}
+
+int cmCPackPKGGenerator::CopyInstallScript(const std::string& resdir,
+ const std::string& script,
+ const std::string& name)
+{
+ std::string dst = resdir;
+ dst += "/";
+ dst += name;
+ cmSystemTools::CopyFileAlways(script.c_str(), dst.c_str());
+ cmSystemTools::SetPermissions(dst.c_str(), 0777);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "copy script : "
+ << script << "\ninto " << dst.c_str() << std::endl);
+
+ return 1;
+}
diff --git a/Source/CPack/cmCPackPKGGenerator.h b/Source/CPack/cmCPackPKGGenerator.h
new file mode 100644
index 0000000..3011f78
--- /dev/null
+++ b/Source/CPack/cmCPackPKGGenerator.h
@@ -0,0 +1,103 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ 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.
+============================================================================*/
+
+#ifndef cmCPackPKGGenerator_h
+#define cmCPackPKGGenerator_h
+
+
+#include "cmCPackGenerator.h"
+
+class cmCPackComponent;
+
+/** \class cmCPackPKGGenerator
+ * \brief A generator for pkg files
+ *
+ */
+class cmCPackPKGGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackPKGGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackPKGGenerator();
+ virtual ~cmCPackPKGGenerator();
+
+ virtual bool SupportsComponentInstallation() const;
+
+protected:
+ virtual int InitializeInternal();
+ virtual const char* GetOutputPostfix() { return "darwin"; }
+
+ // Copies or creates the resource file with the given name to the
+ // package or package staging directory dirName. The variable
+ // CPACK_RESOURCE_FILE_${NAME} (where ${NAME} is the uppercased
+ // version of name) specifies the input file to use for this file,
+ // which will be configured via ConfigureFile.
+ bool CopyCreateResourceFile(const std::string& name,
+ const std::string& dirName);
+ bool CopyResourcePlistFile(const std::string& name, const char* outName = 0);
+
+ int CopyInstallScript(const std::string& resdir, const std::string& script,
+ const std::string& name);
+
+ // Retrieve the name of package file that will be generated for this
+ // component. The name is just the file name with extension, and
+ // does not include the subdirectory.
+ std::string GetPackageName(const cmCPackComponent& component);
+
+ // Writes a distribution.dist file, which turns a metapackage into a
+ // full-fledged distribution. This file is used to describe
+ // inter-component dependencies. metapackageFile is the name of the
+ // metapackage for the distribution. Only valid for a
+ // component-based install.
+ void WriteDistributionFile(const char* metapackageFile);
+
+ // Subroutine of WriteDistributionFile that writes out the
+ // dependency attributes for inter-component dependencies.
+ void AddDependencyAttributes(const cmCPackComponent& component,
+ std::set<const cmCPackComponent*>& visited,
+ std::ostringstream& out);
+
+ // Subroutine of WriteDistributionFile that writes out the
+ // reverse dependency attributes for inter-component dependencies.
+ void AddReverseDependencyAttributes(
+ const cmCPackComponent& component,
+ std::set<const cmCPackComponent*>& visited, std::ostringstream& out);
+
+ // Generates XML that encodes the hierarchy of component groups and
+ // their components in a form that can be used by distribution
+ // metapackages.
+ void CreateChoiceOutline(const cmCPackComponentGroup& group,
+ std::ostringstream& out);
+
+ /// Create the "choice" XML element to describe a component group
+ /// for the installer GUI.
+ void CreateChoice(const cmCPackComponentGroup& group,
+ std::ostringstream& out);
+
+ /// Create the "choice" XML element to describe a component for the
+ /// installer GUI.
+ void CreateChoice(const cmCPackComponent& component,
+ std::ostringstream& out);
+
+ // Escape the given string to make it usable as an XML attribute
+ // value.
+ std::string EscapeForXML(std::string str);
+
+ // The PostFlight component when creating a metapackage
+ cmCPackComponent PostFlightComponent;
+
+};
+
+#endif
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index 5ca3ff7..e50c2e6 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -46,21 +46,6 @@ bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
return this->PackageCompatibilityVersion >= getVersion(10, 4);
}
-int cmCPackPackageMakerGenerator::CopyInstallScript(const std::string& resdir,
- const std::string& script,
- const std::string& name)
-{
- std::string dst = resdir;
- dst += "/";
- dst += name;
- cmSystemTools::CopyFileAlways(script.c_str(), dst.c_str());
- cmSystemTools::SetPermissions(dst.c_str(), 0777);
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "copy script : "
- << script << "\ninto " << dst.c_str() << std::endl);
-
- return 1;
-}
-
int cmCPackPackageMakerGenerator::PackageFiles()
{
// TODO: Use toplevel
@@ -344,10 +329,6 @@ int cmCPackPackageMakerGenerator::PackageFiles()
int cmCPackPackageMakerGenerator::InitializeInternal()
{
- cmCPackLogger(cmCPackLog::LOG_DEBUG,
- "cmCPackPackageMakerGenerator::Initialize()" << std::endl);
- this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
-
// Starting with Xcode 4.3, PackageMaker is a separate app, and you
// can put it anywhere you want. So... use a variable for its location.
// People who put it in unexpected places can use the variable to tell
@@ -481,80 +462,6 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
return this->Superclass::InitializeInternal();
}
-bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(
- const std::string& name, const std::string& dirName)
-{
- std::string uname = cmSystemTools::UpperCase(name);
- std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
- const char* inFileName = this->GetOption(cpackVar.c_str());
- if (!inFileName) {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: "
- << cpackVar.c_str()
- << " not specified. It should point to "
- << (!name.empty() ? name : "<empty>") << ".rtf, " << name
- << ".html, or " << name << ".txt file" << std::endl);
- return false;
- }
- if (!cmSystemTools::FileExists(inFileName)) {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
- << (!name.empty() ? name : "<empty>")
- << " resource file: " << inFileName << std::endl);
- return false;
- }
- std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
- if (ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt") {
- cmCPackLogger(
- cmCPackLog::LOG_ERROR, "Bad file extension specified: "
- << ext
- << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
- << std::endl);
- return false;
- }
-
- std::string destFileName = dirName;
- destFileName += '/';
- destFileName += name + ext;
-
- // Set this so that distribution.dist gets the right name (without
- // the path).
- this->SetOption(("CPACK_RESOURCE_FILE_" + uname + "_NOPATH").c_str(),
- (name + ext).c_str());
-
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
- << (inFileName ? inFileName : "(NULL)") << " to "
- << destFileName.c_str() << std::endl);
- this->ConfigureFile(inFileName, destFileName.c_str());
- return true;
-}
-
-bool cmCPackPackageMakerGenerator::CopyResourcePlistFile(
- const std::string& name, const char* outName)
-{
- if (!outName) {
- outName = name.c_str();
- }
-
- std::string inFName = "CPack.";
- inFName += name;
- inFName += ".in";
- std::string inFileName = this->FindTemplate(inFName.c_str());
- if (inFileName.empty()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find input file: " << inFName << std::endl);
- return false;
- }
-
- std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- destFileName += "/";
- destFileName += outName;
-
- cmCPackLogger(cmCPackLog::LOG_VERBOSE,
- "Configure file: " << inFileName.c_str() << " to "
- << destFileName.c_str() << std::endl);
- this->ConfigureFile(inFileName.c_str(), destFileName.c_str());
- return true;
-}
-
bool cmCPackPackageMakerGenerator::RunPackageMaker(const char* command,
const char* packageFile)
{
@@ -597,21 +504,6 @@ bool cmCPackPackageMakerGenerator::RunPackageMaker(const char* command,
return true;
}
-std::string cmCPackPackageMakerGenerator::GetPackageName(
- const cmCPackComponent& component)
-{
- if (component.ArchiveFile.empty()) {
- std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- packagesDir += ".dummy";
- std::ostringstream out;
- out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-"
- << component.Name << ".pkg";
- return out.str();
- } else {
- return component.ArchiveFile + ".pkg";
- }
-}
-
bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
const char* packageFile, const char* packageDir,
const cmCPackComponent& component)
@@ -686,219 +578,3 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
// Run PackageMaker
return RunPackageMaker(pkgCmd.str().c_str(), packageFile);
}
-
-void cmCPackPackageMakerGenerator::WriteDistributionFile(
- const char* metapackageFile)
-{
- std::string distributionTemplate =
- this->FindTemplate("CPack.distribution.dist.in");
- if (distributionTemplate.empty()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
- << distributionTemplate << std::endl);
- return;
- }
-
- std::string distributionFile = metapackageFile;
- distributionFile += "/Contents/distribution.dist";
-
- // Create the choice outline, which provides a tree-based view of
- // the components in their groups.
- std::ostringstream choiceOut;
- choiceOut << "<choices-outline>" << std::endl;
-
- // Emit the outline for the groups
- std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
- for (groupIt = this->ComponentGroups.begin();
- groupIt != this->ComponentGroups.end(); ++groupIt) {
- if (groupIt->second.ParentGroup == 0) {
- CreateChoiceOutline(groupIt->second, choiceOut);
- }
- }
-
- // Emit the outline for the non-grouped components
- std::map<std::string, cmCPackComponent>::iterator compIt;
- for (compIt = this->Components.begin(); compIt != this->Components.end();
- ++compIt) {
- if (!compIt->second.Group) {
- choiceOut << "<line choice=\"" << compIt->first << "Choice\"></line>"
- << std::endl;
- }
- }
- if (!this->PostFlightComponent.Name.empty()) {
- choiceOut << "<line choice=\"" << PostFlightComponent.Name
- << "Choice\"></line>" << std::endl;
- }
- choiceOut << "</choices-outline>" << std::endl;
-
- // Create the actual choices
- for (groupIt = this->ComponentGroups.begin();
- groupIt != this->ComponentGroups.end(); ++groupIt) {
- CreateChoice(groupIt->second, choiceOut);
- }
- for (compIt = this->Components.begin(); compIt != this->Components.end();
- ++compIt) {
- CreateChoice(compIt->second, choiceOut);
- }
-
- if (!this->PostFlightComponent.Name.empty()) {
- CreateChoice(PostFlightComponent, choiceOut);
- }
-
- this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
-
- // Create the distribution.dist file in the metapackage to turn it
- // into a distribution package.
- this->ConfigureFile(distributionTemplate.c_str(), distributionFile.c_str());
-}
-
-void cmCPackPackageMakerGenerator::CreateChoiceOutline(
- const cmCPackComponentGroup& group, std::ostringstream& out)
-{
- 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();
- ++compIt) {
- out << " <line choice=\"" << (*compIt)->Name << "Choice\"></line>"
- << std::endl;
- }
- out << "</line>" << std::endl;
-}
-
-void cmCPackPackageMakerGenerator::CreateChoice(
- const cmCPackComponentGroup& group, std::ostringstream& out)
-{
- out << "<choice id=\"" << group.Name << "Choice\" "
- << "title=\"" << group.DisplayName << "\" "
- << "start_selected=\"true\" "
- << "start_enabled=\"true\" "
- << "start_visible=\"true\" ";
- if (!group.Description.empty()) {
- out << "description=\"" << EscapeForXML(group.Description) << "\"";
- }
- out << "></choice>" << std::endl;
-}
-
-void cmCPackPackageMakerGenerator::CreateChoice(
- const cmCPackComponent& component, std::ostringstream& out)
-{
- std::string packageId = "com.";
- packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
- packageId += '.';
- packageId += this->GetOption("CPACK_PACKAGE_NAME");
- packageId += '.';
- packageId += component.Name;
-
- out << "<choice id=\"" << component.Name << "Choice\" "
- << "title=\"" << component.DisplayName << "\" "
- << "start_selected=\""
- << (component.IsDisabledByDefault && !component.IsRequired ? "false"
- : "true")
- << "\" "
- << "start_enabled=\"" << (component.IsRequired ? "false" : "true")
- << "\" "
- << "start_visible=\"" << (component.IsHidden ? "false" : "true")
- << "\" ";
- if (!component.Description.empty()) {
- out << "description=\"" << EscapeForXML(component.Description) << "\" ";
- }
- if (!component.Dependencies.empty() ||
- !component.ReverseDependencies.empty()) {
- // The "selected" expression is evaluated each time any choice is
- // selected, for all choices *except* the one that the user
- // selected. A component is marked selected if it has been
- // selected (my.choice.selected in Javascript) and all of the
- // components it depends on have been selected (transitively) or
- // if any of the components that depend on it have been selected
- // (transitively). Assume that we have components A, B, C, D, and
- // E, where each component depends on the previous component (B
- // depends on A, C depends on B, D depends on C, and E depends on
- // D). The expression we build for the component C will be
- // my.choice.selected && B && A || D || E
- // This way, selecting C will automatically select everything it depends
- // on (B and A), while selecting something that depends on C--either D
- // or E--will automatically cause C to get selected.
- out << "selected=\"my.choice.selected";
- std::set<const cmCPackComponent*> visited;
- AddDependencyAttributes(component, visited, out);
- visited.clear();
- AddReverseDependencyAttributes(component, visited, out);
- out << "\"";
- }
- out << ">" << std::endl;
- out << " <pkg-ref id=\"" << packageId << "\"></pkg-ref>" << std::endl;
- out << "</choice>" << std::endl;
-
- // Create a description of the package associated with this
- // component.
- std::string relativePackageLocation = "Contents/Packages/";
- relativePackageLocation += this->GetPackageName(component);
-
- // Determine the installed size of the package.
- std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- dirName += '/';
- dirName += component.Name;
- dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
- unsigned long installedSize =
- component.GetInstalledSizeInKbytes(dirName.c_str());
-
- out << "<pkg-ref id=\"" << packageId << "\" "
- << "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" "
- << "installKBytes=\"" << installedSize << "\" "
- << "auth=\"Admin\" onConclusion=\"None\">";
- if (component.IsDownloaded) {
- out << this->GetOption("CPACK_DOWNLOAD_SITE")
- << this->GetPackageName(component);
- } else {
- out << "file:./" << relativePackageLocation;
- }
- out << "</pkg-ref>" << std::endl;
-}
-
-void cmCPackPackageMakerGenerator::AddDependencyAttributes(
- const cmCPackComponent& component,
- std::set<const cmCPackComponent*>& visited, std::ostringstream& out)
-{
- if (visited.find(&component) != visited.end()) {
- return;
- }
- visited.insert(&component);
-
- std::vector<cmCPackComponent*>::const_iterator dependIt;
- for (dependIt = component.Dependencies.begin();
- dependIt != component.Dependencies.end(); ++dependIt) {
- out << " &amp;&amp; choices['" << (*dependIt)->Name << "Choice'].selected";
- AddDependencyAttributes(**dependIt, visited, out);
- }
-}
-
-void cmCPackPackageMakerGenerator::AddReverseDependencyAttributes(
- const cmCPackComponent& component,
- std::set<const cmCPackComponent*>& visited, std::ostringstream& out)
-{
- if (visited.find(&component) != visited.end()) {
- return;
- }
- visited.insert(&component);
-
- std::vector<cmCPackComponent*>::const_iterator dependIt;
- for (dependIt = component.ReverseDependencies.begin();
- dependIt != component.ReverseDependencies.end(); ++dependIt) {
- out << " || choices['" << (*dependIt)->Name << "Choice'].selected";
- AddReverseDependencyAttributes(**dependIt, visited, out);
- }
-}
-
-std::string cmCPackPackageMakerGenerator::EscapeForXML(std::string str)
-{
- cmSystemTools::ReplaceString(str, "&", "&amp;");
- cmSystemTools::ReplaceString(str, "<", "&lt;");
- cmSystemTools::ReplaceString(str, ">", "&gt;");
- cmSystemTools::ReplaceString(str, "\"", "&quot;");
- return str;
-}
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h
index 2b8d253..5192377 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.h
+++ b/Source/CPack/cmCPackPackageMakerGenerator.h
@@ -13,7 +13,7 @@
#ifndef cmCPackPackageMakerGenerator_h
#define cmCPackPackageMakerGenerator_h
-#include "cmCPackGenerator.h"
+#include "cmCPackPKGGenerator.h"
class cmCPackComponent;
@@ -23,46 +23,28 @@ class cmCPackComponent;
* http://developer.apple.com/documentation/Darwin
* /Reference/ManPages/man1/packagemaker.1.html
*/
-class cmCPackPackageMakerGenerator : public cmCPackGenerator
+class cmCPackPackageMakerGenerator : public cmCPackPKGGenerator
{
public:
- cmCPackTypeMacro(cmCPackPackageMakerGenerator, cmCPackGenerator);
+ cmCPackTypeMacro(cmCPackPackageMakerGenerator, cmCPackPKGGenerator);
/**
* Construct generator
*/
cmCPackPackageMakerGenerator();
virtual ~cmCPackPackageMakerGenerator();
-
- virtual bool SupportsComponentInstallation() const;
+ bool SupportsComponentInstallation() const;
protected:
- int CopyInstallScript(const std::string& resdir, const std::string& script,
- const std::string& name);
virtual int InitializeInternal();
int PackageFiles();
virtual const char* GetOutputExtension() { return ".dmg"; }
- virtual const char* GetOutputPostfix() { return "darwin"; }
-
- // Copies or creates the resource file with the given name to the
- // package or package staging directory dirName. The variable
- // CPACK_RESOURCE_FILE_${NAME} (where ${NAME} is the uppercased
- // version of name) specifies the input file to use for this file,
- // which will be configured via ConfigureFile.
- bool CopyCreateResourceFile(const std::string& name,
- const std::string& dirName);
- bool CopyResourcePlistFile(const std::string& name, const char* outName = 0);
// Run PackageMaker with the given command line, which will (if
// successful) produce the given package file. Returns true if
// PackageMaker succeeds, false otherwise.
bool RunPackageMaker(const char* command, const char* packageFile);
- // Retrieve the name of package file that will be generated for this
- // component. The name is just the file name with extension, and
- // does not include the subdirectory.
- std::string GetPackageName(const cmCPackComponent& component);
-
// Generate a package in the file packageFile for the given
// component. All of the files within this component are stored in
// the directory packageDir. Returns true if successful, false
@@ -71,48 +53,6 @@ protected:
const char* packageDir,
const cmCPackComponent& component);
- // Writes a distribution.dist file, which turns a metapackage into a
- // full-fledged distribution. This file is used to describe
- // inter-component dependencies. metapackageFile is the name of the
- // metapackage for the distribution. Only valid for a
- // component-based install.
- void WriteDistributionFile(const char* metapackageFile);
-
- // Subroutine of WriteDistributionFile that writes out the
- // dependency attributes for inter-component dependencies.
- void AddDependencyAttributes(const cmCPackComponent& component,
- std::set<const cmCPackComponent*>& visited,
- std::ostringstream& out);
-
- // Subroutine of WriteDistributionFile that writes out the
- // reverse dependency attributes for inter-component dependencies.
- void AddReverseDependencyAttributes(
- const cmCPackComponent& component,
- std::set<const cmCPackComponent*>& visited, std::ostringstream& out);
-
- // Generates XML that encodes the hierarchy of component groups and
- // their components in a form that can be used by distribution
- // metapackages.
- void CreateChoiceOutline(const cmCPackComponentGroup& group,
- std::ostringstream& out);
-
- /// Create the "choice" XML element to describe a component group
- /// for the installer GUI.
- void CreateChoice(const cmCPackComponentGroup& group,
- std::ostringstream& out);
-
- /// Create the "choice" XML element to describe a component for the
- /// installer GUI.
- void CreateChoice(const cmCPackComponent& component,
- std::ostringstream& out);
-
- // Escape the given string to make it usable as an XML attribute
- // value.
- std::string EscapeForXML(std::string str);
-
- // The PostFlight component when creating a metapackage
- cmCPackComponent PostFlightComponent;
-
double PackageMakerVersion;
unsigned int PackageCompatibilityVersion;
};