summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2007-01-10 15:30:26 -0500
committerAndy Cedilnik <andy.cedilnik@kitware.com>2007-01-10 15:30:26 -0500
commitde5540f7e5215ea1cce982f5e7357f4999c3f908 (patch)
tree9410e064963651c0b543bdb2941f14fe6b091798 /Source
parentc2780e2c9a83e50b2cdd5225ede341c7de67d862 (diff)
downloadcmake-de5540f7e5215ea1cce982f5e7357f4999c3f908.tar.gz
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
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt15
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx161
-rw-r--r--Source/CPack/cmCPackGenerators.cxx13
-rw-r--r--Source/CPack/cmCPackGenericGenerator.cxx12
-rw-r--r--Source/CPack/cmCPackGenericGenerator.h3
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx220
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.h51
7 files changed, 462 insertions, 13 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ab2c77edb4..46b600657b 100644
--- a/Source/CMakeLists.txt
+++ b/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
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
new file mode 100644
index 0000000000..d09c12e033
--- /dev/null
+++ b/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;
+}
diff --git a/Source/CPack/cmCPackGenerators.cxx b/Source/CPack/cmCPackGenerators.cxx
index 3515e0e58e..4d0dc68392 100644
--- a/Source/CPack/cmCPackGenerators.cxx
+++ b/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
}
diff --git a/Source/CPack/cmCPackGenericGenerator.cxx b/Source/CPack/cmCPackGenericGenerator.cxx
index 52b2e14dbb..0f0ddadfe6 100644
--- a/Source/CPack/cmCPackGenericGenerator.cxx
+++ b/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,
diff --git a/Source/CPack/cmCPackGenericGenerator.h b/Source/CPack/cmCPackGenericGenerator.h
index afe79c0e2b..27d5098f6f 100644
--- a/Source/CPack/cmCPackGenericGenerator.h
+++ b/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();
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
new file mode 100644
index 0000000000..95e2801801
--- /dev/null
+++ b/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;
+}
+
diff --git a/Source/CPack/cmCPackOSXX11Generator.h b/Source/CPack/cmCPackOSXX11Generator.h
new file mode 100644
index 0000000000..8720e79b41
--- /dev/null
+++ b/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