2006-01-02 07:21:05 +03:00
/*=========================================================================
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 "cmCPackPackageMakerGenerator.h"
# include "cmake.h"
# include "cmGlobalGenerator.h"
# include "cmLocalGenerator.h"
# include "cmSystemTools.h"
# include "cmMakefile.h"
# include "cmGeneratedFileStream.h"
2006-01-03 00:14:21 +03:00
# include "cmCPackLog.h"
2006-01-02 07:21:05 +03:00
# include <cmsys/SystemTools.hxx>
# include <cmsys/Glob.hxx>
//----------------------------------------------------------------------
cmCPackPackageMakerGenerator : : cmCPackPackageMakerGenerator ( )
{
2006-03-03 23:04:28 +03:00
this - > PackageMakerVersion = 0 ;
2006-01-02 07:21:05 +03:00
}
//----------------------------------------------------------------------
cmCPackPackageMakerGenerator : : ~ cmCPackPackageMakerGenerator ( )
{
}
//----------------------------------------------------------------------
int cmCPackPackageMakerGenerator : : CompressFiles ( const char * outFileName , const char * toplevel ,
const std : : vector < std : : string > & files )
{
2006-01-02 15:53:05 +03:00
( void ) files ; // TODO: Fix api to not need files.
( void ) toplevel ; // TODO: Use toplevel
2006-01-02 07:21:05 +03:00
// Create directory structure
std : : string resDir = this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) ;
resDir + = " /Resources " ;
std : : string preflightDirName = resDir + " /PreFlight " ;
std : : string postflightDirName = resDir + " /PostFlight " ;
if ( ! cmsys : : SystemTools : : MakeDirectory ( preflightDirName . c_str ( ) )
| | ! cmsys : : SystemTools : : MakeDirectory ( postflightDirName . c_str ( ) ) )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Problem creating installer directories: " < < preflightDirName . c_str ( ) < < " and "
< < postflightDirName . c_str ( ) < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return 0 ;
}
if ( ! this - > CopyCreateResourceFile ( " License " )
| | ! this - > CopyCreateResourceFile ( " ReadMe " )
| | ! this - > CopyCreateResourceFile ( " Welcome " )
| | ! this - > CopyResourcePlistFile ( " Info.plist " )
| | ! this - > CopyResourcePlistFile ( " Description.plist " ) )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Problem copying the resource files " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return 0 ;
}
std : : string packageDirFileName = this - > GetOption ( " CPACK_TEMPORARY_DIRECTORY " ) ;
packageDirFileName + = " .pkg " ;
std : : string tmpFile = this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) ;
tmpFile + = " /PackageMakerOutput.log " ;
cmOStringStream pkgCmd ;
2006-01-05 18:37:05 +03:00
pkgCmd < < " \" " < < this - > GetOption ( " CPACK_INSTALLER_PROGRAM " )
2006-01-02 07:21:05 +03:00
< < " \" -build -p \" " < < packageDirFileName < < " \" -f \" " < < this - > GetOption ( " CPACK_TEMPORARY_DIRECTORY " )
< < " \" -r \" " < < this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) < < " /Resources \" -i \" "
< < this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) < < " /Info.plist \" -d \" "
2006-03-03 23:04:28 +03:00
< < this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) < < " /Description.plist \" " ;
if ( this - > PackageMakerVersion > 2.0 )
{
pkgCmd < < " -v " ;
}
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Execute: " < < pkgCmd . str ( ) . c_str ( ) < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
std : : string output ;
int retVal = 1 ;
//bool res = cmSystemTools::RunSingleCommand(pkgCmd.str().c_str(), &output, &retVal, 0, m_GeneratorVerbose, 0);
bool res = true ;
retVal = system ( pkgCmd . str ( ) . c_str ( ) ) ;
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Done running package maker " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
if ( ! res | | retVal )
{
cmGeneratedFileStream ofs ( tmpFile . c_str ( ) ) ;
ofs < < " # Run command: " < < pkgCmd . str ( ) . c_str ( ) < < std : : endl
< < " # Output: " < < std : : endl
< < output . c_str ( ) < < std : : endl ;
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Problem running PackageMaker command: " < < pkgCmd . str ( ) . c_str ( ) < < std : : endl
< < " Please check " < < tmpFile . c_str ( ) < < " for errors " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return 0 ;
}
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 < < " \" " ;
res = cmSystemTools : : RunSingleCommand ( dmgCmd . str ( ) . c_str ( ) , & output , & retVal , 0 , m_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 ;
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Problem running hdiutil command: " < < dmgCmd . str ( ) . c_str ( ) < < std : : endl
< < " Please check " < < tmpFile . c_str ( ) < < " for errors " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return 0 ;
}
return 1 ;
}
//----------------------------------------------------------------------
2006-01-03 01:28:20 +03:00
int cmCPackPackageMakerGenerator : : Initialize ( const char * name , cmMakefile * mf )
2006-01-02 07:21:05 +03:00
{
2006-01-03 01:28:20 +03:00
int res = this - > Superclass : : Initialize ( name , mf ) ;
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " cmCPackPackageMakerGenerator::Initialize() " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
std : : vector < std : : string > path ;
2006-03-03 23:04:28 +03:00
std : : string pkgPath = " /Developer/Applications/Utilities/PackageMaker.app/Contents " ;
std : : string versionFile = pkgPath + " /version.plist " ;
pkgPath + = " /MacOS " ;
if ( ! cmSystemTools : : FileExists ( versionFile . c_str ( ) ) )
{
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find PackageMaker compiler version file: " < < versionFile . c_str ( ) < < std : : endl ) ;
return 0 ;
}
std : : ifstream ifs ( versionFile . c_str ( ) ) ;
if ( ! ifs )
{
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot open PackageMaker compiler version file " < < std : : endl ) ;
return 0 ;
}
// Check the PackageMaker version
cmsys : : RegularExpression rexKey ( " <key>CFBundleShortVersionString</key> " ) ;
cmsys : : RegularExpression rexVersion ( " <string>([0-9]+.[0-9]+)</string> " ) ;
std : : string line ;
bool foundKey = false ;
while ( cmSystemTools : : GetLineFromStream ( ifs , line ) )
{
if ( rexKey . find ( line ) )
{
foundKey = true ;
break ;
}
}
if ( ! foundKey )
{
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find CFBundleShortVersionString in the PackageMaker compiler version file " < < std : : endl ) ;
return 0 ;
}
if ( ! cmSystemTools : : GetLineFromStream ( ifs , line ) | | ! rexVersion . find ( line ) )
{
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Problem reading the PackageMaker compiler version file " < < std : : endl ) ;
return 0 ;
}
this - > PackageMakerVersion = atof ( rexVersion . match ( 1 ) . c_str ( ) ) ;
if ( this - > PackageMakerVersion < 1 )
{
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Require PackageMaker 1.0 or higher " < < std : : endl ) ;
return 0 ;
}
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " PackageMaker version is: " < < this - > PackageMakerVersion < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
path . push_back ( pkgPath ) ;
pkgPath = cmSystemTools : : FindProgram ( " PackageMaker " , path , false ) ;
if ( pkgPath . empty ( ) )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find PackageMaker compiler " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return 0 ;
}
this - > SetOption ( " CPACK_INSTALLER_PROGRAM " , pkgPath . c_str ( ) ) ;
pkgPath = cmSystemTools : : FindProgram ( " hdiutil " , path , false ) ;
if ( pkgPath . empty ( ) )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find hdiutil compiler " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return 0 ;
}
this - > SetOption ( " CPACK_INSTALLER_PROGRAM_DISK_IMAGE " , pkgPath . c_str ( ) ) ;
return res ;
}
//----------------------------------------------------------------------
bool cmCPackPackageMakerGenerator : : 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 )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " CPack option: " < < cpackVar . c_str ( ) < < " not specified. It should point to " < < name < < " .rtf, " < < name < < " .html, or " < < name < < " .txt file " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return false ;
}
if ( ! cmSystemTools : : FileExists ( inFileName ) )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find " < < name < < " resource file: " < < inFileName < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return false ;
}
std : : string ext = cmSystemTools : : GetFilenameLastExtension ( inFileName ) ;
if ( ext ! = " .rtfd " & & ext ! = " .rtf " & & ext ! = " .html " & & ext ! = " .txt " )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Bad file extension specified: " < < ext < < " . Currently only .rtfd, .rtf, .html, and .txt files allowed. " < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return false ;
}
std : : string destFileName = this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) ;
destFileName + = " /Resources/ " ;
destFileName + = name + ext ;
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Configure file: " < < inFileName < < " to " < < destFileName . c_str ( ) < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
this - > ConfigureFile ( inFileName , destFileName . c_str ( ) ) ;
return true ;
}
bool cmCPackPackageMakerGenerator : : CopyResourcePlistFile ( const char * name )
{
std : : string inFName = " CPack. " ;
inFName + = name ;
inFName + = " .in " ;
std : : string inFileName = this - > FindTemplate ( inFName . c_str ( ) ) ;
if ( inFileName . empty ( ) )
{
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find input file: " < < inFName < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
return false ;
}
std : : string destFileName = this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) ;
destFileName + = " / " ;
destFileName + = name ;
2006-01-03 00:14:21 +03:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Configure file: " < < inFileName . c_str ( ) < < " to " < < destFileName . c_str ( ) < < std : : endl ) ;
2006-01-02 07:21:05 +03:00
this - > ConfigureFile ( inFileName . c_str ( ) , destFileName . c_str ( ) ) ;
return true ;
}