diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2007-01-10 20:30:26 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2007-01-10 20:30:26 (GMT) |
commit | de5540f7e5215ea1cce982f5e7357f4999c3f908 (patch) | |
tree | 9410e064963651c0b543bdb2941f14fe6b091798 /Source/CPack | |
parent | c2780e2c9a83e50b2cdd5225ede341c7de67d862 (diff) | |
download | CMake-de5540f7e5215ea1cce982f5e7357f4999c3f908.zip CMake-de5540f7e5215ea1cce982f5e7357f4999c3f908.tar.gz CMake-de5540f7e5215ea1cce982f5e7357f4999c3f908.tar.bz2 |
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/CPack')
-rw-r--r-- | Source/CPack/OSXScriptLauncher.cxx | 161 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenerators.cxx | 13 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenericGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenericGenerator.h | 3 | ||||
-rw-r--r-- | Source/CPack/cmCPackOSXX11Generator.cxx | 220 | ||||
-rw-r--r-- | Source/CPack/cmCPackOSXX11Generator.h | 51 |
6 files changed, 452 insertions, 8 deletions
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx new file mode 100644 index 0000000..d09c12e --- /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 3515e0e..4d0dc68 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 52b2e14..0f0ddad 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 afe79c0..27d5098 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 0000000..95e2801 --- /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 0000000..8720e79 --- /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 |