[Cmake-commits] [cmake-commits] david.cole committed cmCPackBundleGenerator.cxx NONE 1.1 cmCPackBundleGenerator.h NONE 1.1 cmCPackGeneratorFactory.cxx 1.2 1.3

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Jun 18 09:53:31 EDT 2008


Update of /cvsroot/CMake/CMake/Source/CPack
In directory public:/mounts/ram/cvs-serv6761/Source/CPack

Modified Files:
	cmCPackGeneratorFactory.cxx 
Added Files:
	cmCPackBundleGenerator.cxx cmCPackBundleGenerator.h 
Log Message:
ENH: Apply patch for feature request #7170. Thanks to Tim Shead for contributing...


--- NEW FILE: cmCPackBundleGenerator.cxx ---
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmCPackBundleGenerator.cxx,v $
  Language:  C++
  Date:      $Date: 2008-06-18 13:53:28 $
  Version:   $Revision: 1.1 $

  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 "cmCPackBundleGenerator.h"
#include "cmCPackLog.h"
#include "cmSystemTools.h"

//----------------------------------------------------------------------
cmCPackBundleGenerator::cmCPackBundleGenerator()
{
}

//----------------------------------------------------------------------
cmCPackBundleGenerator::~cmCPackBundleGenerator()
{
}

//----------------------------------------------------------------------
int cmCPackBundleGenerator::InitializeInternal()
{
  const std::string hdiutil_path = cmSystemTools::FindProgram("hdiutil",
    std::vector<std::string>(), false);
  if(hdiutil_path.empty())
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot locate hdiutil command"
      << std::endl);
    return 0;
    }
  this->SetOptionIfNotSet("CPACK_COMMAND_HDIUTIL", hdiutil_path.c_str());

  const std::string setfile_path = cmSystemTools::FindProgram("SetFile",
    std::vector<std::string>(1, "/Developer/Tools"), false);
  if(setfile_path.empty())
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot locate SetFile command"
      << std::endl);
    return 0;
    }
  this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path.c_str());

  return this->Superclass::InitializeInternal();
}

//----------------------------------------------------------------------
const char* cmCPackBundleGenerator::GetOutputExtension()
{
  return ".dmg";
}

//----------------------------------------------------------------------
const char* cmCPackBundleGenerator::GetPackagingInstallPrefix()
{
  this->InstallPrefix = "/";
  this->InstallPrefix += this->GetOption("CPACK_BUNDLE_NAME");
  this->InstallPrefix += ".app/Contents/Resources";

  return this->InstallPrefix.c_str();
}

//----------------------------------------------------------------------
int cmCPackBundleGenerator::CompressFiles(const char* outFileName,
  const char* toplevel, const std::vector<std::string>& files)
{
  // The staging directory contains everything that will end-up inside the
  // final disk image ...
  cmOStringStream staging;
  staging << toplevel;

  cmOStringStream contents;
  contents << staging.str() << "/" << this->GetOption("CPACK_BUNDLE_NAME")
    << ".app/" << "Contents";

  cmOStringStream application;
  application << contents.str() << "/" << "MacOS";

  cmOStringStream resources;
  resources << contents.str() << "/" << "Resources";

  // Install a user-provided bundle metadata file ...
  if(this->GetOption("CPACK_BUNDLE_PLIST"))
    {
    cmOStringStream plist_source;
    plist_source << this->GetOption("CPACK_BUNDLE_PLIST");

    cmOStringStream plist_target;
    plist_target << contents.str() << "/" << "Info.plist";

    if(!this->CopyFile(plist_source, plist_target))
      {
      return 0;
      }
    }

  // Install a user-provided bundle icon ...
  if(this->GetOption("CPACK_BUNDLE_ICON"))
    {
    cmOStringStream icon_source;
    icon_source << this->GetOption("CPACK_BUNDLE_ICON");

    cmOStringStream icon_target;
    icon_target << resources.str() << "/"
      << this->GetOption("CPACK_BUNDLE_NAME") << ".icns";

    if(!this->CopyFile(icon_source, icon_target))
      {
      return 0;
      }
    }

  // Install a user-provided startup command (could be an executable or a
  // script) ...
  if(this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND"))
    {
    cmOStringStream command_source;
    command_source << this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND");

    cmOStringStream command_target;
    command_target << application.str() << "/"
      << this->GetOption("CPACK_BUNDLE_NAME");

    if(!this->CopyFile(command_source, command_target))
      {
      return 0;
      }

    cmSystemTools::SetPermissions(command_target.str().c_str(), 0777);
    }

  // Add a symlink to /Applications so users can drag-and-drop the bundle
  // into it
  cmOStringStream application_link;
  application_link << staging.str() << "/Applications";
  cmSystemTools::CreateSymlink("/Applications",
    application_link.str().c_str());

  // Optionally add a custom volume icon ...
  if(this->GetOption("CPACK_PACKAGE_ICON"))
    {
    cmOStringStream package_icon_source;
    package_icon_source << this->GetOption("CPACK_PACKAGE_ICON");

    cmOStringStream package_icon_destination;
    package_icon_destination << staging.str() << "/.VolumeIcon.icns";

    if(!this->CopyFile(package_icon_source, package_icon_destination))
      {
      return 0;
      }
    }

  // Create a temporary read-write disk image ...
  cmOStringStream temp_image;
  temp_image << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/temp.dmg";

  cmOStringStream temp_image_command;
  temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
  temp_image_command << " create";
  temp_image_command << " -ov";
  temp_image_command << " -srcfolder \"" << staging.str() << "\"";
  temp_image_command << " -volname \""
    << this->GetOption("CPACK_PACKAGE_FILE_NAME") << "\"";
  temp_image_command << " -format UDRW";
  temp_image_command << " \"" << temp_image.str() << "\"";

  if(!this->RunCommand(temp_image_command))
    {
    return 0;
    }

  // Optionally set the custom icon flag for the image ...
  if(this->GetOption("CPACK_PACKAGE_ICON"))
    {
    cmOStringStream temp_mount;
    temp_mount << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/mnt";
    cmSystemTools::MakeDirectory(temp_mount.str().c_str());

    cmOStringStream attach_command;
    attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
    attach_command << " attach";
    attach_command << " -mountpoint \"" << temp_mount.str() << "\"";
    attach_command << " \"" << temp_image.str() << "\"";

    if(!this->RunCommand(attach_command))
      {
      return 0;
      }

    cmOStringStream setfile_command;
    setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
    setfile_command << " -a C";
    setfile_command << " \"" << temp_mount.str() << "\"";

    if(!this->RunCommand(setfile_command))
      {
      return 0;
      }

    cmOStringStream detach_command;
    detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
    detach_command << " detach";
    detach_command << " \"" << temp_mount.str() << "\""; 

    if(!this->RunCommand(detach_command))
      {
      return 0;
      }
    }

  // Create the final compressed read-only disk image ...
  cmOStringStream final_image_command;
  final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
  final_image_command << " convert \"" << temp_image.str() << "\"";
  final_image_command << " -format UDZO";
  final_image_command << " -imagekey";
  final_image_command << " zlib-level=9";
  final_image_command << " -o \"" << outFileName << "\"";

  if(!this->RunCommand(final_image_command))
    {
    return 0;
    }

/*
  // Disk image directories
  std::string diskImageDirectory = toplevel;
  std::string diskImageBackgroundImageDir = diskImageDirectory
    + "/.background";

  // App bundle directories
  std::string packageDirFileName = toplevel;
  packageDirFileName += "/";
  packageDirFileName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
  packageDirFileName += ".app";
  std::string contentsDirectory = packageDirFileName + "/Contents";
  std::string resourcesDirectory = contentsDirectory + "/Resources";
  std::string appDirectory = contentsDirectory + "/MacOS";

  const char* dir = resourcesDirectory.c_str();
  const char* appdir = appDirectory.c_str();
  const char* contDir = contentsDirectory.c_str();
  const char* iconFile = this->GetOption("CPACK_PACKAGE_ICON");
  if ( iconFile )
    {
    std::string iconFileName = cmsys::SystemTools::GetFilenameName(iconFile);
    if ( !cmSystemTools::FileExists(iconFile) )
      {
      cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find icon file: "
        << iconFile << ". Please check CPACK_PACKAGE_ICON setting."
        << std::endl);
      return 0;
      }
    std::string destFileName = resourcesDirectory + "/" + iconFileName;
    this->ConfigureFile(iconFile, destFileName.c_str(), true);
    this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName.c_str());
    }

  if (
    !this->CopyResourcePlistFile("VolumeIcon.icns", 
                                 diskImageDirectory.c_str(),
                                 ".VolumeIcon.icns", true ) ||
    !this->CopyResourcePlistFile("DS_Store", diskImageDirectory.c_str(),
      ".DS_Store", true ) ||
    !this->CopyResourcePlistFile("background.png",
      diskImageBackgroundImageDir.c_str(), "background.png", true ) ||
    !this->CopyResourcePlistFile("RuntimeScript", dir) ||
    !this->CopyResourcePlistFile("Bundle.Info.plist", contDir,
      "Info.plist" ) ||
    !this->CopyResourcePlistFile("OSXScriptLauncher", appdir, 
      this->GetOption("CPACK_PACKAGE_FILE_NAME"), true)
  )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
      << std::endl);
    return 0;
    }
*/

  return 1;
}

//----------------------------------------------------------------------
bool cmCPackBundleGenerator::CopyFile(cmOStringStream& source,
  cmOStringStream& target)
{
  return cmSystemTools::CopyFileIfDifferent(source.str().c_str(),
    target.str().c_str());
}

//----------------------------------------------------------------------
bool cmCPackBundleGenerator::RunCommand(cmOStringStream& command)
{
  std::string output;
  int exit_code = 1;

  bool result = cmSystemTools::RunSingleCommand(command.str().c_str(),
    &output, &exit_code, 0, this->GeneratorVerbose, 0);
  if(!result || exit_code)
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running command: "
      << command.str().c_str() << std::endl);
    return false;
    }

  return true;
}

Index: cmCPackGeneratorFactory.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CPack/cmCPackGeneratorFactory.cxx,v
retrieving revision 1.2
retrieving revision 1.3
diff -C 2 -d -r1.2 -r1.3
*** cmCPackGeneratorFactory.cxx	5 Nov 2007 21:55:45 -0000	1.2
--- cmCPackGeneratorFactory.cxx	18 Jun 2008 13:53:29 -0000	1.3
***************
*** 26,29 ****
--- 26,30 ----
  #include "cmCPackNSISGenerator.h"
  #ifdef __APPLE__
+ #  include "cmCPackBundleGenerator.h"
  #  include "cmCPackPackageMakerGenerator.h"
  #  include "cmCPackOSXX11Generator.h"
***************
*** 67,70 ****
--- 68,73 ----
      cmCPackTarCompressGenerator::CreateGenerator);
  #ifdef __APPLE__
+   this->RegisterGenerator("Bundle", "Mac OSX bundle",
+     cmCPackBundleGenerator::CreateGenerator);
    this->RegisterGenerator("PackageMaker", "Mac OSX Package Maker installer",
      cmCPackPackageMakerGenerator::CreateGenerator);

--- NEW FILE: cmCPackBundleGenerator.h ---
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmCPackBundleGenerator.h,v $
  Language:  C++
  Date:      $Date: 2008-06-18 13:53:29 $
  Version:   $Revision: 1.1 $

  Copyright (c) 2002 Kitware, Inc. 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.

=========================================================================*/

#ifndef cmCPackBundleGenerator_h
#define cmCPackBundleGenerator_h

#include "cmCPackGenerator.h"

/** \class cmCPackBundleGenerator
 * \brief A generator for OSX bundles
 *
 * Based on Gimp.app
 */
class cmCPackBundleGenerator : public cmCPackGenerator
{
public:
  cmCPackTypeMacro(cmCPackBundleGenerator, cmCPackGenerator);

  cmCPackBundleGenerator();
  virtual ~cmCPackBundleGenerator();

protected:
  virtual int InitializeInternal();
  virtual const char* GetOutputExtension();
  virtual const char* GetPackagingInstallPrefix();
  int CompressFiles(const char* outFileName, const char* toplevel,
    const std::vector<std::string>& files);

  bool CopyFile(cmOStringStream& source, cmOStringStream& target);
  bool RunCommand(cmOStringStream& command);

  std::string InstallPrefix;
};

#endif



More information about the Cmake-commits mailing list