[Cmake-commits] CMake branch, next, updated. v3.5.2-844-gb746bd5

Clinton Stimpson clinton at elemtech.com
Thu Jun 2 11:52:38 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  b746bd5c9941cf4747fedd4822ea9660d10a00c5 (commit)
       via  09bb6f89aa3c7f2b5dfcc52bd0d59f97c28503eb (commit)
       via  50a3d34005ec923db3d76d0a5d118437a7632617 (commit)
      from  68e77a5f3048019731b59e91b1e303f7a13f83a7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b746bd5c9941cf4747fedd4822ea9660d10a00c5
commit b746bd5c9941cf4747fedd4822ea9660d10a00c5
Merge: 68e77a5 09bb6f8
Author:     Clinton Stimpson <clinton at elemtech.com>
AuthorDate: Thu Jun 2 11:52:36 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Jun 2 11:52:36 2016 -0400

    Merge topic 'productbuild' into next
    
    09bb6f89 productbuild: Add new productbuild cpack generator.
    50a3d340 PackageMaker: factor out common code for creating pkg files.


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=09bb6f89aa3c7f2b5dfcc52bd0d59f97c28503eb
commit 09bb6f89aa3c7f2b5dfcc52bd0d59f97c28503eb
Author:     Clinton Stimpson <clinton at elemtech.com>
AuthorDate: Sat Nov 2 10:24:53 2013 -0600
Commit:     Clinton Stimpson <clinton at elemtech.com>
CommitDate: Wed Jun 1 21:56:54 2016 -0600

    productbuild: Add new productbuild cpack generator.
    
    This cpack generator basically replaces the obsolete PackageMaker generator.

diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 77f854d..4d51a3e 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -455,6 +455,7 @@ if(NOT CPACK_GENERATOR)
         option(CPACK_BINARY_DRAGNDROP    "Enable to build OSX Drag And Drop package" OFF)
         option(CPACK_BINARY_OSXX11       "Enable to build OSX X11 packages"      OFF)
         option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages" OFF)
+        option(CPACK_BINARY_PRODUCTBUILD "Enable to build productbuild packages" OFF)
       else()
         option(CPACK_BINARY_TZ  "Enable to build TZ packages"     ON)
       endif()
@@ -483,6 +484,7 @@ if(NOT CPACK_GENERATOR)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_NSIS         NSIS)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_OSXX11       OSXX11)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_PACKAGEMAKER PackageMaker)
+  cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_PRODUCTBUILD productbuild)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_RPM          RPM)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_STGZ         STGZ)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TBZ2         TBZ2)
@@ -531,6 +533,7 @@ mark_as_advanced(
   CPACK_BINARY_NSIS
   CPACK_BINARY_OSXX11
   CPACK_BINARY_PACKAGEMAKER
+  CPACK_BINARY_PRODUCTBUILD
   CPACK_BINARY_RPM
   CPACK_BINARY_STGZ
   CPACK_BINARY_TBZ2
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index f85f143..7cf11ca 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -719,6 +719,7 @@ if(APPLE)
     CPack/cmCPackOSXX11Generator.cxx
     CPack/cmCPackPKGGenerator.cxx
     CPack/cmCPackPackageMakerGenerator.cxx
+    CPack/cmCPackProductBuildGenerator.cxx
     )
 endif()
 
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index b17f52e..cf072bb 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -28,6 +28,7 @@
 #include "cmCPackDragNDropGenerator.h"
 #include "cmCPackOSXX11Generator.h"
 #include "cmCPackPackageMakerGenerator.h"
+#include "cmCPackProductBuildGenerator.h"
 #endif
 
 #ifdef __CYGWIN__
@@ -122,6 +123,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
     this->RegisterGenerator("OSXX11", "Mac OSX X11 bundle",
                             cmCPackOSXX11Generator::CreateGenerator);
   }
+  if (cmCPackProductBuildGenerator::CanGenerate()) {
+    this->RegisterGenerator("productbuild", "Mac OSX pkg",
+      cmCPackProductBuildGenerator::CreateGenerator);
+  }
 #endif
 #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) &&         \
   !defined(__HAIKU__)
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 8282714..ff0fa8c 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -41,7 +41,6 @@ int cmCPackPKGGenerator::InitializeInternal()
 {
   cmCPackLogger(cmCPackLog::LOG_DEBUG,
                 "cmCPackPKGGenerator::Initialize()" << std::endl);
-  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
 
   return this->Superclass::InitializeInternal();
 }
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index e50c2e6..5bb24c0 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -329,6 +329,8 @@ int cmCPackPackageMakerGenerator::PackageFiles()
 
 int cmCPackPackageMakerGenerator::InitializeInternal()
 {
+  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
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
new file mode 100644
index 0000000..44adccd
--- /dev/null
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -0,0 +1,258 @@
+/*============================================================================
+  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 "cmCPackProductBuildGenerator.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>
+
+cmCPackProductBuildGenerator::cmCPackProductBuildGenerator()
+{
+  this->componentPackageMethod = ONE_PACKAGE;
+}
+
+cmCPackProductBuildGenerator::~cmCPackProductBuildGenerator()
+{
+}
+
+int cmCPackProductBuildGenerator::PackageFiles()
+{
+  // TODO: Use toplevel
+  //       It is used! Is this an obsolete comment?
+
+  std::string packageDirFileName
+    = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+
+  // Create the directory where component packages will be built.
+  std::string basePackageDir = packageDirFileName;
+  basePackageDir += "/Contents/Packages";
+  if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str()))
+  {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Problem creating component packages directory: "
+                  << basePackageDir.c_str() << std::endl);
+    return 0;
+  }
+
+  if (!this->Components.empty())
+    {
+    std::map<std::string, cmCPackComponent>::iterator compIt;
+    for (compIt = this->Components.begin(); compIt != this->Components.end();
+         ++compIt)
+      {
+      std::string packageDir = toplevel;
+      packageDir += '/';
+      packageDir += compIt->first;
+      if (!this->GenerateComponentPackage(basePackageDir,
+                                          GetPackageName(compIt->second),
+                                          packageDir,
+                                          &compIt->second))
+        {
+        return 0;
+        }
+      }
+    }
+  else
+  {
+    if(!this->GenerateComponentPackage(basePackageDir,
+                                       this->GetOption("CPACK_PACKAGE_NAME"),
+                                       toplevel, NULL))
+    {
+      return 0;
+    }
+  }
+
+  // Copy or create all of the resource files we need.
+  std::string resDir = packageDirFileName + "/Contents";
+  if ( !this->CopyCreateResourceFile("License", resDir.c_str())
+      || !this->CopyCreateResourceFile("ReadMe", resDir.c_str())
+      || !this->CopyCreateResourceFile("Welcome", resDir.c_str()))
+  {
+    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
+                  << std::endl);
+    return 0;
+  }
+
+  // combine package(s) into a distribution
+  WriteDistributionFile(packageDirFileName.c_str());
+  std::ostringstream pkgCmd;
+
+  std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
+  std::string productbuild = this->GetOption("CPACK_COMMAND_PRODUCTBUILD");
+
+  pkgCmd << productbuild
+  << " --distribution \"" << packageDirFileName << "/Contents/distribution.dist\""
+  << " --package-path \"" << packageDirFileName << "/Contents/Packages" << "\""
+  << " --resources \"" << resDir << "\""
+  << " --version \"" << version << "\""
+  << " \"" << packageFileNames[0] << "\"";
+
+  // Run ProductBuild
+  return RunProductBuild(pkgCmd.str(), packageFileNames[0]);
+}
+
+int cmCPackProductBuildGenerator::InitializeInternal()
+{
+  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/Applications");
+
+  std::vector<std::string> no_paths;
+  std::string program =
+    cmSystemTools::FindProgram("pkgbuild", no_paths, false);
+  if (program.empty()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find pkgbuild executable"
+                    << std::endl);
+    return 0;
+  }
+  this->SetOptionIfNotSet("CPACK_COMMAND_PKGBUILD", program.c_str());
+
+
+  program = cmSystemTools::FindProgram("productbuild", no_paths, false);
+  if (program.empty()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find productbuild executable"
+                    << std::endl);
+    return 0;
+  }
+  this->SetOptionIfNotSet("CPACK_COMMAND_PRODUCTBUILD", program.c_str());
+
+  return this->Superclass::InitializeInternal();
+}
+
+
+bool cmCPackProductBuildGenerator::RunProductBuild(const std::string& command,
+                                                   const std::string& packageFile)
+{
+  std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+  tmpFile += "/ProductBuildOutput.log";
+
+  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
+  std::string output, stderr;
+  int retVal = 1;
+  bool res = cmSystemTools::RunSingleCommand(command.c_str(), &output, &stderr, &retVal, 0,
+                                             this->GeneratorVerbose, 0);
+  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running command"
+    << std::endl);
+  if ( !res || retVal )
+    {
+    cmGeneratedFileStream ofs(tmpFile.c_str());
+    ofs << "# Run command: " << command << std::endl
+      << "# Output:" << std::endl
+      << output.c_str() << std::endl;
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Problem running command: " << command
+      << std::endl << "Please check " << tmpFile.c_str() << " for errors"
+      << std::endl);
+    return false;
+    }
+  return true;
+}
+
+bool cmCPackProductBuildGenerator::GenerateComponentPackage(
+  const std::string& packageFileDir,
+  const std::string& packageFileName,
+  const std::string& packageDir,
+  const cmCPackComponent* component)
+{
+  std::string packageFile = packageFileDir;
+  packageFile += '/';
+  packageFile += packageFileName;
+
+  cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                "-   Building component package: " <<
+                packageFile << std::endl);
+
+  const char* comp_name = component ? component->Name.c_str() : NULL;
+
+  const char* preflight = this->GetComponentScript("PREFLIGHT", comp_name);
+  const char* postflight = this->GetComponentScript("POSTFLIGHT", comp_name);
+
+  std::string resDir = packageFileDir;
+  if(component)
+  {
+    resDir += "/";
+    resDir += component->Name;
+  }
+  std::string scriptDir = resDir + "/scripts";
+
+  if ( !cmsys::SystemTools::MakeDirectory(scriptDir.c_str()))
+  {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Problem creating installer directory: "
+                  << scriptDir.c_str() << std::endl);
+    return 0;
+  }
+
+  // if preflight, postflight, or postupgrade are set
+  // then copy them into the script directory and make
+  // them executable
+  if(preflight)
+  {
+    this->CopyInstallScript(scriptDir.c_str(),
+                            preflight,
+                            "preinstall");
+  }
+  if(postflight)
+  {
+    this->CopyInstallScript(scriptDir.c_str(),
+                            postflight,
+                            "postinstall");
+  }
+
+
+  // The command that will be used to run ProductBuild
+  std::ostringstream pkgCmd;
+
+  std::string pkgId = "com.";
+  pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
+  pkgId += '.';
+  pkgId += this->GetOption("CPACK_PACKAGE_NAME");
+  if(component)
+    {
+    pkgId += '.';
+    pkgId += component->Name;
+    }
+
+  std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
+  std::string pkgbuild = this->GetOption("CPACK_COMMAND_PKGBUILD");
+
+  pkgCmd << pkgbuild
+         << " --root \"" << packageDir << "\""
+         << " --identifier \"" << pkgId << "\""
+         << " --scripts \"" << scriptDir << "\""
+         << " --version \"" << version << "\""
+         << " --install-location \"/\""
+         << " \"" << packageFile << "\"";
+
+  // Run ProductBuild
+  return RunProductBuild(pkgCmd.str(), packageFile);
+}
+
+const char* cmCPackProductBuildGenerator::GetComponentScript(const char* script,
+                                                             const char* component_name)
+{
+  std::string scriptname = std::string("CPACK_") + script + "_";
+  if(component_name)
+  {
+    scriptname += cmSystemTools::UpperCase(component_name);
+    scriptname += "_";
+  }
+  scriptname += "SCRIPT";
+
+  return this->GetOption(scriptname);
+}
diff --git a/Source/CPack/cmCPackProductBuildGenerator.h b/Source/CPack/cmCPackProductBuildGenerator.h
new file mode 100644
index 0000000..9cc9653
--- /dev/null
+++ b/Source/CPack/cmCPackProductBuildGenerator.h
@@ -0,0 +1,60 @@
+/*============================================================================
+  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 cmCPackProductBuildGenerator_h
+#define cmCPackProductBuildGenerator_h
+
+
+#include "cmCPackPKGGenerator.h"
+
+class cmCPackComponent;
+
+/** \class cmCPackProductBuildGenerator
+ * \brief A generator for ProductBuild files
+ *
+ */
+class cmCPackProductBuildGenerator : public cmCPackPKGGenerator
+{
+public:
+  cmCPackTypeMacro(cmCPackProductBuildGenerator, cmCPackPKGGenerator);
+
+  /**
+   * Construct generator
+   */
+  cmCPackProductBuildGenerator();
+  virtual ~cmCPackProductBuildGenerator();
+
+protected:
+  virtual int InitializeInternal();
+  int PackageFiles();
+  virtual const char* GetOutputExtension() { return ".pkg"; }
+
+  // Run ProductBuild with the given command line, which will (if
+  // successful) produce the given package file. Returns true if
+  // ProductBuild succeeds, false otherwise.
+  bool RunProductBuild(const std::string& command, const std::string& packageFile);
+
+  // 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
+  // otherwise.
+  bool GenerateComponentPackage(const std::string& packageFileDir,
+                                const std::string& packageFileName,
+                                const std::string& packageDir,
+                                const cmCPackComponent* component);
+
+  const char* GetComponentScript(const char* script,
+                                 const char* script_component);
+
+};
+
+#endif
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2db5ded..63d494f 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -951,6 +951,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     set(CPackComponents_BUILD_OPTIONS)
     if(APPLE)
       set(CPackComponents_BUILD_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON)
+      set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
+        -DCPACK_BINARY_PRODUCTBUILD:BOOL=ON)
     endif()
     if(NSIS_MAKENSIS_EXECUTABLE)
       set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
@@ -995,6 +997,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     list(APPEND ACTIVE_CPACK_GENERATORS "ZIP")
     if(APPLE)
       list(APPEND ACTIVE_CPACK_GENERATORS "DragNDrop")
+      list(APPEND ACTIVE_CPACK_GENERATORS "productbuild")
     endif()
 
     # set up list of component packaging ways
@@ -1105,6 +1108,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     set(CPackComponents_BUILD_OPTIONS)
     if(APPLE)
       set(CPackComponents_BUILD_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON)
+      set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
+        -DCPACK_BINARY_PRODUCTBUILD:BOOL=ON)
     endif()
     if(NOT NSIS_MAKENSIS_EXECUTABLE)
       set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=50a3d34005ec923db3d76d0a5d118437a7632617
commit 50a3d34005ec923db3d76d0a5d118437a7632617
Author:     Clinton Stimpson <clinton at elemtech.com>
AuthorDate: Mon Apr 4 18:53:05 2016 -0600
Commit:     Clinton Stimpson <clinton at elemtech.com>
CommitDate: Wed Jun 1 21:56:50 2016 -0600

    PackageMaker: factor out common code for creating pkg files.

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 << " && 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, "&", "&");
+  cmSystemTools::ReplaceString(str, "<", "<");
+  cmSystemTools::ReplaceString(str, ">", ">");
+  cmSystemTools::ReplaceString(str, "\"", """);
+  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/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPKGGenerator.h
similarity index 73%
copy from Source/CPack/cmCPackPackageMakerGenerator.h
copy to Source/CPack/cmCPackPKGGenerator.h
index 2b8d253..3011f78 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.h
+++ b/Source/CPack/cmCPackPKGGenerator.h
@@ -10,38 +10,33 @@
   See the License for more information.
 ============================================================================*/
 
-#ifndef cmCPackPackageMakerGenerator_h
-#define cmCPackPackageMakerGenerator_h
+#ifndef cmCPackPKGGenerator_h
+#define cmCPackPKGGenerator_h
+
 
 #include "cmCPackGenerator.h"
 
 class cmCPackComponent;
 
-/** \class cmCPackPackageMakerGenerator
- * \brief A generator for PackageMaker files
+/** \class cmCPackPKGGenerator
+ * \brief A generator for pkg files
  *
- * http://developer.apple.com/documentation/Darwin
- * /Reference/ManPages/man1/packagemaker.1.html
  */
-class cmCPackPackageMakerGenerator : public cmCPackGenerator
+class cmCPackPKGGenerator : public cmCPackGenerator
 {
 public:
-  cmCPackTypeMacro(cmCPackPackageMakerGenerator, cmCPackGenerator);
+  cmCPackTypeMacro(cmCPackPKGGenerator, cmCPackGenerator);
 
   /**
    * Construct generator
    */
-  cmCPackPackageMakerGenerator();
-  virtual ~cmCPackPackageMakerGenerator();
+  cmCPackPKGGenerator();
+  virtual ~cmCPackPKGGenerator();
 
   virtual 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
@@ -53,24 +48,14 @@ protected:
                               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);
+  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);
 
-  // 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
-  // otherwise.
-  bool GenerateComponentPackage(const char* packageFile,
-                                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
@@ -113,8 +98,6 @@ protected:
   // The PostFlight component when creating a metapackage
   cmCPackComponent PostFlightComponent;
 
-  double PackageMakerVersion;
-  unsigned int PackageCompatibilityVersion;
 };
 
 #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 << " && 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, "&", "&");
-  cmSystemTools::ReplaceString(str, "<", "<");
-  cmSystemTools::ReplaceString(str, ">", ">");
-  cmSystemTools::ReplaceString(str, "\"", """);
-  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;
 };

-----------------------------------------------------------------------

Summary of changes:
 Modules/CPack.cmake                                |    3 +
 Source/CMakeLists.txt                              |    2 +
 Source/CPack/cmCPackGeneratorFactory.cxx           |    5 +
 Source/CPack/cmCPackPKGGenerator.cxx               |  367 ++++++++++++++++++++
 ...ckageMakerGenerator.h => cmCPackPKGGenerator.h} |   39 +--
 Source/CPack/cmCPackPackageMakerGenerator.cxx      |  322 -----------------
 Source/CPack/cmCPackPackageMakerGenerator.h        |   68 +---
 Source/CPack/cmCPackProductBuildGenerator.cxx      |  258 ++++++++++++++
 Source/CPack/cmCPackProductBuildGenerator.h        |   60 ++++
 Tests/CMakeLists.txt                               |    5 +
 10 files changed, 715 insertions(+), 414 deletions(-)
 create mode 100644 Source/CPack/cmCPackPKGGenerator.cxx
 copy Source/CPack/{cmCPackPackageMakerGenerator.h => cmCPackPKGGenerator.h} (73%)
 create mode 100644 Source/CPack/cmCPackProductBuildGenerator.cxx
 create mode 100644 Source/CPack/cmCPackProductBuildGenerator.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list