Browse Source

ENH: One more patch from Doug Gregor including PackageMaker functionality for componentized-for-the-end-user and download-some-bit-on-demand installers.

David Cole 17 years ago
parent
commit
71f61636b6

+ 1 - 1
Modules/CPack.Info.plist.in

@@ -32,6 +32,6 @@
 <key>IFPkgFormatVersion</key>
 <key>IFPkgFormatVersion</key>
 <real>0.10000000149011612</real>
 <real>0.10000000149011612</real>
 <key>CFBundleIdentifier</key>
 <key>CFBundleIdentifier</key>
-<string>com.@CPACK_PACKAGE_VENDOR@.@CPACK_PACKAGE_NAME@.@CPACK_PACKAGE_VERSION@@CPACK_MODULE_VERSION_SUFFIX@</string>
+<string>com.@CPACK_PACKAGE_VENDOR@.@CPACK_PACKAGE_NAME@@CPACK_MODULE_VERSION_SUFFIX@</string>
 </dict>
 </dict>
 </plist>
 </plist>

+ 41 - 21
Modules/CPack.cmake

@@ -107,7 +107,7 @@
 #   that won't be packaged when building a source package. This is a
 #   that won't be packaged when building a source package. This is a
 #   list of patterns, e.g., /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*
 #   list of patterns, e.g., /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*
 #
 #
-# The following variables are specific to the graphical installers build
+# The following variables are specific to the graphical installers built
 # on Windows using the Nullsoft Installation System.
 # on Windows using the Nullsoft Installation System.
 #
 #
 #   CPACK_PACKAGE_INSTALL_REGISTRY_KEY - Registry key used when
 #   CPACK_PACKAGE_INSTALL_REGISTRY_KEY - Registry key used when
@@ -157,6 +157,22 @@
 #   CPACK_NSIS_DELETE_ICONS_EXTRA -Additional NSIS commands to
 #   CPACK_NSIS_DELETE_ICONS_EXTRA -Additional NSIS commands to
 #   uninstall start menu shortcuts.
 #   uninstall start menu shortcuts.
 #
 #
+# The following variable is specific to installers build on Mac OS X
+# using PackageMaker:
+#
+#   CPACK_OSX_PACKAGE_VERSION - The version of Mac OS X that the
+#   resulting PackageMaker archive should be compatible
+#   with. Different versions of Mac OS X support different
+#   features. For example, CPack can only build component-based
+#   installers for Mac OS X 10.4 or newer, and can only build
+#   installers that download component son-the-fly for Mac OS X 10.5
+#   or newer. If left blank, this value will be set to the minimum
+#   version of Mac OS X that supports the requested features. Set this
+#   variable to some value (e.g., 10.4) only if you want to guarantee
+#   that your installer will work on that version of Mac OS X, and
+#   don't mind missing extra features available in the installer
+#   shipping with later versions of Mac OS X.
+#
 # The following variables are for advanced uses of CPack:
 # The following variables are for advanced uses of CPack:
 #
 #
 #   CPACK_CMAKE_GENERATOR - What CMake generator should be used if the
 #   CPACK_CMAKE_GENERATOR - What CMake generator should be used if the
@@ -251,9 +267,9 @@
 #   installer itself. For more information, see the cpack_configure_downloads
 #   installer itself. For more information, see the cpack_configure_downloads
 #   command.
 #   command.
 #
 #
-#   ARCHIVE_FILE provides a name for the ZIP file created by CPack to
-#   be used for downloaded components. If not supplied, CPack will
-#   create ZIP file with some name based on CPACK_PACKAGE_FILE_NAME and
+#   ARCHIVE_FILE provides a name for the archive file created by CPack
+#   to be used for downloaded components. If not supplied, CPack will
+#   create a file with some name based on CPACK_PACKAGE_FILE_NAME and
 #   the name of the component. See cpack_configure_downloads for more
 #   the name of the component. See cpack_configure_downloads for more
 #   information.
 #   information.
 #
 #
@@ -330,30 +346,34 @@
 #
 #
 #   The cpack_configure_downloads command configures installation-time
 #   The cpack_configure_downloads command configures installation-time
 #   downloads of selected components. For each downloadable component,
 #   downloads of selected components. For each downloadable component,
-#   CPack will create a ZIP file containing the contents of that component,
-#   which should be uploaded to the given site. When the user selects that
-#   component for installation, the installer will download and extract
-#   the component in place. This feature is useful for creating small
-#   installers that only download the requested components, saving
-#   bandwidth. Additionally, the installers are small enough that they
-#   will be installed as part of the normal installation process, and the 
-#   "Change" button in Windows Add/Remove Programs control panel will
-#   allow one to add or remove parts of the application after the original
-#   installation. The downloaded-components functionality is currently
-#   only available with the NSIS generator on Windows. It requires the
-#   ZipDLL plug-in for NSIS, available at:
+#   CPack will create an archive containing the contents of that
+#   component, which should be uploaded to the given site. When the
+#   user selects that component for installation, the installer will
+#   download and extract the component in place. This feature is
+#   useful for creating small installers that only download the
+#   requested components, saving bandwidth. Additionally, the
+#   installers are small enough that they will be installed as part of
+#   the normal installation process, and the "Change" button in
+#   Windows Add/Remove Programs control panel will allow one to add or
+#   remove parts of the application after the original
+#   installation. On Windows, the downloaded-components functionality
+#   requires the ZipDLL plug-in for NSIS, available at:
 #
 #
 #     http://nsis.sourceforge.net/ZipDLL_plug-in
 #     http://nsis.sourceforge.net/ZipDLL_plug-in
 #
 #
-#   The site argument is a URL where the ZIP files for downloadable 
+#   On Mac OS X, installers that download components on-the-fly can
+#   only be built and installed on system using Mac OS X 10.5 or
+#   later.
+#
+#   The site argument is a URL where the archives for downloadable 
 #   components will reside, e.g., http://www.cmake.org/files/2.6.1/installer/
 #   components will reside, e.g., http://www.cmake.org/files/2.6.1/installer/
-#   All of the ZIP files produced by CPack should be uploaded to that location.
+#   All of the archives produced by CPack should be uploaded to that location.
 #
 #
 #   UPLOAD_DIRECTORY is the local directory where CPack will create the 
 #   UPLOAD_DIRECTORY is the local directory where CPack will create the 
-#   various .ZIP archives for each of the components. The contents of this
+#   various archives for each of the components. The contents of this
 #   directory should be uploaded to a location accessible by the URL given
 #   directory should be uploaded to a location accessible by the URL given
 #   in the site argument. If omitted, CPack will use the directory CPackUploads
 #   in the site argument. If omitted, CPack will use the directory CPackUploads
-#   inside the CMake binary directory to store the generated ZIP files.
+#   inside the CMake binary directory to store the generated archives.
 #
 #
 #   The ALL flag indicates that all components be downloaded. Otherwise, only 
 #   The ALL flag indicates that all components be downloaded. Otherwise, only 
 #   those components explicitly marked as DOWNLOADED or that have a specified 
 #   those components explicitly marked as DOWNLOADED or that have a specified 
@@ -363,7 +383,7 @@
 #   ADD_REMOVE indicates that CPack should install a copy of the installer
 #   ADD_REMOVE indicates that CPack should install a copy of the installer
 #   that can be called from Windows' Add/Remove Programs dialog (via the 
 #   that can be called from Windows' Add/Remove Programs dialog (via the 
 #   "Modify" button) to change the set of installed components. NO_ADD_REMOVE
 #   "Modify" button) to change the set of installed components. NO_ADD_REMOVE
-#   turns off this behavior.
+#   turns off this behavior. This option is ignored on Mac OS X.
 
 
 
 
 # Pick a configuration file
 # Pick a configuration file

+ 1 - 0
Source/CMakeLists.txt

@@ -349,6 +349,7 @@ TARGET_LINK_LIBRARIES(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_L
 # Sources for CPack
 # Sources for CPack
 #
 #
 SET(CPACK_SRCS
 SET(CPACK_SRCS
+  CPack/cmCPackComponentGroup.cxx
   CPack/cmCPackGeneratorFactory.cxx
   CPack/cmCPackGeneratorFactory.cxx
   CPack/cmCPackGenerator.cxx
   CPack/cmCPackGenerator.cxx
   CPack/cmCPackLog.cxx
   CPack/cmCPackLog.cxx

+ 49 - 0
Source/CPack/cmCPackComponentGroup.cxx

@@ -0,0 +1,49 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include "cmCPackComponentGroup.h"
+#include "cmSystemTools.h"
+#include <vector>
+#include <string>
+
+//----------------------------------------------------------------------
+unsigned long cmCPackComponent::GetInstalledSize(const char* installDir) const
+{
+  if (this->TotalSize != 0)
+    {
+    return this->TotalSize;
+    }
+
+  std::vector<std::string>::const_iterator fileIt;
+  for (fileIt = this->Files.begin(); fileIt != this->Files.end(); ++fileIt)
+    {
+    std::string path = installDir;
+    path += '/';
+    path += *fileIt;
+    this->TotalSize += cmSystemTools::FileLength(path.c_str());
+    }
+
+  return this->TotalSize;
+}
+
+//----------------------------------------------------------------------
+unsigned long 
+cmCPackComponent::GetInstalledSizeInKbytes(const char* installDir) const
+{
+  unsigned long result = (GetInstalledSize(installDir) + 512) / 1024;
+  return result? result : 1;
+}

+ 13 - 1
Source/CPack/cmCPackComponentGroup.h

@@ -49,7 +49,7 @@ public:
 class cmCPackComponent
 class cmCPackComponent
 {
 {
 public:
 public:
-  cmCPackComponent() : Group(0) { }
+ cmCPackComponent() : Group(0), TotalSize(0) { }
 
 
   /// The name of the component (used to reference the component).
   /// The name of the component (used to reference the component).
   std::string Name;
   std::string Name;
@@ -95,6 +95,18 @@ public:
 
 
   /// The list of installed directories that are part of this component.
   /// The list of installed directories that are part of this component.
   std::vector<std::string> Directories;
   std::vector<std::string> Directories;
+
+  /// Get the total installed size of all of the files in this
+  /// component, in bytes. installDir is the directory into which the 
+  /// component was installed.
+  unsigned long GetInstalledSize(const char* installDir) const;
+
+  /// Identical to GetInstalledSize, but returns the result in
+  /// kilobytes.
+  unsigned long GetInstalledSizeInKbytes(const char* installDir) const;
+
+ private:
+  mutable unsigned long TotalSize;
 };
 };
 
 
 /** \class cmCPackComponentGroup
 /** \class cmCPackComponentGroup

+ 191 - 98
Source/CPack/cmCPackPackageMakerGenerator.cxx

@@ -32,6 +32,7 @@
 cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
 cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
 {
 {
   this->PackageMakerVersion = 0.0;
   this->PackageMakerVersion = 0.0;
+  this->PackageCompatibilityVersion = 10.4;
 }
 }
 
 
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
@@ -42,7 +43,7 @@ cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator()
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
 bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
 bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
 {
 {
-  return true;
+  return this->PackageCompatibilityVersion >= 10.4;
 }
 }
 
 
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
@@ -165,7 +166,7 @@ int cmCPackPackageMakerGenerator::CompressFiles(const char* outFileName,
 
 
   if (!this->Components.empty())
   if (!this->Components.empty())
     {
     {
-    // Create the directory where component packages will be installed.
+    // Create the directory where component packages will be built.
     std::string basePackageDir = packageDirFileName;
     std::string basePackageDir = packageDirFileName;
     basePackageDir += "/Contents/Packages";
     basePackageDir += "/Contents/Packages";
     if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str()))
     if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str()))
@@ -176,12 +177,78 @@ int cmCPackPackageMakerGenerator::CompressFiles(const char* outFileName,
       return 0;
       return 0;
       }
       }
 
 
+    // Create the directory where downloaded component packages will
+    // be placed.
+    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";
+      }
+
     // Create packages for each component
     // Create packages for each component
+    bool warnedAboutDownloadCompatibility = false;
+
     std::map<std::string, cmCPackComponent>::iterator compIt;
     std::map<std::string, cmCPackComponent>::iterator compIt;
     for (compIt = this->Components.begin(); compIt != this->Components.end();
     for (compIt = this->Components.begin(); compIt != this->Components.end();
          ++compIt)
          ++compIt)
       {
       {
-      std::string packageFile = basePackageDir;
+      std::string packageFile;
+      if (compIt->second.IsDownloaded)
+        {
+        if (this->PackageCompatibilityVersion >= 10.5 &&
+            this->PackageMakerVersion >= 3.0)
+          {
+          // Build this package within the upload directory.
+          packageFile = uploadDirectory;
+
+          if(!cmSystemTools::FileExists(uploadDirectory.c_str()))
+            {
+            if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str()))
+              {
+              cmCPackLogger(cmCPackLog::LOG_ERROR,
+                            "Unable to create package upload directory " 
+                            << uploadDirectory << std::endl);
+              return 0;
+              }
+            }
+          }
+        else if (!warnedAboutDownloadCompatibility)
+          {
+          if (this->PackageCompatibilityVersion < 10.5)
+            {
+            cmCPackLogger(cmCPackLog::LOG_WARNING,
+                        "CPack warning: please set CPACK_OSX_PACKAGE_VERSION to 10.5 or greater enable downloaded packages. CPack will build a non-downloaded package."
+                          << std::endl);
+            }
+
+          if (this->PackageMakerVersion < 3)
+            {
+            cmCPackLogger(cmCPackLog::LOG_WARNING,
+                        "CPack warning: unable to build downloaded packages with PackageMaker versions prior to 3.0. CPack will build a non-downloaded package."
+                          << std::endl);
+            }
+
+          warnedAboutDownloadCompatibility = true;
+          }
+        }
+
+      if (packageFile.empty())
+        {
+        // Build this package within the overall distribution
+        // metapackage.
+        packageFile = basePackageDir;
+
+        // We're not downloading this component, even if the user
+        // requested it.
+        compIt->second.IsDownloaded = false;
+        }
+
       packageFile += '/';
       packageFile += '/';
       packageFile += GetPackageName(compIt->second);
       packageFile += GetPackageName(compIt->second);
 
 
@@ -229,7 +296,7 @@ int cmCPackPackageMakerGenerator::CompressFiles(const char* outFileName,
            << "/Resources\" -i \""
            << "/Resources\" -i \""
            << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") 
            << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") 
            << "/Info.plist\" -d \""
            << "/Info.plist\" -d \""
-           << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") 
+           << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
            << "/Description.plist\"";
            << "/Description.plist\"";
     if ( this->PackageMakerVersion > 2.0 )
     if ( this->PackageMakerVersion > 2.0 )
       {
       {
@@ -339,6 +406,30 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
   cmCPackLogger(cmCPackLog::LOG_DEBUG, "PackageMaker version is: "
   cmCPackLogger(cmCPackLog::LOG_DEBUG, "PackageMaker version is: "
     << this->PackageMakerVersion << std::endl);
     << this->PackageMakerVersion << std::endl);
 
 
+  // Determine the package compatibility version. If it wasn't
+  // specified by the user, we define it based on which features the
+  // user requested.
+  const char *packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION");
+  if (packageCompat && *packageCompat)
+    {
+    this->PackageCompatibilityVersion = atof(packageCompat);  
+    }
+  else if (this->GetOption("CPACK_DOWNLOAD_SITE"))
+    {
+    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5");
+    this->PackageCompatibilityVersion = 10.5;
+    }
+  else if (this->GetOption("CPACK_COMPONENTS_ALL"))
+    {
+    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4");
+    this->PackageCompatibilityVersion = 10.4;
+    }
+  else
+    {
+    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3");
+    this->PackageCompatibilityVersion = 10.3;
+    }
+
   pkgPath += "/MacOS";
   pkgPath += "/MacOS";
   path.push_back(pkgPath);
   path.push_back(pkgPath);
   pkgPath = cmSystemTools::FindProgram("PackageMaker", path, false);
   pkgPath = cmSystemTools::FindProgram("PackageMaker", path, false);
@@ -491,12 +582,19 @@ bool cmCPackPackageMakerGenerator::RunPackageMaker(const char *command,
 std::string 
 std::string 
 cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component)
 cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component)
 {
 {
-  std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
-  packagesDir += ".dummy";
-  cmOStringStream out;
-  out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
-      << "-" << component.Name << ".pkg";
-  return out.str();
+  if (component.ArchiveFile.empty())
+    {
+    std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+    packagesDir += ".dummy";
+    cmOStringStream out;
+    out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
+        << "-" << component.Name << ".pkg";
+    return out.str();
+    }
+  else
+    {
+    return component.ArchiveFile + ".pkg";
+    }
 }
 }
 
 
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
@@ -509,46 +607,74 @@ GenerateComponentPackage(const char *packageFile,
   cmCPackLogger(cmCPackLog::LOG_OUTPUT,
   cmCPackLogger(cmCPackLog::LOG_OUTPUT,
                 "-   Building component package: " << packageFile << std::endl);
                 "-   Building component package: " << packageFile << std::endl);
 
 
-  // Create the description file for this component.
-  std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-  descriptionFile += '/' + component.Name + "-Description.plist";
-  std::ofstream out(descriptionFile.c_str());
-  out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
-      << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
-      << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << std::endl
-      << "<plist version=\"1.4\">" << std::endl
-      << "<dict>" << std::endl
-      << "  <key>IFPkgDescriptionTitle</key>" << std::endl
-      << "  <string>" << component.DisplayName << "</string>" << std::endl
-      << "  <key>IFPkgDescriptionVersion</key>" << std::endl
-      << "  <string>" << this->GetOption("CPACK_PACKAGE_VERSION") 
-      << "</string>" << std::endl
-      << "  <key>IFPkgDescriptionDescription</key>" << std::endl
-      << "  <string>" + this->EscapeForXML(component.Description) 
-      << "</string>" << std::endl
-      << "</dict>" << std::endl
-      << "</plist>" << std::endl;
-  out.close();
-
-  // Create the Info.plist file for this component
-  std::string moduleVersionSuffix = ".";
-  moduleVersionSuffix += component.Name;
-  this->SetOption("CPACK_MODULE_VERSION_SUFFIX", moduleVersionSuffix.c_str());
-  std::string infoFileName = component.Name;
-  infoFileName += "-Info.plist";
-  if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str()))
+  // The command that will be used to run PackageMaker
+  cmOStringStream pkgCmd;
+
+  if (this->PackageCompatibilityVersion < 10.5 || 
+      this->PackageMakerVersion < 3.0)
+    {
+    // Create Description.plist and Info.plist files for normal Mac OS
+    // X packages, which work on Mac OS X 10.3 and newer.
+    std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+    descriptionFile += '/' + component.Name + "-Description.plist";
+    std::ofstream out(descriptionFile.c_str());
+    out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
+        << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
+        << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << std::endl
+        << "<plist version=\"1.4\">" << std::endl
+        << "<dict>" << std::endl
+        << "  <key>IFPkgDescriptionTitle</key>" << std::endl
+        << "  <string>" << component.DisplayName << "</string>" << std::endl
+        << "  <key>IFPkgDescriptionVersion</key>" << std::endl
+        << "  <string>" << this->GetOption("CPACK_PACKAGE_VERSION") 
+        << "</string>" << std::endl
+        << "  <key>IFPkgDescriptionDescription</key>" << std::endl
+        << "  <string>" + this->EscapeForXML(component.Description) 
+        << "</string>" << std::endl
+        << "</dict>" << std::endl
+        << "</plist>" << std::endl;
+    out.close();
+
+    // Create the Info.plist file for this component
+    std::string moduleVersionSuffix = ".";
+    moduleVersionSuffix += component.Name;
+    this->SetOption("CPACK_MODULE_VERSION_SUFFIX", moduleVersionSuffix.c_str());
+    std::string infoFileName = component.Name;
+    infoFileName += "-Info.plist";
+    if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str()))
+      {
+      return false;
+      }
+
+    pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
+           << "\" -build -p \"" << packageFile << "\""
+           << " -f \"" << packageDir << "\""
+           << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") 
+           << "/" << infoFileName << "\""
+           << " -d \"" << descriptionFile << "\""; 
+    }
+  else
     {
     {
-    return false;
+    // Create a "flat" package on Mac OS X 10.5 and newer. Flat
+    // packages are stored in a single file, rather than a directory
+    // like normal packages, and can be downloaded by the installer
+    // on-the-fly in Mac OS X 10.5 or newer. Thus, we need to create
+    // flat packages when the packages will be downloaded on the fly.
+    std::string pkgId = "com.";
+    pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
+    pkgId += '.';
+    pkgId += this->GetOption("CPACK_PACKAGE_NAME");
+    pkgId += '.';
+    pkgId += component.Name;
+
+    pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
+           << "\" --root \"" << packageDir << "\""
+           << " --id " << pkgId
+           << " --target " << this->GetOption("CPACK_OSX_PACKAGE_VERSION")
+           << " --out \"" << packageFile << "\"";
     }
     }
 
 
   // Run PackageMaker  
   // Run PackageMaker  
-  cmOStringStream pkgCmd;
-  pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
-         << "\" -build -p \"" << packageFile << "\""
-         << " -f \"" << packageDir << "\""
-         << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") 
-         << "/" << infoFileName << "\""
-         << " -d \"" << descriptionFile << "\""; 
   return RunPackageMaker(pkgCmd.str().c_str(), packageFile);
   return RunPackageMaker(pkgCmd.str().c_str(), packageFile);
 }
 }
 
 
@@ -670,8 +796,6 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component,
   packageId += '.'; 
   packageId += '.'; 
   packageId += this->GetOption("CPACK_PACKAGE_NAME");
   packageId += this->GetOption("CPACK_PACKAGE_NAME");
   packageId += '.';
   packageId += '.';
-  packageId += this->GetOption("CPACK_PACKAGE_VERSION");
-  packageId += '.';
   packageId += component.Name;
   packageId += component.Name;
 
 
   out << "<choice id=\"" << component.Name << "Choice\" " 
   out << "<choice id=\"" << component.Name << "Choice\" " 
@@ -716,60 +840,29 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component,
   // Create a description of the package associated with this
   // Create a description of the package associated with this
   // component.
   // component.
   std::string relativePackageLocation = "Contents/Packages/";
   std::string relativePackageLocation = "Contents/Packages/";
-  relativePackageLocation += GetPackageName(component);
-
-  // Determine the installed size of the package. To do so, we dig
-  // into the Info.plist file from the generated package to retrieve
-  // this size.
-  int installedSize = 0;
-  std::string infoPlistFile = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
-  infoPlistFile += ".mpkg/";
-  infoPlistFile += relativePackageLocation;
-  infoPlistFile += "/Contents/Info.plist";
-  bool foundFlagInstalledSize = false;
-  std::string line;
-  std::ifstream ifs(infoPlistFile.c_str());
-  while ( cmSystemTools::GetLineFromStream(ifs, line) )
-    {
-      if (foundFlagInstalledSize)
-        {
-        std::string::size_type pos = line.find("<integer>");
-        if (pos == std::string::npos)
-          {
-          cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot parse package size in "
-                        << infoPlistFile << std::endl
-                        << "String is \"" << line << "\"" << std::endl);
-          }
-        else
-          {
-          line.erase(0, pos + 9);
-          pos = line.find("</integer>");
-          if (pos == std::string::npos)
-            {
-            cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot parse package size in "
-                          << infoPlistFile << std::endl);
-            }
-          else
-            {
-            line.erase(pos, std::string::npos);
-            installedSize = atoi(line.c_str());
-            }
-          }
-        foundFlagInstalledSize = false;
-        }
-      else 
-        {
-        foundFlagInstalledSize 
-          = line.find("IFPkgFlagInstalledSize") != std::string::npos;
-        }
-    }
-  
+  relativePackageLocation += this->GetPackageName(component);
+
+  // Determine the installed size of the package.
+  std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+  dirName += '/';
+  dirName += component.Name;
+  unsigned long installedSize 
+    = component.GetInstalledSizeInKbytes(dirName.c_str());
 
 
   out << "<pkg-ref id=\"" << packageId << "\" "
   out << "<pkg-ref id=\"" << packageId << "\" "
       << "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" "
       << "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" "
       << "installKBytes=\"" << installedSize << "\" "
       << "installKBytes=\"" << installedSize << "\" "
-      << "auth=\"Admin\" onConclusion=\"None\">"
-      << "file:./" << relativePackageLocation << "</pkg-ref>" << std::endl;
+      << "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;
 }
 }
 
 
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------

+ 1 - 0
Source/CPack/cmCPackPackageMakerGenerator.h

@@ -116,6 +116,7 @@ protected:
   std::string EscapeForXML(std::string str);
   std::string EscapeForXML(std::string str);
   
   
   double PackageMakerVersion;
   double PackageMakerVersion;
+  double PackageCompatibilityVersion;
 };
 };
 
 
 #endif
 #endif