2006-01-02 04:21:05 +00: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.
2006-03-10 18:06:26 +00:00
This software is distributed WITHOUT ANY WARRANTY ; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
2006-01-02 04:21:05 +00:00
PURPOSE . See the above copyright notices for more information .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "cmCPackNSISGenerator.h"
# include "cmGlobalGenerator.h"
# include "cmLocalGenerator.h"
# include "cmSystemTools.h"
# include "cmMakefile.h"
# include "cmGeneratedFileStream.h"
2006-01-02 21:14:21 +00:00
# include "cmCPackLog.h"
2006-01-02 04:21:05 +00:00
# include <cmsys/SystemTools.hxx>
# include <cmsys/Glob.hxx>
2006-02-16 20:20:23 +00:00
# include <cmsys/Directory.hxx>
2006-02-23 14:38:40 +00:00
# include <cmsys/RegularExpression.hxx>
2006-01-02 04:21:05 +00:00
//----------------------------------------------------------------------
cmCPackNSISGenerator : : cmCPackNSISGenerator ( )
{
}
//----------------------------------------------------------------------
cmCPackNSISGenerator : : ~ cmCPackNSISGenerator ( )
{
}
//----------------------------------------------------------------------
2006-03-08 21:33:39 +00:00
int cmCPackNSISGenerator : : CompressFiles ( const char * outFileName ,
const char * toplevel , const std : : vector < std : : string > & files )
2006-01-02 04:21:05 +00:00
{
( void ) outFileName ; // TODO: Fix nsis to force out file name
( void ) toplevel ;
std : : string nsisInFileName = this - > FindTemplate ( " NSIS.template.in " ) ;
if ( nsisInFileName . size ( ) = = 0 )
{
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR ,
" CPack error: Could not find NSIS installer template file. "
< < std : : endl ) ;
2006-01-02 04:21:05 +00:00
return false ;
}
2006-04-29 23:22:21 +00:00
std : : string nsisInInstallOptions
= this - > FindTemplate ( " NSIS.InstallOptions.ini.in " ) ;
if ( nsisInInstallOptions . size ( ) = = 0 )
{
cmCPackLogger ( cmCPackLog : : LOG_ERROR ,
" CPack error: Could not find NSIS installer options file. "
< < std : : endl ) ;
return false ;
}
2006-01-02 04:21:05 +00:00
std : : string nsisFileName = this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) ;
std : : string tmpFile = nsisFileName ;
tmpFile + = " /NSISOutput.log " ;
2006-04-29 23:22:21 +00:00
std : : string nsisInstallOptions = nsisFileName + " /NSIS.InstallOptions.ini " ;
2006-01-02 04:21:05 +00:00
nsisFileName + = " /project.nsi " ;
2006-02-16 20:20:23 +00:00
cmOStringStream str ;
std : : vector < std : : string > : : const_iterator it ;
for ( it = files . begin ( ) ; it ! = files . end ( ) ; + + it )
{
std : : string fileN = cmSystemTools : : RelativePath ( toplevel ,
it - > c_str ( ) ) ;
cmSystemTools : : ReplaceString ( fileN , " / " , " \\ " ) ;
str < < " Delete \" $INSTDIR \\ " < < fileN . c_str ( ) < < " \" " < < std : : endl ;
}
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " Uninstall Files: "
< < str . str ( ) . c_str ( ) < < std : : endl ) ;
2006-05-02 12:49:01 +00:00
this - > SetOptionIfNotSet ( " CPACK_NSIS_DELETE_FILES " , str . str ( ) . c_str ( ) ) ;
2006-02-16 20:20:23 +00:00
std : : vector < std : : string > dirs ;
this - > GetListOfSubdirectories ( toplevel , dirs ) ;
std : : vector < std : : string > : : const_iterator sit ;
cmOStringStream dstr ;
for ( sit = dirs . begin ( ) ; sit ! = dirs . end ( ) ; + + sit )
{
std : : string fileN = cmSystemTools : : RelativePath ( toplevel ,
sit - > c_str ( ) ) ;
if ( fileN . empty ( ) )
{
continue ;
}
cmSystemTools : : ReplaceString ( fileN , " / " , " \\ " ) ;
dstr < < " RMDir \" $INSTDIR \\ " < < fileN . c_str ( ) < < " \" " < < std : : endl ;
}
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " Uninstall Dirs: "
< < dstr . str ( ) . c_str ( ) < < std : : endl ) ;
2006-05-12 18:44:24 +00:00
this - > SetOptionIfNotSet ( " CPACK_NSIS_DELETE_DIRECTORIES " ,
dstr . str ( ) . c_str ( ) ) ;
2006-02-16 20:20:23 +00:00
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Configure file: " < < nsisInFileName
< < " to " < < nsisFileName < < std : : endl ) ;
2006-05-12 18:44:24 +00:00
this - > ConfigureFile ( nsisInInstallOptions . c_str ( ) ,
nsisInstallOptions . c_str ( ) ) ;
2006-01-02 04:21:05 +00:00
this - > ConfigureFile ( nsisInFileName . c_str ( ) , nsisFileName . c_str ( ) ) ;
std : : string nsisCmd = " \" " ;
nsisCmd + = this - > GetOption ( " CPACK_INSTALLER_PROGRAM " ) ;
nsisCmd + = " \" \" " + nsisFileName + " \" " ;
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Execute: " < < nsisCmd . c_str ( )
< < std : : endl ) ;
2006-01-02 04:21:05 +00:00
std : : string output ;
int retVal = 1 ;
2006-03-08 21:33:39 +00:00
bool res = cmSystemTools : : RunSingleCommand ( nsisCmd . c_str ( ) , & output ,
2006-03-10 18:06:26 +00:00
& retVal , 0 , this - > GeneratorVerbose , 0 ) ;
2006-01-02 04:21:05 +00:00
if ( ! res | | retVal )
{
cmGeneratedFileStream ofs ( tmpFile . c_str ( ) ) ;
ofs < < " # Run command: " < < nsisCmd . c_str ( ) < < std : : endl
< < " # Output: " < < std : : endl
< < output . c_str ( ) < < std : : endl ;
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Problem running NSIS command: "
< < nsisCmd . c_str ( ) < < std : : endl
2006-01-02 21:14:21 +00:00
< < " Please check " < < tmpFile . c_str ( ) < < " for errors " < < std : : endl ) ;
2006-01-02 04:21:05 +00:00
return 0 ;
}
return 1 ;
}
//----------------------------------------------------------------------
2006-04-15 17:02:18 +00:00
int cmCPackNSISGenerator : : InitializeInternal ( )
2006-01-02 04:21:05 +00:00
{
2006-04-02 15:20:58 +00:00
if ( cmSystemTools : : IsOn ( this - > GetOption (
" CPACK_INCLUDE_TOPLEVEL_DIRECTORY " ) ) )
{
2006-04-15 17:02:18 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR ,
" NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY. "
" This option will be ignored. "
2006-04-02 15:20:58 +00:00
< < std : : endl ) ;
this - > SetOption ( " CPACK_INCLUDE_TOPLEVEL_DIRECTORY " , 0 ) ;
}
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " cmCPackNSISGenerator::Initialize() "
< < std : : endl ) ;
2006-01-02 04:21:05 +00:00
std : : vector < std : : string > path ;
std : : string nsisPath ;
2006-03-08 21:33:39 +00:00
if ( ! cmsys : : SystemTools : : ReadRegistryValue (
" HKEY_LOCAL_MACHINE \\ SOFTWARE \\ NSIS " , nsisPath ) )
2006-01-02 04:21:05 +00:00
{
2006-11-14 03:08:42 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find NSIS registry value. This is usually caused by NSIS not being installed. Please install NSIS from http://nsis.sourceforge.org "
2006-03-08 21:33:39 +00:00
< < std : : endl ) ;
2006-01-02 04:21:05 +00:00
return 0 ;
}
path . push_back ( nsisPath ) ;
nsisPath = cmSystemTools : : FindProgram ( " makensis " , path , false ) ;
if ( nsisPath . empty ( ) )
{
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR , " Cannot find NSIS compiler "
< < std : : endl ) ;
2006-01-02 04:21:05 +00:00
return 0 ;
}
2006-02-23 14:38:40 +00:00
std : : string nsisCmd = " \" " + nsisPath + " \" /VERSION " ;
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_VERBOSE , " Test NSIS version: "
< < nsisCmd . c_str ( ) < < std : : endl ) ;
2006-02-23 14:38:40 +00:00
std : : string output ;
int retVal = 1 ;
2006-03-08 21:33:39 +00:00
bool resS = cmSystemTools : : RunSingleCommand ( nsisCmd . c_str ( ) ,
2006-03-10 18:06:26 +00:00
& output , & retVal , 0 , this - > GeneratorVerbose , 0 ) ;
2006-02-23 14:38:40 +00:00
cmsys : : RegularExpression versionRex ( " v([0-9]+.[0-9]+) " ) ;
if ( ! resS | | retVal | | ! versionRex . find ( output ) )
{
std : : string tmpFile = this - > GetOption ( " CPACK_TOPLEVEL_DIRECTORY " ) ;
tmpFile + = " /NSISOutput.log " ;
cmGeneratedFileStream ofs ( tmpFile . c_str ( ) ) ;
ofs < < " # Run command: " < < nsisCmd . c_str ( ) < < std : : endl
< < " # Output: " < < std : : endl
< < output . c_str ( ) < < std : : endl ;
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR ,
" Problem checking NSIS version with command: "
< < nsisCmd . c_str ( ) < < std : : endl
2006-02-23 14:38:40 +00:00
< < " Please check " < < tmpFile . c_str ( ) < < " for errors " < < std : : endl ) ;
return 0 ;
}
float nsisVersion = atof ( versionRex . match ( 1 ) . c_str ( ) ) ;
float minNSISVersion = 2.09 ;
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " NSIS Version: "
< < nsisVersion < < std : : endl ) ;
if ( nsisVersion < minNSISVersion )
{
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR ,
" CPack requires NSIS Version 2.09 or greater. NSIS found on the system "
" was: "
2006-02-23 14:38:40 +00:00
< < nsisVersion < < std : : endl ) ;
return 0 ;
}
2006-02-14 19:29:15 +00:00
2006-05-02 12:49:01 +00:00
this - > SetOptionIfNotSet ( " CPACK_INSTALLER_PROGRAM " , nsisPath . c_str ( ) ) ;
2006-03-08 21:33:39 +00:00
const char * cpackPackageExecutables
= this - > GetOption ( " CPACK_PACKAGE_EXECUTABLES " ) ;
2006-02-14 19:29:15 +00:00
if ( cpackPackageExecutables )
{
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_DEBUG , " The cpackPackageExecutables: "
< < cpackPackageExecutables < < " . " < < std : : endl ) ;
2006-02-14 19:29:15 +00:00
cmOStringStream str ;
cmOStringStream deleteStr ;
std : : vector < std : : string > cpackPackageExecutablesVector ;
2006-03-08 21:33:39 +00:00
cmSystemTools : : ExpandListArgument ( cpackPackageExecutables ,
cpackPackageExecutablesVector ) ;
2006-02-14 19:29:15 +00:00
if ( cpackPackageExecutablesVector . size ( ) % 2 ! = 0 )
{
2006-03-08 21:33:39 +00:00
cmCPackLogger ( cmCPackLog : : LOG_ERROR ,
" CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
" <icon name>. " < < std : : endl ) ;
2006-02-14 19:29:15 +00:00
return 0 ;
}
std : : vector < std : : string > : : iterator it ;
2006-03-08 21:33:39 +00:00
for ( it = cpackPackageExecutablesVector . begin ( ) ;
it ! = cpackPackageExecutablesVector . end ( ) ;
2006-02-14 19:29:15 +00:00
+ + it )
{
std : : string execName = * it ;
+ + it ;
std : : string linkName = * it ;
2006-03-08 21:33:39 +00:00
str < < " CreateShortCut \" $SMPROGRAMS \\ $STARTMENU_FOLDER \\ "
< < linkName < < " .lnk \" \" $INSTDIR \\ bin \\ " < < execName < < " .exe \" "
< < std : : endl ;
deleteStr < < " Delete \" $SMPROGRAMS \\ $MUI_TEMP \\ " < < linkName
< < " .lnk \" " < < std : : endl ;
2006-02-14 19:29:15 +00:00
}
2006-05-02 12:49:01 +00:00
this - > SetOptionIfNotSet ( " CPACK_NSIS_CREATE_ICONS " , str . str ( ) . c_str ( ) ) ;
2006-05-12 18:44:24 +00:00
this - > SetOptionIfNotSet ( " CPACK_NSIS_DELETE_ICONS " ,
deleteStr . str ( ) . c_str ( ) ) ;
2006-02-14 19:29:15 +00:00
}
2006-10-12 18:59:43 +00:00
this - > SetOptionIfNotSet ( " CPACK_NSIS_COMPRESSOR " , " lzma " ) ;
2006-02-14 19:29:15 +00:00
2006-04-15 17:02:18 +00:00
return this - > Superclass : : InitializeInternal ( ) ;
2006-01-02 04:21:05 +00:00
}
2006-02-16 20:20:23 +00:00
//----------------------------------------------------------------------
2006-03-08 21:33:39 +00:00
bool cmCPackNSISGenerator : : GetListOfSubdirectories ( const char * topdir ,
std : : vector < std : : string > & dirs )
2006-02-16 20:20:23 +00:00
{
cmsys : : Directory dir ;
dir . Load ( topdir ) ;
size_t fileNum ;
for ( fileNum = 0 ; fileNum < dir . GetNumberOfFiles ( ) ; + + fileNum )
{
if ( strcmp ( dir . GetFile ( static_cast < unsigned long > ( fileNum ) ) , " . " ) & &
strcmp ( dir . GetFile ( static_cast < unsigned long > ( fileNum ) ) , " .. " ) )
{
2006-08-27 17:15:39 +00:00
cmsys_stl : : string fullPath = topdir ;
2006-02-16 20:20:23 +00:00
fullPath + = " / " ;
fullPath + = dir . GetFile ( static_cast < unsigned long > ( fileNum ) ) ;
if ( cmsys : : SystemTools : : FileIsDirectory ( fullPath . c_str ( ) ) & &
! cmsys : : SystemTools : : FileIsSymlink ( fullPath . c_str ( ) ) )
{
if ( ! this - > GetListOfSubdirectories ( fullPath . c_str ( ) , dirs ) )
{
return false ;
}
}
}
}
dirs . push_back ( topdir ) ;
return true ;
}