Browse Source

ENH: First pass at CPack generator for OSX X11 applications. This are applications that require X11 to work. This is not really installed but a bundle packager

Andy Cedilnik 19 years ago
parent
commit
de5540f7e5

BIN
Modules/CPack.OSXScriptLauncher.in


+ 36 - 0
Modules/CPack.OSXX11.Info.plist.in

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>@CPACK_PACKAGE_FILE_NAME@</string>
+	<key>CFBundleGetInfoString</key>
+	<string>@CPACK_APPLE_GUI_INFO_STRING@</string>
+	<key>CFBundleIconFile</key>
+	<string>@CPACK_APPLE_GUI_ICON@</string>
+	<key>CFBundleIdentifier</key>
+	<string>@CPACK_APPLE_GUI_IDENTIFIER@</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleLongVersionString</key>
+	<string>@CPACK_APPLE_GUI_LONG_VERSION_STRING@</string>
+	<key>CFBundleName</key>
+	<string>@CPACK_APPLE_GUI_BUNDLE_NAME@</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@CPACK_APPLE_GUI_SHORT_VERSION_STRING@</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>@CPACK_APPLE_GUI_BUNDLE_VERSION@</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+	<key>LSRequiresCarbon</key>
+	<true/>
+	<key>NSHumanReadableCopyright</key>
+	<string>@CPACK_APPLE_GUI_COPYRIGHT@</string>
+</dict>
+</plist>

+ 40 - 0
Modules/CPack.RuntimeScript.in

@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Modified from: Aaron Voisine <[email protected]>
+
+CWD="`dirname \"$0\"`"
+TMP=/tmp/$UID/TemporaryItems
+
+ps -wx -ocommand | grep -e '[X]11.app' > /dev/null
+if [ "$?" != "0" -a ! -f ~/.xinitrc ]; then
+    echo "rm -f ~/.xinitrc" > ~/.xinitrc
+    sed 's/xterm/# xterm/' /usr/X11R6/lib/X11/xinit/xinitrc >> ~/.xinitrc
+fi
+
+mkdir -p $TMP
+cat << __END_OF_GETDISPLAY_SCRIPT__ > "$TMP/getdisplay.sh"
+#!/bin/sh
+mkdir -p "$TMP"
+
+if [ "\$DISPLAY"x == "x" ]; then
+    echo :0 > "$TMP/display"
+else
+    echo \$DISPLAY > "$TMP/display"
+fi
+__END_OF_GETDISPLAY_SCRIPT__
+rm -f $TMP/display
+open-x11 $TMP/getdisplay.sh || \
+open -a XDarwin $TMP/getdisplay.sh || \
+echo ":0" > $TMP/display
+
+while [ "$?" == "0" -a ! -f $TMP/display ]; do sleep 1; done
+export "DISPLAY=`cat $TMP/display`"
+
+ps -wx -ocommand | grep -e '[X]11' > /dev/null || exit 11
+
+cd ~/
+echo "$@" > /tmp/arguments.log
+if echo $1 | grep -- "^-psn_"; then
+  shift
+fi
+exec "$CWD/bin/@CPACK_EXECUTABLE_NAME@" "$@" > /tmp/slicer.output 2>&1

+ 10 - 5
Source/CMakeLists.txt

@@ -286,15 +286,16 @@ TARGET_LINK_LIBRARIES(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_L
 #
 SET(CPACK_SRCS
   CPack/cmCPackGenerators.cxx
-  CPack/cmCPackSTGZGenerator.cxx
-  CPack/cmCPackTGZGenerator.cxx
+  CPack/cmCPackGenericGenerator.cxx
+  CPack/cmCPackLog.cxx
   CPack/cmCPackNSISGenerator.cxx
+  CPack/cmCPackOSXX11Generator.cxx
   CPack/cmCPackPackageMakerGenerator.cxx
-  CPack/cmCPackZIPGenerator.cxx
+  CPack/cmCPackSTGZGenerator.cxx
+  CPack/cmCPackTGZGenerator.cxx
   CPack/cmCPackTarBZip2Generator.cxx
   CPack/cmCPackTarCompressGenerator.cxx
-  CPack/cmCPackGenericGenerator.cxx
-  CPack/cmCPackLog.cxx
+  CPack/cmCPackZIPGenerator.cxx
   )
 # Build CPackLib
 ADD_LIBRARY(CPackLib ${CPACK_SRCS})
@@ -303,6 +304,10 @@ TARGET_LINK_LIBRARIES(CPackLib CMakeLib)
 IF(APPLE)
   ADD_EXECUTABLE(cmakexbuild cmakexbuild.cxx)
   TARGET_LINK_LIBRARIES(cmakexbuild CMakeLib)
+  ADD_EXECUTABLE(OSXScriptLauncher
+    MACOSX_BUNDLE CPack/OSXScriptLauncher.cxx)
+  TARGET_LINK_LIBRARIES(OSXScriptLauncher cmsys)
+  TARGET_LINK_LIBRARIES(OSXScriptLauncher "-framework Carbon")
 ENDIF(APPLE)
 
 # Build CMake executable

+ 161 - 0
Source/CPack/OSXScriptLauncher.cxx

@@ -0,0 +1,161 @@
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Process.h>
+#include <cmsys/ios/fstream>
+#include <cmsys/ios/iostream>
+
+#include <Carbon/Carbon.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#define MaximumPathLength 1024
+
+#define DebugError(x) \
+  ofs << x << cmsys_ios::endl; \
+  cmsys_ios::cout << x << cmsys_ios::endl
+
+int main(int argc, char* argv[])
+{
+  //if ( cmsys::SystemTools::FileExists(
+  cmsys_stl::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
+  cmsys_ios::ofstream ofs("/tmp/output.txt");
+
+  CFStringRef fileName;
+  CFBundleRef appBundle;
+  CFURLRef scriptFileURL;
+  FSRef fileRef;
+  FSSpec fileSpec;
+  UInt8 *path;
+
+  //get CF URL for script
+  if (! (appBundle = CFBundleGetMainBundle()))
+    {
+    DebugError("Cannot get main bundle");
+    return 1;
+    }
+  if (! (fileName = CFStringCreateWithCString(NULL, "RuntimeScript",
+        kCFStringEncodingASCII)))
+    {
+    DebugError("CFStringCreateWithCString failed");
+    return 1;
+    }
+  if (! (scriptFileURL = CFBundleCopyResourceURL(appBundle, fileName, NULL,
+        NULL)))
+    {
+    DebugError("CFBundleCopyResourceURL failed");
+    return 1;
+    }
+
+  //Get file reference from Core Foundation URL
+  if (! CFURLGetFSRef(scriptFileURL, &fileRef))
+    {
+    DebugError("CFURLGetFSRef failed");
+    return 1;
+    }
+
+  //dispose of the CF variables
+  CFRelease(scriptFileURL);
+  CFRelease(fileName);
+
+  //convert FSRef to FSSpec
+  if (FSGetCatalogInfo(&fileRef, kFSCatInfoNone, NULL, NULL, &fileSpec,
+      NULL))
+    {
+    DebugError("FSGetCatalogInfo failed");
+    return 1;
+    }
+
+  //create path string
+  if (! (path = new UInt8[MaximumPathLength]))
+    {
+    return 1;
+    }
+
+  OSErr err = noErr;
+
+  //create file reference from file spec
+  if (err = FSpMakeFSRef(&fileSpec, &fileRef)) return err;
+
+  // and then convert the FSRef to a path
+  if ( FSRefMakePath(&fileRef, path, MaximumPathLength) )
+    {
+    DebugError("FSRefMakePath failed");
+    return 1;
+    }
+  cmsys_stl::string fullScriptPath = reinterpret_cast<char*>(path);
+  delete [] path;
+
+
+  if (! cmsys::SystemTools::FileExists(fullScriptPath.c_str()))
+    {
+    return 1;
+    }
+
+  cmsys_stl::string scriptDirectory = cmsys::SystemTools::GetFilenamePath(
+    fullScriptPath);
+  ofs << fullScriptPath.c_str() << cmsys_ios::endl;
+  cmsys_stl::vector<const char*> args;
+  args.push_back(fullScriptPath.c_str());
+  int cc;
+  for ( cc = 1; cc < argc; ++ cc )
+    {
+    args.push_back(argv[cc]);
+    }
+  args.push_back(0);
+
+  cmsysProcess* cp = cmsysProcess_New();
+  cmsysProcess_SetCommand(cp, &*args.begin());
+  cmsysProcess_SetWorkingDirectory(cp, scriptDirectory.c_str());
+  cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+  cmsysProcess_SetTimeout(cp, 0);
+  cmsysProcess_Execute(cp);
+  
+  std::vector<char> tempOutput;
+  char* data;
+  int length;
+  while(cmsysProcess_WaitForData(cp, &data, &length, 0))
+    {
+    // Translate NULL characters in the output into valid text.
+    // Visual Studio 7 puts these characters in the output of its
+    // build process.
+    for(int i=0; i < length; ++i)
+      {
+      if(data[i] == '\0')
+        {
+        data[i] = ' ';
+        }
+      }
+    cmsys_ios::cout.write(data, length);
+    }
+  
+  cmsysProcess_WaitForExit(cp, 0);
+  
+  bool result = true;
+  if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
+    {
+    if ( cmsysProcess_GetExitValue(cp) !=  0 )
+      {
+      result = false;
+      }
+    }
+  else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception)
+    {
+    const char* exception_str = cmsysProcess_GetExceptionString(cp);
+    std::cerr << exception_str << std::endl;
+    result = false;
+    }
+  else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
+    {
+    const char* error_str = cmsysProcess_GetErrorString(cp);
+    std::cerr << error_str << std::endl;
+    result = false;
+    }
+  else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired)
+    {
+    const char* error_str = "Process terminated due to timeout\n";
+    std::cerr << error_str << std::endl;
+    result = false;
+    }
+  
+  cmsysProcess_Delete(cp);
+
+  return 0;
+}

+ 10 - 3
Source/CPack/cmCPackGenerators.cxx

@@ -23,8 +23,13 @@
 #include "cmCPackTarCompressGenerator.h"
 #include "cmCPackZIPGenerator.h"
 #include "cmCPackSTGZGenerator.h"
-#include "cmCPackNSISGenerator.h"
-#include "cmCPackPackageMakerGenerator.h"
+#ifdef _WIN32
+#  include "cmCPackNSISGenerator.h"
+#endif
+#ifdef __APPLE__
+#  include "cmCPackPackageMakerGenerator.h"
+#  include "cmCPackOSXX11Generator.h"
+#endif
 
 #include "cmCPackLog.h"
 
@@ -46,8 +51,10 @@ cmCPackGenerators::cmCPackGenerators()
   this->RegisterGenerator("TZ", "Tar Compress compression",
     cmCPackTarCompressGenerator::CreateGenerator);
 #ifdef __APPLE__
-  this->RegisterGenerator("PackageMaker", "Mac OSX Package Maker compression",
+  this->RegisterGenerator("PackageMaker", "Mac OSX Package Maker installer",
     cmCPackPackageMakerGenerator::CreateGenerator);
+  this->RegisterGenerator("OSXX11", "Mac OSX X11 bundle",
+    cmCPackOSXX11Generator::CreateGenerator);
 #endif
 }
 

+ 8 - 4
Source/CPack/cmCPackGenericGenerator.cxx

@@ -152,8 +152,10 @@ int cmCPackGenericGenerator::InstallProject()
 {
   cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Install projects" << std::endl);
   this->CleanTemporaryDirectory();
-  const char* tempInstallDirectory
+  std::string tempInstallDirectoryWithPostfix
     = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
+  tempInstallDirectoryWithPostfix += this->GetTemporaryInstallDirectoryPostfix();
+  const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str();
   int res = 1;
   if ( !cmsys::SystemTools::MakeDirectory(tempInstallDirectory))
     {
@@ -965,17 +967,19 @@ bool cmCPackGenericGenerator::ConfigureString(const std::string& inString,
 
 //----------------------------------------------------------------------
 bool cmCPackGenericGenerator::ConfigureFile(const char* inName,
-  const char* outName)
+  const char* outName, bool copyOnly /* = false */)
 {
   return this->MakefileMap->ConfigureFile(inName, outName,
-    false, true, false) == 1;
+    copyOnly, true, false) == 1;
 }
 
 //----------------------------------------------------------------------
 int cmCPackGenericGenerator::CleanTemporaryDirectory()
 {
-  const char* tempInstallDirectory
+  std::string tempInstallDirectoryWithPostfix
     = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
+  tempInstallDirectoryWithPostfix += this->GetTemporaryInstallDirectoryPostfix();
+  const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str();
   if(cmsys::SystemTools::FileExists(tempInstallDirectory))
     {
     cmCPackLogger(cmCPackLog::LOG_OUTPUT,

+ 2 - 1
Source/CPack/cmCPackGenericGenerator.h

@@ -100,9 +100,10 @@ protected:
     const std::vector<std::string>& files);
   virtual const char* GetInstallPath();
   virtual const char* GetInstallPrefix() { return "/"; }
+  virtual const char* GetTemporaryInstallDirectoryPostfix() { return ""; }
 
   virtual std::string FindTemplate(const char* name);
-  virtual bool ConfigureFile(const char* inName, const char* outName);
+  virtual bool ConfigureFile(const char* inName, const char* outName, bool copyOnly = false);
   virtual bool ConfigureString(const std::string& input, std::string& output);
   virtual int InitializeInternal();
 

+ 220 - 0
Source/CPack/cmCPackOSXX11Generator.cxx

@@ -0,0 +1,220 @@
+/*=========================================================================
+
+  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 "cmCPackOSXX11Generator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+
+//----------------------------------------------------------------------
+cmCPackOSXX11Generator::cmCPackOSXX11Generator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackOSXX11Generator::~cmCPackOSXX11Generator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackOSXX11Generator::CompressFiles(const char* outFileName,
+  const char* toplevel,
+  const std::vector<std::string>& files)
+{
+  (void) files; // TODO: Fix api to not need files.
+  (void) toplevel; // TODO: Use toplevel
+
+  const char* cpackPackageExecutables
+    = this->GetOption("CPACK_PACKAGE_EXECUTABLES");
+  if ( cpackPackageExecutables )
+    {
+    cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
+      << cpackPackageExecutables << "." << std::endl);
+    cmOStringStream str;
+    cmOStringStream deleteStr;
+    std::vector<std::string> cpackPackageExecutablesVector;
+    cmSystemTools::ExpandListArgument(cpackPackageExecutables,
+      cpackPackageExecutablesVector);
+    if ( cpackPackageExecutablesVector.size() % 2 != 0 )
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+        "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
+        "<icon name>." << std::endl);
+      return 0;
+      }
+    std::vector<std::string>::iterator it;
+    for ( it = cpackPackageExecutablesVector.begin();
+      it != cpackPackageExecutablesVector.end();
+      ++it )
+      {
+      std::string cpackExecutableName = *it;
+      ++ it;
+      this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME", 
+        cpackExecutableName.c_str());
+      }
+    }
+
+  std::string packageDirFileName = toplevel;
+  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();
+  if (
+    !this->CopyResourcePlistFile("RuntimeScript", dir) ||
+    !this->CopyResourcePlistFile("OSXX11.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;
+    }
+
+  std::string output;
+  std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+  tmpFile += "/hdiutilOutput.log";
+  cmOStringStream dmgCmd;
+  dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
+    << "\" create -ov -format UDZO -srcfolder \"" << packageDirFileName
+    << "\" \"" << outFileName << "\"";
+  int retVal = 1;
+  bool res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
+    &retVal, 0, this->GeneratorVerbose, 0);
+  if ( !res || retVal )
+    {
+    cmGeneratedFileStream ofs(tmpFile.c_str());
+    ofs << "# Run command: " << dmgCmd.str().c_str() << std::endl
+      << "# Output:" << std::endl
+      << output.c_str() << std::endl;
+    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running hdiutil command: "
+      << dmgCmd.str().c_str() << std::endl
+      << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+    return 0;
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackOSXX11Generator::InitializeInternal()
+{
+  cmCPackLogger(cmCPackLog::LOG_DEBUG,
+    "cmCPackOSXX11Generator::Initialize()" << std::endl);
+  std::vector<std::string> path;
+  std::string pkgPath = cmSystemTools::FindProgram("hdiutil", path, false);
+  if ( pkgPath.empty() )
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find hdiutil compiler"
+      << std::endl);
+    return 0;
+    }
+  this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", 
+                          pkgPath.c_str());
+
+  
+
+  return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+/*
+bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
+{
+  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 ? name : "(NULL)")
+                  << ".rtf, " << name
+                  << ".html, or " << name << ".txt file" << std::endl);
+    return false;
+    }
+  if ( !cmSystemTools::FileExists(inFileName) )
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find " 
+                  << (name ? name : "(NULL)")
+                  << " 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 = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+  destFileName += "/Resources/";
+  destFileName += name + ext;
+
+
+  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " 
+                << (inFileName ? inFileName : "(NULL)")
+                << " to " << destFileName.c_str() << std::endl);
+  this->ConfigureFile(inFileName, destFileName.c_str());
+  return true;
+}
+*/
+
+bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name,
+  const char* dir, const char* outputFileName /* = 0 */,
+  bool copyOnly /* = false */)
+{
+  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;
+    }
+
+  if ( !outputFileName )
+    {
+    outputFileName = name;
+    }
+
+  std::string destFileName = dir;
+  destFileName += "/";
+  destFileName += outputFileName;
+
+  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
+    << inFileName.c_str() << " to " << destFileName.c_str() << std::endl);
+  this->ConfigureFile(inFileName.c_str(), destFileName.c_str(), copyOnly);
+  return true;
+}
+

+ 51 - 0
Source/CPack/cmCPackOSXX11Generator.h

@@ -0,0 +1,51 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  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 cmCPackOSXX11Generator_h
+#define cmCPackOSXX11Generator_h
+
+#include "cmCPackGenericGenerator.h"
+
+/** \class cmCPackOSXX11Generator
+ * \brief A generator for OSX X11 modules
+ *
+ * Based on Gimp.app
+ */
+class cmCPackOSXX11Generator : public cmCPackGenericGenerator
+{
+public:
+  cmCPackTypeMacro(cmCPackOSXX11Generator, cmCPackGenericGenerator);
+
+  /**
+   * Construct generator
+   */
+  cmCPackOSXX11Generator();
+  virtual ~cmCPackOSXX11Generator();
+
+protected:
+  virtual int InitializeInternal();
+  int CompressFiles(const char* outFileName, const char* toplevel,
+    const std::vector<std::string>& files);
+  virtual const char* GetOutputExtension() { return "dmg"; }
+  virtual const char* GetInstallPrefix() { return ".app/Contents/Resources"; }
+
+  //bool CopyCreateResourceFile(const char* name, const char* dir);
+  bool CopyResourcePlistFile(const char* name, const char* dir,
+    const char* outputFileName = 0, bool copyOnly = false);
+};
+
+#endif