Browse Source

ENH: add ability to set installer icons, links to web pages, nsis code in the icon section of the template, and ability to escape variables correctly

Bill Hoffman 18 years ago
parent
commit
02f79c7242
4 changed files with 125 additions and 15 deletions
  1. 18 2
      CMakeCPack.cmake
  2. 78 6
      Modules/CPack.cmake
  3. 4 1
      Modules/NSIS.template.in
  4. 25 6
      Source/CPack/cmCPackNSISGenerator.cxx

+ 18 - 2
CMakeCPack.cmake

@@ -38,11 +38,25 @@ IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
   ENDIF(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
   ENDIF(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
   SET(CPACK_PACKAGE_CONTACT "[email protected]")
   SET(CPACK_PACKAGE_CONTACT "[email protected]")
   IF(WIN32 AND NOT UNIX)
   IF(WIN32 AND NOT UNIX)
+    # set the install/unistall icon used for the installer itself
+    SET(CPACK_NSIS_MUI_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\CMakeLogo.ico")
+    SET(CPACK_NSIS_MUI_UNIICON "${CMake_SOURCE_DIR}/Utilities/Release\\CMakeLogo.ico")
     # There is a bug in NSI that does not handle full unix paths properly. Make
     # There is a bug in NSI that does not handle full unix paths properly. Make
     # sure there is at least one set of four (4) backlasshes.
     # sure there is at least one set of four (4) backlasshes.
-    SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\CMakeInstall.bmp")
+    SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\CMakeInstall.bmp")
     # tell cpack the executables you want in the start menu as links
     # tell cpack the executables you want in the start menu as links
     SET(CPACK_PACKAGE_EXECUTABLES "CMakeSetup" "CMake" )
     SET(CPACK_PACKAGE_EXECUTABLES "CMakeSetup" "CMake" )
+    # tell cpack to create a desktop link to CMakeSetup
+    SET(CPACK_CREATE_DESKTOP_LINK_CMakeSetup ON)
+    # These variables should have escapes preserved during the 
+    # translation to the CPackConfig.cmake file.  By default,
+    # CPack will require double escapes as it gets parsed by
+    # cmake twice
+    SET(CPACK_ESCAPE_VARIABLES 
+      CPACK_PACKAGE_ICON 
+      CPACK_NSIS_MUI_ICON 
+      CPACK_NSIS_MUI_UNIICON
+      )
     # tell cpack to create links to the doc files
     # tell cpack to create links to the doc files
     SET(CPACK_NSIS_MENU_LINKS
     SET(CPACK_NSIS_MENU_LINKS
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/CMakeSetup.html" "CMakeSetup Help"
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/CMakeSetup.html" "CMakeSetup Help"
@@ -52,7 +66,9 @@ IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/ctest.html" "CTest Help"
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/ctest.html" "CTest Help"
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/cmake-modules.html" "CMake Modules Help"
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/cmake-modules.html" "CMake Modules Help"
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/cmake-commands.html" "CMake Commands Help"
       "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/cmake-commands.html" "CMake Commands Help"
-      "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/cpack.html" "CPack Help")
+      "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/cpack.html" "CPack Help"
+      "http://www.cmake.org" "CMake Web Site"
+)
     SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\CMakeSetup.exe")
     SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\CMakeSetup.exe")
     SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} a cross-platform, open-source build system")
     SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} a cross-platform, open-source build system")
     SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.cmake.org")
     SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.cmake.org")

+ 78 - 6
Modules/CPack.cmake

@@ -19,6 +19,39 @@ MACRO(cpack_set_if_not_set name value)
   ENDIF(NOT DEFINED "${name}")
   ENDIF(NOT DEFINED "${name}")
 ENDMACRO(cpack_set_if_not_set)
 ENDMACRO(cpack_set_if_not_set)
 
 
+# create a new variable using var called
+# _${var}_ESC_ where var is the name of a variable.
+# the value of the new variable will have an extra
+# level of escapes so that it will preserve escapes
+# in the configured CPackConfig.cmake file.
+
+MACRO(cpack_escape_variable var)
+  STRING(REPLACE "\\" "\\\\" var_value "${${var}}")
+  STRING(REPLACE "\"" "\\\"" var_value "${var_value}")
+  SET(_${var}_ESC_ "${var_value}")
+ENDMACRO(cpack_escape_variable)
+
+# do extra escapes on variables in CPACK_ESCAPE_VARIABLE
+# create "special" value variables like this 
+# _(VARNAME)_ESC_ that store the extra escaped values for
+# the varibles.  This is because the original variables
+# can not be used because this file gets included more 
+# than once and things would get double double escacped.
+# (I think I want to escape...)
+MACRO(cpack_escape_variables)
+  SET(_CPACK_OTHER_VARIABLES_)
+  GET_CMAKE_PROPERTY(res VARIABLES)
+  # first add extra escapes to the variables in CPACK_ESCAPE_VARIABLES
+  FOREACH(var ${res})
+    IF("xxx${var}" MATCHES "xxxCPACK") 
+      list(FIND CPACK_ESCAPE_VARIABLES "${var}" _SHOULD_BE_ESCAPED)
+      if(_SHOULD_BE_ESCAPED GREATER -1)
+        cpack_escape_variable(${var})
+      endif(_SHOULD_BE_ESCAPED GREATER -1)
+    ENDIF("xxx${var}" MATCHES "xxxCPACK") 
+  ENDFOREACH(var ${res})
+ENDMACRO(cpack_escape_variables)
+
 # Macro to encode variables for the configuration file
 # Macro to encode variables for the configuration file
 # find any varable that stars with CPACK and create a variable
 # find any varable that stars with CPACK and create a variable
 # _CPACK_OTHER_VARIABLES_ that contains SET commands for
 # _CPACK_OTHER_VARIABLES_ that contains SET commands for
@@ -28,14 +61,22 @@ MACRO(cpack_encode_variables)
   SET(_CPACK_OTHER_VARIABLES_)
   SET(_CPACK_OTHER_VARIABLES_)
   GET_CMAKE_PROPERTY(res VARIABLES)
   GET_CMAKE_PROPERTY(res VARIABLES)
   FOREACH(var ${res})
   FOREACH(var ${res})
-    IF("xxx${var}" MATCHES "xxxCPACK")
-      SET(_CPACK_OTHER_VARIABLES_
-        "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")")
-    ENDIF("xxx${var}" MATCHES "xxxCPACK")
+    IF("xxx${var}" MATCHES "xxxCPACK")  
+      # check for special escaped variables and use
+      # the escaped value instead of the actual value for 
+      # the set.
+      list(FIND CPACK_ESCAPE_VARIABLES "${var}" _SHOULD_BE_ESCAPED)
+      if(_SHOULD_BE_ESCAPED GREATER -1)
+        SET(_CPACK_OTHER_VARIABLES_
+          "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${_${var}_ESC_}\")")
+      else(_SHOULD_BE_ESCAPED GREATER -1)
+        SET(_CPACK_OTHER_VARIABLES_
+          "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")")
+      endif(_SHOULD_BE_ESCAPED GREATER -1)
+      ENDIF("xxx${var}" MATCHES "xxxCPACK")
   ENDFOREACH(var ${res})
   ENDFOREACH(var ${res})
 ENDMACRO(cpack_encode_variables)
 ENDMACRO(cpack_encode_variables)
 
 
-
 # Set the package name
 # Set the package name
 cpack_set_if_not_set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
 cpack_set_if_not_set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
 cpack_set_if_not_set(CPACK_PACKAGE_VERSION_MAJOR "0")
 cpack_set_if_not_set(CPACK_PACKAGE_VERSION_MAJOR "0")
@@ -184,18 +225,48 @@ cpack_set_if_not_set(CPACK_USE_DESTDIR ON)
 cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
 cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
 
 
 cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
 cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
+cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
+
+# escape variables now before we do the icon define
+# stuff
+cpack_escape_variables()
 
 
 # if CPACK_PACKAGE_ICON is set, then create a 
 # if CPACK_PACKAGE_ICON is set, then create a 
 # cpack variable that contains the NSIS code to define
 # cpack variable that contains the NSIS code to define
 # the CPACK_PACKAGE_ICON and MUI_HEADERIMAGE_BITMAP, this is used
 # the CPACK_PACKAGE_ICON and MUI_HEADERIMAGE_BITMAP, this is used
 # as an icon in the install wizard
 # as an icon in the install wizard
+# handle ESC_CPACK_PACKAGE_ICON version as well, that does
+# not require extra escapes
+
 if(CPACK_PACKAGE_ICON)
 if(CPACK_PACKAGE_ICON)
-  set(CPACK_NSIS_INSTALLER_ICON_CODE "
+  if(DEFINED _CPACK_PACKAGE_ICON_ESC_)
+    set(CPACK_NSIS_INSTALLER_ICON_CODE "
+!define CPACK_PACKAGE_ICON \\\"@_CPACK_PACKAGE_ICON_ESC_@\\\"
+!define MUI_HEADERIMAGE_BITMAP \\\"@_CPACK_PACKAGE_ICON_ESC_@\\\"
+")
+  else(DEFINED _CPACK_PACKAGE_ICON_ESC_)
+    set(CPACK_NSIS_INSTALLER_ICON_CODE "
 !define CPACK_PACKAGE_ICON \\\"@CPACK_PACKAGE_ICON@\\\"
 !define CPACK_PACKAGE_ICON \\\"@CPACK_PACKAGE_ICON@\\\"
 !define MUI_HEADERIMAGE_BITMAP \\\"@CPACK_PACKAGE_ICON@\\\"
 !define MUI_HEADERIMAGE_BITMAP \\\"@CPACK_PACKAGE_ICON@\\\"
 ")
 ")
+  endif(DEFINED _CPACK_PACKAGE_ICON_ESC_)
 endif(CPACK_PACKAGE_ICON)
 endif(CPACK_PACKAGE_ICON)
 
 
+
+if(CPACK_NSIS_MUI_ICON AND CPACK_NSIS_MUI_UNIICON)
+  if(DEFINED _CPACK_NSIS_MUI_ICON_ESC_)
+    set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "
+!define MUI_ICON \\\"@_CPACK_NSIS_MUI_ICON_ESC_@\\\"
+!define MUI_UNICON \\\"@_CPACK_NSIS_MUI_UNIICON_ESC_@\\\"
+")
+  else(DEFINED _CPACK_NSIS_MUI_ICON_ESC_)
+    set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "
+!define MUI_ICON \\\"@CPACK_NSIS_MUI_ICON@\\\"
+!define MUI_UNICON \\\"@CPACK_NSIS_MUI_UNIICON@\\\"
+")
+  endif(DEFINED _CPACK_NSIS_MUI_ICON_ESC_)
+endif(CPACK_NSIS_MUI_ICON AND CPACK_NSIS_MUI_UNIICON)
+
 cpack_encode_variables()
 cpack_encode_variables()
 
 
 
 
@@ -218,6 +289,7 @@ SET(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
 SET(CPACK_IGNORE_FILES "${CPACK_SOURCE_IGNORE_FILES}")
 SET(CPACK_IGNORE_FILES "${CPACK_SOURCE_IGNORE_FILES}")
 SET(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}")
 SET(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}")
 
 
+cpack_escape_variables()
 cpack_encode_variables()
 cpack_encode_variables()
 configure_file("${cpack_source_input_file}"
 configure_file("${cpack_source_input_file}"
   "${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE)
   "${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE)

+ 4 - 1
Modules/NSIS.template.in

@@ -408,6 +408,7 @@ FunctionEnd
 
 
 ;--------------------------------
 ;--------------------------------
 ; Define some macro setting for the gui
 ; Define some macro setting for the gui
+@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
 @CPACK_NSIS_INSTALLER_ICON_CODE@
 @CPACK_NSIS_INSTALLER_ICON_CODE@
 
 
 ;--------------------------------
 ;--------------------------------
@@ -493,6 +494,7 @@ Section "Installer Section" InstSection
   ;Create shortcuts
   ;Create shortcuts
   CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
   CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
 @CPACK_NSIS_CREATE_ICONS@
 @CPACK_NSIS_CREATE_ICONS@
+@CPACK_NSIS_CREATE_ICONS_EXTRA@
   CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
   CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
 
 
   ; Write special uninstall registry entries
   ; Write special uninstall registry entries
@@ -602,6 +604,7 @@ Section "Uninstall"
     
     
   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
 @CPACK_NSIS_DELETE_ICONS@
 @CPACK_NSIS_DELETE_ICONS@
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
   
   
   ;Delete empty start menu parent diretories
   ;Delete empty start menu parent diretories
   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
@@ -620,7 +623,7 @@ Section "Uninstall"
   ; try to fix it.
   ; try to fix it.
   StrCpy $MUI_TEMP "$START_MENU"
   StrCpy $MUI_TEMP "$START_MENU"
   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
-@CPACK_NSIS_DELETE_ICONS@
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
   
   
   ;Delete empty start menu parent diretories
   ;Delete empty start menu parent diretories
   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"

+ 25 - 6
Source/CPack/cmCPackNSISGenerator.cxx

@@ -295,15 +295,34 @@ void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
         ++it )
         ++it )
     {
     {
     std::string sourceName = *it;
     std::string sourceName = *it;
+    bool url = false;
+    if(sourceName.find("http:") == 0)
+      {
+      url = true;
+      }
     /* convert / to \\ */
     /* convert / to \\ */
-    cmSystemTools::ReplaceString(sourceName, "/", "\\");
+    if(!url)
+      {
+      cmSystemTools::ReplaceString(sourceName, "/", "\\");
+      }
     ++ it;
     ++ it;
     std::string linkName = *it;
     std::string linkName = *it;
-    str << "  CreateShortCut \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
-        << linkName << ".lnk\" \"$INSTDIR\\" << sourceName << "\""
-        << std::endl;
-    deleteStr << "  Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
-              << ".lnk\"" << std::endl;
+    if(!url)
+      {
+      str << "  CreateShortCut \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
+          << linkName << ".lnk\" \"$INSTDIR\\" << sourceName << "\""
+          << std::endl;
+      deleteStr << "  Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
+                << ".lnk\"" << std::endl;
+      }
+    else
+      {
+      str << "  WriteINIStr \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
+          << linkName << ".url\" \"InternetShortcut\" \"URL\" \"" << sourceName << "\""
+          << std::endl;
+      deleteStr << "  Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
+                << ".url\"" << std::endl;
+      }
     // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
     // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
     // if so add a desktop link
     // if so add a desktop link
     std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";
     std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";