ソースを参照

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 年 前
コミット
02f79c7242
4 ファイル変更125 行追加15 行削除
  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)
   SET(CPACK_PACKAGE_CONTACT "[email protected]")
   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
     # 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
     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
     SET(CPACK_NSIS_MENU_LINKS
       "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}/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}/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_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} a cross-platform, open-source build system")
     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}")
 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
 # find any varable that stars with CPACK and create a variable
 # _CPACK_OTHER_VARIABLES_ that contains SET commands for
@@ -28,14 +61,22 @@ MACRO(cpack_encode_variables)
   SET(_CPACK_OTHER_VARIABLES_)
   GET_CMAKE_PROPERTY(res VARIABLES)
   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})
 ENDMACRO(cpack_encode_variables)
 
-
 # Set the package name
 cpack_set_if_not_set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
 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_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 
 # cpack variable that contains the NSIS code to define
 # the CPACK_PACKAGE_ICON and MUI_HEADERIMAGE_BITMAP, this is used
 # 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)
-  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 MUI_HEADERIMAGE_BITMAP \\\"@CPACK_PACKAGE_ICON@\\\"
 ")
+  endif(DEFINED _CPACK_PACKAGE_ICON_ESC_)
 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()
 
 
@@ -218,6 +289,7 @@ SET(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
 SET(CPACK_IGNORE_FILES "${CPACK_SOURCE_IGNORE_FILES}")
 SET(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}")
 
+cpack_escape_variables()
 cpack_encode_variables()
 configure_file("${cpack_source_input_file}"
   "${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
+@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
 @CPACK_NSIS_INSTALLER_ICON_CODE@
 
 ;--------------------------------
@@ -493,6 +494,7 @@ Section "Installer Section" InstSection
   ;Create shortcuts
   CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
 @CPACK_NSIS_CREATE_ICONS@
+@CPACK_NSIS_CREATE_ICONS_EXTRA@
   CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
 
   ; Write special uninstall registry entries
@@ -602,6 +604,7 @@ Section "Uninstall"
     
   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
 @CPACK_NSIS_DELETE_ICONS@
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
   
   ;Delete empty start menu parent diretories
   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
@@ -620,7 +623,7 @@ Section "Uninstall"
   ; try to fix it.
   StrCpy $MUI_TEMP "$START_MENU"
   Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
-@CPACK_NSIS_DELETE_ICONS@
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
   
   ;Delete empty start menu parent diretories
   StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"

+ 25 - 6
Source/CPack/cmCPackNSISGenerator.cxx

@@ -295,15 +295,34 @@ void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
         ++it )
     {
     std::string sourceName = *it;
+    bool url = false;
+    if(sourceName.find("http:") == 0)
+      {
+      url = true;
+      }
     /* convert / to \\ */
-    cmSystemTools::ReplaceString(sourceName, "/", "\\");
+    if(!url)
+      {
+      cmSystemTools::ReplaceString(sourceName, "/", "\\");
+      }
     ++ 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
     // if so add a desktop link
     std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";