diff --git a/CMake/Modules/NSIS.template.in b/CMake/Modules/NSIS.template.in new file mode 100644 index 000000000..9e171e283 --- /dev/null +++ b/CMake/Modules/NSIS.template.in @@ -0,0 +1,1056 @@ +; CPack install script designed for a nmake build + +;-------------------------------- +; You must define these values + + !define VERSION "@CPACK_PACKAGE_VERSION@" + !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@" + !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" + +;-------------------------------- +;Variables + + Var MUI_TEMP + Var STARTMENU_FOLDER + Var SV_ALLUSERS + Var START_MENU + Var RB_DO_NOT_ADD_TO_PATH + Var DO_NOT_ADD_TO_PATH + Var RB_ADD_TO_PATH_ALL_USERS + Var ADD_TO_PATH_ALL_USERS + Var RB_ADD_TO_PATH_CURRENT_USER + Var ADD_TO_PATH_CURRENT_USER + Var CB_INSTALL_DESKTOP + Var INSTALL_DESKTOP + Var IS_DEFAULT_INSTALLDIR + +;-------------------------------- +;Include Modern UI + + !include "MUI2.nsh" + !include "nsDialogs.nsh" + +;-------------------------------- +;Include Logic Lib and add a DirExists command + + !include "LogicLib.nsh" +;FileExists is already part of LogicLib, but returns true for directories as well as files + !macro _FileExists2 _a _b _t _f + !insertmacro _LOGICLIB_TEMP + StrCpy $_LOGICLIB_TEMP '0' + StrCmp `${_b}` `` +4 0 ;if path is not blank, continue to next check + IfFileExists `${_b}` `0` +3 ;if path exists, continue to next check (IfFileExists returns true if this is a directory) + IfFileExists `${_b}\*.*` +2 0 ;if path is not a directory, continue to confirm exists + StrCpy $_LOGICLIB_TEMP '1' ;file exists + ;now we have a definitive value - the file exists or it does not + StrCmp $_LOGICLIB_TEMP '1' `${_t}` `${_f}` + !macroend + !undef FileExists + !define FileExists `'' FileExists2` + !macro _DirExists _a _b _t _f + !insertmacro _LOGICLIB_TEMP + StrCpy $_LOGICLIB_TEMP '0' + StrCmp `${_b}` `` +3 0 ;if path is not blank, continue to next check + IfFileExists `${_b}\*.*` 0 +2 ;if directory exists, continue to confirm exists + StrCpy $_LOGICLIB_TEMP '1' + StrCmp $_LOGICLIB_TEMP '1' `${_t}` `${_f}` + !macroend + !define DirExists `'' DirExists` + + ;Default installation folder + InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" + +;-------------------------------- +;General + + ;Name and file + Name "@CPACK_NSIS_PACKAGE_NAME@" + OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" + + ;Set compression + SetCompressor @CPACK_NSIS_COMPRESSOR@ + + ;Require administrator access + RequestExecutionLevel admin + +@CPACK_NSIS_DEFINES@ +@CPACK_NSIS_EXTRA_DEFINES@ + + !include Sections.nsh + +;--- Component support macros: --- +; The code for the add/remove functionality is from: +; http://nsis.sourceforge.net/Add/Remove_Functionality +; It has been modified slightly and extended to provide +; inter-component dependencies. +Var AR_SecFlags +Var AR_RegFlags +@CPACK_NSIS_SECTION_SELECTED_VARS@ + +; Loads the "selected" flag for the section named SecName into the +; variable VarName. +!macro LoadSectionSelectedIntoVar SecName VarName + SectionGetFlags ${${SecName}} $${VarName} + IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits +!macroend + +; Loads the value of a variable... can we get around this? +!macro LoadVar VarName + IntOp $R0 0 + $${VarName} +!macroend + +; Sets the value of a variable +!macro StoreVar VarName IntValue + IntOp $${VarName} 0 + ${IntValue} +!macroend + +!macro InitSection SecName + ; This macro reads component installed flag from the registry and + ;changes checked state of the section on the components page. + ;Input: section index constant name specified in Section command. + + ClearErrors + ;Reading component status from registry + ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed" + IfErrors "default_${SecName}" + ;Status will stay default if registry value not found + ;(component was never installed) + IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits + SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags + IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off + IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit + + ; Note whether this component was installed before + !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags + IntOp $R0 $AR_RegFlags & $AR_RegFlags + + ;Writing modified flags + SectionSetFlags ${${SecName}} $AR_SecFlags + + "default_${SecName}:" + !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected +!macroend + +!macro FinishSection SecName + ; This macro reads section flag set by user and removes the section + ;if it is not selected. + ;Then it writes component installed flag to registry + ;Input: section index constant name specified in Section command. + + SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags + ;Checking lowest bit: + IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED} + IntCmp $AR_SecFlags 1 "leave_${SecName}" + ;Section is not selected: + ;Calling Section uninstall macro and writing zero installed flag + !insertmacro "Remove_${${SecName}}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ + "Installed" 0 + Goto "exit_${SecName}" + + "leave_${SecName}:" + ;Section is selected: + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ + "Installed" 1 + + "exit_${SecName}:" +!macroend + +!macro RemoveSection_CPack SecName + ; This macro is used to call section's Remove_... macro + ;from the uninstaller. + ;Input: section index constant name specified in Section command. + + !insertmacro "Remove_${${SecName}}" +!macroend + +; Determine whether the selection of SecName changed +!macro MaybeSelectionChanged SecName + !insertmacro LoadVar ${SecName}_selected + SectionGetFlags ${${SecName}} $R1 + IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits + + ; See if the status has changed: + IntCmp $R0 $R1 "${SecName}_unchanged" + !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected + + IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected" + !insertmacro "Deselect_required_by_${SecName}" + goto "${SecName}_unchanged" + + "${SecName}_was_selected:" + !insertmacro "Select_${SecName}_depends" + + "${SecName}_unchanged:" +!macroend +;--- End of Add/Remove macros --- + +;-------------------------------- +;Interface Settings + + !define MUI_HEADERIMAGE + !define MUI_ABORTWARNING + !define MUI_FINISHPAGE_NOAUTOCLOSE + +;-------------------------------- +; path functions + +!verbose 3 +!include "WinMessages.NSH" +!verbose 4 + +;---------------------------------------- +; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02" +;---------------------------------------- +!verbose 3 +!include "WinMessages.NSH" +!verbose 4 +;==================================================== +; get_NT_environment +; Returns: the selected environment +; Output : head of the stack +;==================================================== +!macro select_NT_profile UN +Function ${UN}select_NT_profile + ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED} + DetailPrint "Selected environment for all users" + Push "all" + ${Else} + DetailPrint "Selected environment for current user only." + Push "current" + ${EndIf} +FunctionEnd +!macroend +!insertmacro select_NT_profile "" +!insertmacro select_NT_profile "un." +;---------------------------------------------------- +!define NT_current_env 'HKCU "Environment"' +!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' + +!ifndef WriteEnvStr_RegKey + !ifdef ALL_USERS + !define WriteEnvStr_RegKey \ + 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' + !else + !define WriteEnvStr_RegKey 'HKCU "Environment"' + !endif +!endif + +; AddToPath - Adds the given dir to the search path. +; Input - head of the stack +; Note - Win9x systems requires reboot + +Function AddToPath + Exch $0 + Push $1 + Push $2 + Push $3 + + # don't add if the path doesn't exist + IfFileExists "$0\*.*" "" AddToPath_done + + ReadEnvStr $1 PATH + ; if the path is too long for a NSIS variable NSIS will return a 0 + ; length string. If we find that, then warn and skip any path + ; modification as it will trash the existing path. + StrLen $2 $1 + IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done + CheckPathLength_ShowPathWarning: + Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!" + Goto AddToPath_done + CheckPathLength_Done: + Push "$1;" + Push "$0;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + Push "$1;" + Push "$0\;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + GetFullPathName /SHORT $3 $0 + Push "$1;" + Push "$3;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + Push "$1;" + Push "$3\;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + + Call IsNT + Pop $1 + StrCmp $1 1 AddToPath_NT + ; Not on NT + StrCpy $1 $WINDIR 2 + FileOpen $1 "$1\autoexec.bat" a + FileSeek $1 -1 END + FileReadByte $1 $2 + IntCmp $2 26 0 +2 +2 # DOS EOF + FileSeek $1 -1 END # write over EOF + FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" + FileClose $1 + SetRebootFlag true + Goto AddToPath_done + + AddToPath_NT: + ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED} + ReadRegStr $1 ${NT_all_env} "PATH" + ${Else} + ReadRegStr $1 ${NT_current_env} "PATH" + ${EndIf} + StrCmp $1 "" AddToPath_NTdoIt + Push $1 + Call Trim + Pop $1 + StrCpy $0 "$1;$0" + AddToPath_NTdoIt: + ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED} + WriteRegExpandStr ${NT_all_env} "PATH" $0 + ${Else} + WriteRegExpandStr ${NT_current_env} "PATH" $0 + ${EndIf} + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + AddToPath_done: + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + + +; RemoveFromPath - Remove a given dir from the path +; Input: head of the stack + +Function un.RemoveFromPath + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + + IntFmt $6 "%c" 26 # DOS EOF + + Call un.IsNT + Pop $1 + StrCmp $1 1 unRemoveFromPath_NT + ; Not on NT + StrCpy $1 $WINDIR 2 + FileOpen $1 "$1\autoexec.bat" r + GetTempFileName $4 + FileOpen $2 $4 w + GetFullPathName /SHORT $0 $0 + StrCpy $0 "SET PATH=%PATH%;$0" + Goto unRemoveFromPath_dosLoop + + unRemoveFromPath_dosLoop: + FileRead $1 $3 + StrCpy $5 $3 1 -1 # read last char + StrCmp $5 $6 0 +2 # if DOS EOF + StrCpy $3 $3 -1 # remove DOS EOF so we can compare + StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine + StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine + StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine + StrCmp $3 "" unRemoveFromPath_dosLoopEnd + FileWrite $2 $3 + Goto unRemoveFromPath_dosLoop + unRemoveFromPath_dosLoopRemoveLine: + SetRebootFlag true + Goto unRemoveFromPath_dosLoop + + unRemoveFromPath_dosLoopEnd: + FileClose $2 + FileClose $1 + StrCpy $1 $WINDIR 2 + Delete "$1\autoexec.bat" + CopyFiles /SILENT $4 "$1\autoexec.bat" + Delete $4 + Goto unRemoveFromPath_done + + unRemoveFromPath_NT: + ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED} + ReadRegStr $1 ${NT_all_env} "PATH" + ${Else} + ReadRegStr $1 ${NT_current_env} "PATH" + ${EndIf} + StrCpy $5 $1 1 -1 # copy last char + StrCmp $5 ";" +2 # if last char != ; + StrCpy $1 "$1;" # append ; + Push $1 + Push "$0;" + Call un.StrStr ; Find `$0;` in $1 + Pop $2 ; pos of our dir + StrCmp $2 "" unRemoveFromPath_done + ; else, it is in path + # $0 - path to add + # $1 - path var + StrLen $3 "$0;" + StrLen $4 $2 + StrCpy $5 $1 -$4 # $5 is now the part before the path to remove + StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove + StrCpy $3 $5$6 + + StrCpy $5 $3 1 -1 # copy last char + StrCmp $5 ";" 0 +2 # if last char == ; + StrCpy $3 $3 -1 # remove last char + + ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED} + WriteRegExpandStr ${NT_all_env} "PATH" $3 + ${Else} + WriteRegExpandStr ${NT_current_env} "PATH" $3 + ${EndIf} + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + unRemoveFromPath_done: + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Uninstall sutff +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +########################################### +# Utility Functions # +########################################### + +;==================================================== +; IsNT - Returns 1 if the current system is NT, 0 +; otherwise. +; Output: head of the stack +;==================================================== +; IsNT +; no input +; output, top of the stack = 1 if NT or 0 if not +; +; Usage: +; Call IsNT +; Pop $R0 +; ($R0 at this point is 1 or 0) + +!macro IsNT un +Function ${un}IsNT + Push $0 + ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion + StrCmp $0 "" 0 IsNT_yes + ; we are not NT. + Pop $0 + Push 0 + Return + + IsNT_yes: + ; NT!!! + Pop $0 + Push 1 +FunctionEnd +!macroend +!insertmacro IsNT "" +!insertmacro IsNT "un." + +; StrStr +; input, top of stack = string to search for +; top of stack-1 = string to search in +; output, top of stack (replaces with the portion of the string remaining) +; modifies no other variables. +; +; Usage: +; Push "this is a long ass string" +; Push "ass" +; Call StrStr +; Pop $R0 +; ($R0 at this point is "ass string") + +!macro StrStr un +Function ${un}StrStr +Exch $R1 ; st=haystack,old$R1, $R1=needle + Exch ; st=old$R1,haystack + Exch $R2 ; st=old$R1,old$R2, $R2=haystack + Push $R3 + Push $R4 + Push $R5 + StrLen $R3 $R1 + StrCpy $R4 0 + ; $R1=needle + ; $R2=haystack + ; $R3=len(needle) + ; $R4=cnt + ; $R5=tmp + loop: + StrCpy $R5 $R2 $R3 $R4 + StrCmp $R5 $R1 done + StrCmp $R5 "" done + IntOp $R4 $R4 + 1 + Goto loop +done: + StrCpy $R1 $R2 "" $R4 + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Exch $R1 +FunctionEnd +!macroend +!insertmacro StrStr "" +!insertmacro StrStr "un." + +Function Trim ; Added by Pelaca + Exch $R1 + Push $R2 +Loop: + StrCpy $R2 "$R1" 1 -1 + StrCmp "$R2" " " RTrim + StrCmp "$R2" "$\n" RTrim + StrCmp "$R2" "$\r" RTrim + StrCmp "$R2" ";" RTrim + GoTo Done +RTrim: + StrCpy $R1 "$R1" -1 + Goto Loop +Done: + Pop $R2 + Exch $R1 +FunctionEnd + +Function ConditionalAddToRegisty + Pop $0 + Pop $1 + StrCmp "$0" "" ConditionalAddToRegisty_EmptyString + WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ + "$1" "$0" + ;MessageBox MB_OK "Set Registry: '$1' to '$0'" + DetailPrint "Set install registry entry: '$1' to '$0'" + ConditionalAddToRegisty_EmptyString: +FunctionEnd + +;-------------------------------- + +!ifdef CPACK_USES_DOWNLOAD +Function DownloadFile + IfFileExists $INSTDIR\* +2 + CreateDirectory $INSTDIR + Pop $0 + + ; Skip if already downloaded + IfFileExists $INSTDIR\$0 0 +2 + Return + + StrCpy $1 "@CPACK_DOWNLOAD_SITE@" + + try_again: + NSISdl::download "$1/$0" "$INSTDIR\$0" + + Pop $1 + StrCmp $1 "success" success + StrCmp $1 "Cancelled" cancel + MessageBox MB_OK "Download failed: $1" + cancel: + Return + success: +FunctionEnd +!endif + +;-------------------------------- +; Installation types +@CPACK_NSIS_INSTALLATION_TYPES@ + +;-------------------------------- +; Component sections +@CPACK_NSIS_COMPONENT_SECTIONS@ + +;-------------------------------- +; Define some macro setting for the gui +@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@ +@CPACK_NSIS_INSTALLER_ICON_CODE@ +@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ +@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@ + +;-------------------------------- +;Pages + !insertmacro MUI_PAGE_WELCOME + + !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@" + Page custom InstallOptionsPage InstallOptionsPageLeave + !insertmacro MUI_PAGE_DIRECTORY + + ;Start Menu Folder Page Configuration + !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX" + !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" + !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER + + @CPACK_NSIS_PAGE_COMPONENTS@ + + @CPACK_NSIS_EXTRA_PAGES@ + + !insertmacro MUI_PAGE_INSTFILES + !insertmacro MUI_PAGE_FINISH + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" ;first language is the default language + !insertmacro MUI_LANGUAGE "Albanian" + !insertmacro MUI_LANGUAGE "Arabic" + !insertmacro MUI_LANGUAGE "Basque" + !insertmacro MUI_LANGUAGE "Belarusian" + !insertmacro MUI_LANGUAGE "Bosnian" + !insertmacro MUI_LANGUAGE "Breton" + !insertmacro MUI_LANGUAGE "Bulgarian" + !insertmacro MUI_LANGUAGE "Croatian" + !insertmacro MUI_LANGUAGE "Czech" + !insertmacro MUI_LANGUAGE "Danish" + !insertmacro MUI_LANGUAGE "Dutch" + !insertmacro MUI_LANGUAGE "Estonian" + !insertmacro MUI_LANGUAGE "Farsi" + !insertmacro MUI_LANGUAGE "Finnish" + !insertmacro MUI_LANGUAGE "French" + !insertmacro MUI_LANGUAGE "German" + !insertmacro MUI_LANGUAGE "Greek" + !insertmacro MUI_LANGUAGE "Hebrew" + !insertmacro MUI_LANGUAGE "Hungarian" + !insertmacro MUI_LANGUAGE "Icelandic" + !insertmacro MUI_LANGUAGE "Indonesian" + !insertmacro MUI_LANGUAGE "Irish" + !insertmacro MUI_LANGUAGE "Italian" + !insertmacro MUI_LANGUAGE "Japanese" + !insertmacro MUI_LANGUAGE "Korean" + !insertmacro MUI_LANGUAGE "Kurdish" + !insertmacro MUI_LANGUAGE "Latvian" + !insertmacro MUI_LANGUAGE "Lithuanian" + !insertmacro MUI_LANGUAGE "Luxembourgish" + !insertmacro MUI_LANGUAGE "Macedonian" + !insertmacro MUI_LANGUAGE "Malay" + !insertmacro MUI_LANGUAGE "Mongolian" + !insertmacro MUI_LANGUAGE "Norwegian" + !insertmacro MUI_LANGUAGE "Polish" + !insertmacro MUI_LANGUAGE "Portuguese" + !insertmacro MUI_LANGUAGE "PortugueseBR" + !insertmacro MUI_LANGUAGE "Romanian" + !insertmacro MUI_LANGUAGE "Russian" + !insertmacro MUI_LANGUAGE "Serbian" + !insertmacro MUI_LANGUAGE "SerbianLatin" + !insertmacro MUI_LANGUAGE "SimpChinese" + !insertmacro MUI_LANGUAGE "Slovak" + !insertmacro MUI_LANGUAGE "Slovenian" + !insertmacro MUI_LANGUAGE "Spanish" + !insertmacro MUI_LANGUAGE "Swedish" + !insertmacro MUI_LANGUAGE "Thai" + !insertmacro MUI_LANGUAGE "TradChinese" + !insertmacro MUI_LANGUAGE "Turkish" + !insertmacro MUI_LANGUAGE "Ukrainian" + !insertmacro MUI_LANGUAGE "Welsh" + + +;-------------------------------- +;Reserve Files + + ;These files should be inserted before other files in the data block + ;Keep these lines before any File command + ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) + +;-------------------------------- +;Installer Sections + +Section "-Core installation" + ;Use the entire tree produced by the INSTALL target. Keep the + ;list of directories here in sync with the RMDir commands below. + SetOutPath "$INSTDIR" + @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ + @CPACK_NSIS_FULL_INSTALL@ + + ;Store installation folder + WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR + + ;Create uninstaller + WriteUninstaller "$INSTDIR\Uninstall.exe" + Push "DisplayName" + Push "@CPACK_NSIS_DISPLAY_NAME@" + Call ConditionalAddToRegisty + Push "DisplayVersion" + Push "@CPACK_PACKAGE_VERSION@" + Call ConditionalAddToRegisty + Push "Publisher" + Push "@CPACK_PACKAGE_VENDOR@" + Call ConditionalAddToRegisty + Push "UninstallString" + Push "$INSTDIR\Uninstall.exe" + Call ConditionalAddToRegisty + Push "NoRepair" + Push "1" + Call ConditionalAddToRegisty + + !ifdef CPACK_NSIS_ADD_REMOVE + ;Create add/remove functionality + Push "ModifyPath" + Push "$INSTDIR\AddRemove.exe" + Call ConditionalAddToRegisty + !else + Push "NoModify" + Push "1" + Call ConditionalAddToRegisty + !endif + + ; Optional registration + Push "DisplayIcon" + Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@" + Call ConditionalAddToRegisty + Push "HelpLink" + Push "@CPACK_NSIS_HELP_LINK@" + Call ConditionalAddToRegisty + Push "URLInfoAbout" + Push "@CPACK_NSIS_URL_INFO_ABOUT@" + Call ConditionalAddToRegisty + Push "Contact" + Push "@CPACK_NSIS_CONTACT@" + Call ConditionalAddToRegisty + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + + ;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 + Push "StartMenu" + Push "$STARTMENU_FOLDER" + Call ConditionalAddToRegisty + WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ + "DoNotAddToPath" $DO_NOT_ADD_TO_PATH + WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ + "AddToPathAllUsers" $ADD_TO_PATH_ALL_USERS + WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ + "AddToPathCurrentUser" $ADD_TO_PATH_CURRENT_USER + WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ + "InstallToDesktop" $INSTALL_DESKTOP + + !insertmacro MUI_STARTMENU_WRITE_END + +@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ + +SectionEnd + +Section "-Add to path" + Push $INSTDIR\bin + ${If} "@CPACK_NSIS_MODIFY_PATH@" == "ON" + ${If} $DO_NOT_ADD_TO_PATH = ${BST_UNCHECKED} + Call AddToPath + ${EndIf} + ${EndIf} +SectionEnd + +;-------------------------------- +; Create custom pages +Function InstallOptionsPage + Push $R0 + Push $0 + + !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@" + + nsDialogs::Create 1018 + Pop $R0 + ${If} $R0 == error + Abort + ${EndIf} + + ${NSD_CreateLabel} 0u 0u 100% 20u 'By default @CPACK_PACKAGE_INSTALL_DIRECTORY@ does not add its directory to the system PATH.' + Pop $0 + + ${NSD_CreateRadioButton} 0u 30u 100% 10u 'Do not add @CPACK_PACKAGE_NAME@ to the system PATH' + Pop $RB_DO_NOT_ADD_TO_PATH + ${NSD_SetState} $RB_DO_NOT_ADD_TO_PATH $DO_NOT_ADD_TO_PATH + + ${NSD_CreateRadioButton} 0u 40u 100% 10u 'Add @CPACK_PACKAGE_NAME@ to the system PATH for all users' + Pop $RB_ADD_TO_PATH_ALL_USERS + ${NSD_SetState} $RB_ADD_TO_PATH_ALL_USERS $ADD_TO_PATH_ALL_USERS + + ${NSD_CreateRadioButton} 0u 50u 100% 10u 'Add @CPACK_PACKAGE_NAME@ to the system PATH for the current user' + Pop $RB_ADD_TO_PATH_CURRENT_USER + ${NSD_SetState} $RB_ADD_TO_PATH_CURRENT_USER $ADD_TO_PATH_CURRENT_USER + + ${NSD_CreateCheckBox} 0u 80u 100% 10u 'Create @CPACK_PACKAGE_NAME@ Desktop Icon' + Pop $CB_INSTALL_DESKTOP + ${NSD_SetState} $CB_INSTALL_DESKTOP $INSTALL_DESKTOP + + @CPACK_NSIS_EXTRA_INSTALL_OPTIONS@ + + nsDialogs::Show + + Pop $0 + Pop $R0 +FunctionEnd + +Function InstallOptionsPageLeave + ${NSD_GetState} $RB_DO_NOT_ADD_TO_PATH $DO_NOT_ADD_TO_PATH + ${NSD_GetState} $RB_ADD_TO_PATH_ALL_USERS $ADD_TO_PATH_ALL_USERS + ${NSD_GetState} $RB_ADD_TO_PATH_CURRENT_USER $ADD_TO_PATH_CURRENT_USER + + ${NSD_GetState} $CB_INSTALL_DESKTOP $INSTALL_DESKTOP + + @CPACK_NSIS_EXTRA_INSTALL_OPTIONS_READ@ +FunctionEnd + +;-------------------------------- +; determine admin versus local install +Function un.onInit + Push $0 + Push $1 + + ClearErrors + UserInfo::GetName + IfErrors noLM + Pop $0 + UserInfo::GetAccountType + Pop $1 + StrCmp $1 "Admin" 0 +3 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Admin group' + Goto done + StrCmp $1 "Power" 0 +3 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Power Users group' + Goto done + + noLM: + ;Get installation folder from registry if available + + done: + + Pop $1 + Pop $0 +FunctionEnd + +;--- Add/Remove callback functions: --- +!macro SectionList MacroName + ;This macro used to perform operation on multiple sections. + ;List all of your components in following manner here. +@CPACK_NSIS_COMPONENT_SECTION_LIST@ +!macroend + +Section -FinishComponents + ;Removes unselected components and writes component status to registry + !insertmacro SectionList "FinishSection" + +!ifdef CPACK_NSIS_ADD_REMOVE + ; Get the name of the installer executable + System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1' + StrCpy $R3 $R0 + + ; Strip off the last 13 characters, to see if we have AddRemove.exe + StrLen $R1 $R0 + IntOp $R1 $R0 - 13 + StrCpy $R2 $R0 13 $R1 + StrCmp $R2 "AddRemove.exe" addremove_installed + + ; We're not running AddRemove.exe, so install it + CopyFiles $R3 $INSTDIR\AddRemove.exe + + addremove_installed: +!endif +SectionEnd +;--- End of Add/Remove callback functions --- + +;-------------------------------- +; Component dependencies +Function .onSelChange + !insertmacro SectionList MaybeSelectionChanged +FunctionEnd + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + ReadRegStr $START_MENU SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu" + ;MessageBox MB_OK "Start menu is in: $START_MENU" + ReadRegDWORD $DO_NOT_ADD_TO_PATH SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath" + ReadRegDWORD $ADD_TO_PATH_ALL_USERS SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers" + ReadRegDWORD $ADD_TO_PATH_CURRENT_USER SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser" + ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS" + ReadRegDWORD $INSTALL_DESKTOP SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop" + ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP " + +@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ + + ;Remove files we installed. + ;Keep the list of directories here in sync with the File commands above. +@CPACK_NSIS_DELETE_FILES@ +@CPACK_NSIS_DELETE_DIRECTORIES@ + +!ifdef CPACK_NSIS_ADD_REMOVE + ;Remove the add/remove program + Delete "$INSTDIR\AddRemove.exe" +!endif + + ;Remove the uninstaller itself. + Delete "$INSTDIR\Uninstall.exe" + DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + + ;Remove the installation directory if it is empty. + RMDir "$INSTDIR" + + ; Remove the registry entries. + DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + + ; Removes all optional components + !insertmacro SectionList "RemoveSection_CPack" + + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + + 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" + + startMenuDeleteLoop: + ClearErrors + RMDir $MUI_TEMP + GetFullPathName $MUI_TEMP "$MUI_TEMP\.." + + IfErrors startMenuDeleteLoopDone + + StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop + startMenuDeleteLoopDone: + + ; If the user changed the shortcut, then untinstall may not work. This should + ; try to fix it. + StrCpy $MUI_TEMP "$START_MENU" + Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" +@CPACK_NSIS_DELETE_ICONS_EXTRA@ + + ;Delete empty start menu parent diretories + StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" + + secondStartMenuDeleteLoop: + ClearErrors + RMDir $MUI_TEMP + GetFullPathName $MUI_TEMP "$MUI_TEMP\.." + + IfErrors secondStartMenuDeleteLoopDone + + StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop + secondStartMenuDeleteLoopDone: + + DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + + Push $INSTDIR\bin + ${Unless} $DO_NOT_ADD_TO_PATH = ${BST_CHECKED} + Call un.RemoveFromPath + ${EndUnless} +SectionEnd + +;-------------------------------- +; determine admin versus local install +; Is install for "AllUsers" or "JustMe"? +; Default to "JustMe" - set to "AllUsers" if admin or on Win9x +; This function is used for the very first "custom page" of the installer. +; This custom page does not show up visibly, but it executes prior to the +; first visible page and sets up $INSTDIR properly... +; Choose different default installation folder based on SV_ALLUSERS... +; "Program Files" for AllUsers, "My Documents" for JustMe... + +Function .onInit + Push $0 + Push $1 + Push $2 + Push $3 + + StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst + + ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString" + StrCmp $0 "" inst + + MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \ + "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \ + IDYES uninst IDNO inst + Abort + +;Run the uninstaller +uninst: + ClearErrors + StrLen $2 "\Uninstall.exe" + StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path + ExecWait '$0 _?=$3' ;Do not copy the uninstaller to a temp file + + IfErrors uninst_failed inst +uninst_failed: + MessageBox MB_OK|MB_ICONSTOP "Uninstall failed." + Abort + + +inst: + ; Reads components status for registry + !insertmacro SectionList "InitSection" + + ; check to see if /D has been used to change + ; the install directory by comparing it to the + ; install directory that is expected to be the + ; default + StrCpy $IS_DEFAULT_INSTALLDIR 0 + StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2 + StrCpy $IS_DEFAULT_INSTALLDIR 1 + + StrCpy $SV_ALLUSERS "JustMe" + ; if default install dir then change the default + ; if it is installed for JustMe + StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 + StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@" + + ClearErrors + UserInfo::GetName + IfErrors noLM + Pop $0 + UserInfo::GetAccountType + Pop $1 + StrCmp $1 "Admin" 0 +4 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Admin group' + StrCpy $SV_ALLUSERS "AllUsers" + Goto done + StrCmp $1 "Power" 0 +4 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Power Users group' + StrCpy $SV_ALLUSERS "AllUsers" + Goto done + + noLM: + StrCpy $SV_ALLUSERS "AllUsers" + ;Get installation folder from registry if available + + done: + StrCmp $SV_ALLUSERS "AllUsers" 0 +3 + StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 + StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" + + IntOp $DO_NOT_ADD_TO_PATH 0 + ${BST_CHECKED} ; set to checked + IntOp $ADD_TO_PATH_ALL_USERS 0 + ${BST_UNCHECKED} ; set to unchecked + IntOp $ADD_TO_PATH_CURRENT_USER 0 + ${BST_UNCHECKED} ; ditto + IntOp $INSTALL_DESKTOP 0 + ${BST_UNCHECKED} ; set to unchecked + + @CPACK_NSIS_EXTRA_INIT_COMMANDS@ + + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd diff --git a/CMake/download_kvasd.cmake b/CMake/download_kvasd.cmake index 603d62fee..18c8649dc 100644 --- a/CMake/download_kvasd.cmake +++ b/CMake/download_kvasd.cmake @@ -1,25 +1,34 @@ # # CMake script to fetch kvasd binary for the current platform # -set (kvasd_NAME https://svn.code.sf.net/p/wsjt/wsjt/trunk/kvasd-binary/${SYSTEM_NAME}/kvasd${EXECUTABLE_SUFFIX}) +set (kvasd_NAME ${URL}/${SYSTEM_NAME}/kvasd${EXECUTABLE_SUFFIX}) message (STATUS "file: ${kvasd_NAME}") -if (APPLE) - set (__kvasd_md5sum 198dbdde1e4b04f9940f63731097ee35) -elseif (WIN32) - set (__kvasd_md5sum 7b16809e51126a01bd02aed44427510c) -elseif (UNIX) - set (__kvasd_md5sum 28a6f8ba2efc3df02af2a781bd3ab654) -endif () + +file ( + DOWNLOAD ${kvasd_NAME}.md5 contrib/kvasd${EXECUTABLE_SUFFIX}.md5 + TIMEOUT 120 + STATUS status + LOG log + SHOW_PROGRESS + ) +list (GET staus 0 rc) +if (rc) + message (WARNING "${status}") + message (FATAL_ERROR "${log}") +endif (rc) +file (READ contrib/kvasd${EXECUTABLE_SUFFIX}.md5 md5sum) +string (REGEX MATCH "[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]" md5sum ${md5sum}) + file ( DOWNLOAD ${kvasd_NAME} contrib/kvasd${EXECUTABLE_SUFFIX} TIMEOUT 120 - STATUS kvasd_STATUS - LOG kvasd_LOG + STATUS status + LOG log SHOW_PROGRESS - EXPECTED_MD5 ${__kvasd_md5sum} + EXPECTED_MD5 ${md5sum} ) -list (GET kvasd_STATUS 0 kvasd_RC) -if (kvasd_RC) - message (WARNING "${kvasd_STATUS}") - message (FATAL_ERROR "${kvasd_LOG}") -endif (kvasd_RC) +list (GET status 0 rc) +if (rc) + message (WARNING "${status}") + message (FATAL_ERROR "${log}") +endif (rc) diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in index feb6936e8..0ed5f5e81 100644 --- a/CMakeCPackOptions.cmake.in +++ b/CMakeCPackOptions.cmake.in @@ -15,9 +15,11 @@ set (CPACK_STRIP_FILES TRUE) # # components # -#set (CPACK_COMPONENTS_ALL Unspecified Runtime) -#set (CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "@PROJECT_NAME@ Application") -#set (CPACK_COMPONENT_APPLICATIONS_DESCRIPTION "@WSJTX_DESCRIPTION_SUMMARY@") +#set (CPACK_COMPONENTS_ALL runtime kvasd) +#set (CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "@PROJECT_NAME@ Application") +#set (CPACK_COMPONENT_RUNTIME_DESCRIPTION "@WSJTX_DESCRIPTION_SUMMARY@") +#set (CPACK_COMPONENT_KVASD_DISPLAY_NAME "KVASD Reed Solomon Decoder") +#set (CPACK_COMPONENT_KVASD_DESCRIPTION "Optional decoder component") if (CPACK_GENERATOR MATCHES "NSIS") set (CPACK_STRIP_FILES FALSE) # breaks Qt packaging on Windows @@ -44,6 +46,191 @@ if (CPACK_GENERATOR MATCHES "NSIS") set (CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}") set (CPACK_NSIS_MUI_FINISHPAGE_RUN "wsjtx.exe") set (CPACK_NSIS_MODIFY_PATH ON) + + set (CPACK_NSIS_EXTRA_DEFINES " + ; + ; enable local plugins + ; + !ifdef NSIS_WIN32_MAKENSIS + !define NSISCONF_3 ';' ; NSIS 2 tries to parse some preprocessor instructions inside \"!if 0\" blocks! + !addincludedir '@CMAKE_CURRENT_SOURCE_DIR@\\contrib\\NSIS\\Include' + !if \${NSIS_PACKEDVERSION} > 0x02ffffff ; NSIS 3+: + !define /redef NSISCONF_3 '' + \${NSISCONF_3} !addplugindir /x86-ansi '@CMAKE_CURRENT_SOURCE_DIR@\\contrib\\NSIS\\Plugins-i386-ansi' + \${NSISCONF_3} !addplugindir /x86-unicode '@CMAKE_CURRENT_SOURCE_DIR@\\contrib\\NSIS\\Plugins-i386-unicode' + !else ; NSIS 2: + !addplugindir '@CMAKE_CURRENT_SOURCE_DIR@\\contrib\\NSIS\\Plugins-i386-ansi' + !endif ;~ NSIS_PACKEDVERSION + !undef NSISCONF_3 + !endif ;~ NSIS_WIN32_MAKENSIS + + ; global variables + Var KVASD_EXECUTABLE + Var CB_INSTALL_KVASD + Var INSTALL_KVASD + Var RichEditLicense + Var CheckBoxAgree + Var KVASD_LICENSE + + ; page callbacks + Function KVASD_page_create + Push $R0 + + \${If} $INSTALL_KVASD = \${BST_CHECKED} + \${AndIfNot} \${FileExists} $KVASD_LICENSE + GetTempFileName $KVASD_LICENSE +retry_eula: + NSISdl::download /TIMEOUT=30000 @PROJECT_KVASD_URL@/kvasd_eula.txt $KVASD_LICENSE + Pop $R0 + \${If} $R0 != success + MessageBox MB_RETRYCANCEL|MB_ICONQUESTION 'Download: @PROJECT_KVASD_URL@/kvasd_eula.txt$\\nFailed: $R0' IDRETRY retry_eula + StrCpy $INSTALL_KVASD \${BST_UNCHECKED} + Delete $KVASD_LICENSE + \${EndIf} + \${EndIf} + + \${If} $INSTALL_KVASD = \${BST_CHECKED} + \${AndIf} \${FileExists} $KVASD_LICENSE + !insertmacro MUI_HEADER_TEXT `$(MUI_TEXT_LICENSE_TITLE)` `Please agree the terms of this license before installing KVASD` + + ; disable install button until agreed + GetDlgItem $R0 $HWNDPARENT 1 + EnableWindow $R0 0 + + nsDialogs::Create 1018 + Pop $R0 +; \${If} $R0 == error +; Abort +; \${EndIf} + + nsDialogs::CreateControl RichEdit20A \${WS_VISIBLE}|\${WS_CHILD}|\${WS_TABSTOP}|\${WS_VSCROLL}|\${ES_MULTILINE}|\${ES_READONLY} \${__NSD_Text_EXSTYLE} 0 0 100% -24u '' + Pop $RichEditLicense + + nsRichEdit::Load $RichEditLicense $KVASD_LICENSE + + \${NSD_CreateCheckBox} 0 -20u 160u 12u `$(^AcceptBtn)` + Pop $CheckBoxAgree + \${NSD_OnClick} $CheckBoxAgree KVASD_Page_CheckBoxAgree_Click + nsDialogs::Show + \${Else} + Abort ; skip page + \${EndIf} + + Pop $R0 + FunctionEnd + + Function KVASD_page_leave + FunctionEnd + + ; field callbacks + Function KVASD_Page_CheckBoxAgree_Click + Pop $0 + + \${NSD_GetState} $CheckBoxAgree $R0 + \${If} $R0 = \${BST_CHECKED} + GetDlgItem $R0 $HWNDPARENT 1 + EnableWindow $R0 1 + \${Else} + GetDlgItem $R0 $HWNDPARENT 1 + EnableWindow $R0 0 + \${EndIf} + FunctionEnd" + ) + + set (CPACK_NSIS_EXTRA_INIT_COMMANDS " + ; initial value of $INSATLL_KVASD chack box + IntOp $INSTALL_KVASD 0 + \${BST_CHECKED}" + ) + + set (CPACK_NSIS_EXTRA_PAGES " + ; custom page for KVASD license display and acceptance + Page custom KVASD_page_create KVASD_page_leave" + ) + + set (CPACK_NSIS_EXTRA_INSTALL_OPTIONS " + ; add a chackbox for installing KVASD + \${NSD_CreateCheckBox} 0u 110u 100% 10u 'Install the optional KVASD decoder' + Pop $CB_INSTALL_KVASD + \${NSD_SetState} $CB_INSTALL_KVASD $INSTALL_KVASD" + ) + + set (CPACK_NSIS_EXTRA_INSTALL_OPTIONS_READ " + \${NSD_GetState} $CB_INSTALL_KVASD $INSTALL_KVASD" + ) + + set (CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS " + \${If} $INSTALL_KVASD = \${BST_CHECKED} + ; + ; fetch KVASD license + ; + StrCpy $5 @PROJECT_KVASD_URL@/@SYSTEM_NAME@/kvasd@CMAKE_EXECUTABLE_SUFFIX@ + GetTempFileName $1 +retry: + NSISdl::download /TIMEOUT=30000 $5.md5 $1 + Pop $R0 + \${If} $R0 != success + MessageBox MB_RETRYCANCEL|MB_ICONQUESTION 'Download: $5.md5$\\nFailed: $R0' IDRETRY retry + Abort + \${EndIf} + ClearErrors + FileOpen $2 $1 r + \${If} \${Errors} + MessageBox MB_RETRYCANCEL|MB_ICONQUESTION 'Failed to read MD5 hash file: $5.md5' IDRETRY retry + Abort + \${EndIf} + + ; extract MD5 hash + FileRead $2 $3 32 + FileClose $2 + + ; + ; fetch kvasd executable + ; + GetTempFileName $KVASD_EXECUTABLE + NSISdl::download /TIMEOUT=30000 $5 $KVASD_EXECUTABLE + Pop $R0 + \${If} $R0 != success + MessageBox MB_RETRYCANCEL|MB_ICONQUESTION 'Download: $5$\\nFailed: $R0' IDRETRY retry + Abort + \${EndIf} + + ; calculate MD5 hash + Crypto::HashFile 'MD5' $KVASD_EXECUTABLE + Pop $0 + + \${If} $3 != $0 + MessageBox MB_RETRYCANCEL|MB_ICONQUESTION 'MD5 hash check failed on: $5$\\nExpected: [$4]$\\n Actual: [$0]' IDRETRY retry + Abort + \${EndIf} + +skip_kvasd: + Delete $1 ; MD5 hash file + \${EndIf} + + ; save $INSTALL_KVASD to registry for use in teh un-installer + WriteRegDWORD SHCTX 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${CPACK_PACKAGE_INSTALL_REGISTRY_KEY}' \\ + 'InstallKvasd' $INSTALL_KVASD" + ) + + set (CPACK_NSIS_EXTRA_INSTALL_COMMANDS " + ; install the kvasd executable + \${If} $INSTALL_KVASD = \${BST_CHECKED} + \${AndIf} \${FileExists} $KVASD_EXECUTABLE + DetailPrint 'Installing: $INSTDIR\\@WSJT_BIN_DESTINATION@\\kvasd@CMAKE_EXECUTABLE_SUFFIX@' + Rename $KVASD_EXECUTABLE '$INSTDIR\\@WSJT_BIN_DESTINATION@\\kvasd@CMAKE_EXECUTABLE_SUFFIX@' + \${EndIf}" + ) + + set (CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS " + ; fetch $INSTALL_KVASD from registry + ReadRegDWORD $INSTALL_KVASD SHCTX \\ + 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${CPACK_PACKAGE_INSTALL_REGISTRY_KEY}' 'InstallKvasd' + + ; conditionally un-install the kvasd executable + \${If} $INSTALL_KVASD = \${BST_CHECKED} + Delete '$INSTDIR\\@WSJT_BIN_DESTINATION@\\kvasd@CMAKE_EXECUTABLE_SUFFIX@' + \${EndIf}" + ) endif () if ("${CPACK_GENERATOR}" STREQUAL "PackageMaker") diff --git a/CMakeLists.txt b/CMakeLists.txt index bde99ce7d..4db3cc7cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,8 +49,9 @@ set (PROJECT_DESCRIPTION "${PROJECT_SUMMARY_DESCRIPTION} standard SSB-width IF filters, switching between JT65 and JT9 modes is quick and convenient. Be sure to read the online ${PROJECT_NAME} User's Guide.") +set (PROJECT_KVASD_URL https://svn.code.sf.net/p/wsjt/wsjt/trunk/kvasd-binary) -set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake/Modules) +set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/Modules ${CMAKE_MODULE_PATH}) include (${PROJECT_SOURCE_DIR}/CMake/VersionCompute.cmake) message (STATUS "Building ${CMAKE_PROJECT_NAME}-${wsjtx_VERSION}") @@ -102,7 +103,7 @@ attach a debugger which will then receive the console output inside its console. # decide if we are bundling kvasd (non-FOSS) # CMAKE_DEPENDENT_OPTION (WSJT_INCLUDE_KVASD "Include kvasd in the package." OFF - "NOT is_debug_build;NOT WIN32" ON) + "NOT is_debug_build" ON) # @@ -666,19 +667,6 @@ elseif (CMAKE_HOST_WIN32) endif () -if (WSJT_INCLUDE_KVASD) - # - # fetch and validate kvasd - # - set (KVASD contrib/kvasd${CMAKE_EXECUTABLE_SUFFIX}) - add_custom_target (kvasd ALL - ${CMAKE_COMMAND} -D SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -D EXECUTABLE_SUFFIX=${CMAKE_EXECUTABLE_SUFFIX} -P ${CMAKE_SOURCE_DIR}/CMake/download_kvasd.cmake - COMMENT "Downloading kvasd for ${CMAKE_SYSTEM_NAME}" - VERBATIM - ) -endif (WSJT_INCLUDE_KVASD) - - # UI generation qt5_wrap_ui (wsjt_qt_GENUISRCS ${wsjt_qt_UISRCS}) qt5_wrap_ui (ConfigTest_GENUISRCS ${ConfigTest_UISRCS}) @@ -736,6 +724,24 @@ add_executable (wsjtx MACOSX_BUNDLE ) qt5_use_modules (wsjtx Widgets OpenGL Network Multimedia) +set (SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}) +if (WIN32) + set (SYSTEM_NAME "${SYSTEM_NAME}i386") +endif (WIN32) +if (WSJT_INCLUDE_KVASD) + # + # fetch and validate kvasd + # + set (KVASD_BINARY contrib/kvasd${CMAKE_EXECUTABLE_SUFFIX}) + + add_custom_target (kvasd ALL + ${CMAKE_COMMAND} -D SYSTEM_NAME=${SYSTEM_NAME} -D EXECUTABLE_SUFFIX=${CMAKE_EXECUTABLE_SUFFIX} -D URL=${PROJECT_KVASD_URL} -P ${CMAKE_SOURCE_DIR}/CMake/download_kvasd.cmake + COMMENT "Downloading kvasd for ${SYSTEM_NAME}" + VERBATIM + ) +endif (WSJT_INCLUDE_KVASD) + + if (UNIX) if (NOT WSJT_SKIP_MANPAGES) add_subdirectory (manpages) @@ -768,24 +774,19 @@ target_link_libraries (wsjtx wsjt wsjt_qt ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES} # installation # install (TARGETS wsjtx - RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} - LIBRARY DESTINATION ${WSJT_LIB_DESTINATION} - BUNDLE DESTINATION . - #COMPONENT Runtime + RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime + BUNDLE DESTINATION . COMPONENT runtime ) install (TARGETS jt9 jt65code jt9code - RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} - LIBRARY DESTINATION ${WSJT_LIB_DESTINATION} - BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} - #COMPONENT Runtime + RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime + BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime ) if (WSJT_INCLUDE_KVASD) install (PROGRAMS - ${CMAKE_BINARY_DIR}/${KVASD} - DESTINATION ${WSJT_BIN_DESTINATION} - #COMPONENT Runtime + ${CMAKE_BINARY_DIR}/${KVASD_BINARY} + DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime ) else (WSJT_INCLUDE_KVASD) if (APPLE) @@ -800,14 +801,14 @@ endif (WSJT_INCLUDE_KVASD) install (PROGRAMS ${RIGCTLD_EXE} DESTINATION ${WSJT_BIN_DESTINATION} - #COMPONENT Runtime + #COMPONENT runtime RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX} ) install (FILES ${CMAKE_BINARY_DIR}/contrib/${PROJECT_MANUAL} DESTINATION ${WSJT_SHARE_DESTINATION}/${WSJT_DOC_DESTINATION} - #COMPONENT Runtime + #COMPONENT runtime ) # @@ -818,7 +819,7 @@ if (APPLE) Darwin/ReadMe.txt Darwin/sysctl.conf DESTINATION . - #COMPONENT Runtime + #COMPONENT runtime ) endif (APPLE) @@ -862,12 +863,12 @@ if (NOT WIN32 AND NOT APPLE) install ( FILES wsjtx.desktop DESTINATION share/applications - #COMPONENT Runtime + #COMPONENT runtime ) install ( FILES icons/Unix/wsjtx_icon.png DESTINATION share/pixmaps - #COMPONENT Runtime + #COMPONENT runtime ) endif (NOT WIN32 AND NOT APPLE) @@ -901,7 +902,7 @@ if (NOT is_debug_build) \"[Paths] \") " - #COMPONENT Runtime + #COMPONENT runtime ) # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation @@ -918,7 +919,7 @@ if (NOT is_debug_build) ${QT_PLUGINS_DIR}/accessible DESTINATION ${WSJT_PLUGIN_DESTINATION} CONFIGURATIONS Release MinSizeRel - #COMPONENT Runtime + #COMPONENT runtime FILES_MATCHING PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}" PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE @@ -932,7 +933,7 @@ if (NOT is_debug_build) # ${QT_PLUGINS_DIR}/accessible # DESTINATION ${WSJT_PLUGIN_DESTINATION} # CONFIGURATIONS Debug - # #COMPONENT Runtime + # #COMPONENT runtime # FILES_MATCHING PATTERN "*_debug${CMAKE_SHARED_LIBRARY_SUFFIX}" # PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE # PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE @@ -945,7 +946,7 @@ file (APPEND \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION \"Plugins = Plugins \") " - #COMPONENT Runtime + #COMPONENT runtime ) endif (APPLE) @@ -963,7 +964,7 @@ file (APPEND \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION ${QT_PLUGINS_DIR}/accessible DESTINATION ${WSJT_PLUGIN_DESTINATION} CONFIGURATIONS Release MinSizeRel - #COMPONENT Runtime + #COMPONENT runtime FILES_MATCHING PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}" PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE @@ -976,7 +977,7 @@ file (APPEND \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION # ${QT_PLUGINS_DIR}/accessible # DESTINATION ${WSJT_PLUGIN_DESTINATION} # CONFIGURATIONS Debug - # #COMPONENT Runtime + # #COMPONENT runtime # FILES_MATCHING PATTERN "*d${CMAKE_SHARED_LIBRARY_SUFFIX}" # PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE # PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE @@ -990,7 +991,7 @@ file (APPEND \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION \"Plugins = ${_plugins_path} \") " - #COMPONENT Runtime + #COMPONENT runtime ) # set (gp_tool "objdump") # we want MinGW tool - not MSVC (See GetPrerequisites.cmake) @@ -1010,7 +1011,7 @@ file (APPEND \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION message (STATUS \"fixup_exe: \${the_exe}\") fixup_bundle (\"\${the_exe}\" \"\${QTPLUGINS}\" \"${fixup_library_dirs}\") " - #COMPONENT Runtime + #COMPONENT runtime ) endif (APPLE OR WIN32) @@ -1020,6 +1021,7 @@ endif (NOT is_debug_build) # # packaging # +set (CPACK_MONOLITHIC_INSTALL 1) set (CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") set (CPACK_PACKAGE_VERSION_MAJOR ${WSJTX_VERSION_MAJOR}) set (CPACK_PACKAGE_VERSION_MINOR ${WSJTX_VERSION_MINOR}) diff --git a/contrib/NSIS/NsRichEdit.zip b/contrib/NSIS/NsRichEdit.zip new file mode 100644 index 000000000..f028a74f9 Binary files /dev/null and b/contrib/NSIS/NsRichEdit.zip differ diff --git a/contrib/NSIS/Plugins-i386-ansi/Crypto.dll b/contrib/NSIS/Plugins-i386-ansi/Crypto.dll new file mode 100644 index 000000000..4f8d0efb1 Binary files /dev/null and b/contrib/NSIS/Plugins-i386-ansi/Crypto.dll differ diff --git a/contrib/NSIS/Plugins-i386-ansi/nsRichEdit.dll b/contrib/NSIS/Plugins-i386-ansi/nsRichEdit.dll new file mode 100644 index 000000000..e07f39576 Binary files /dev/null and b/contrib/NSIS/Plugins-i386-ansi/nsRichEdit.dll differ diff --git a/contrib/NSIS/Plugins-i386-unicode/Crypto.dll b/contrib/NSIS/Plugins-i386-unicode/Crypto.dll new file mode 100644 index 000000000..4f8d0efb1 Binary files /dev/null and b/contrib/NSIS/Plugins-i386-unicode/Crypto.dll differ diff --git a/contrib/NSIS/Plugins-i386-unicode/nsRichEdit.dll b/contrib/NSIS/Plugins-i386-unicode/nsRichEdit.dll new file mode 100644 index 000000000..b44340f96 Binary files /dev/null and b/contrib/NSIS/Plugins-i386-unicode/nsRichEdit.dll differ diff --git a/contrib/NSIS/README b/contrib/NSIS/README new file mode 100644 index 000000000..2182d813f --- /dev/null +++ b/contrib/NSIS/README @@ -0,0 +1,9 @@ +NSIS Addons +=========== + +This directory contains archives of NSIS plugins and includes that are +used in making the WSJT-X Windows installer. The plugin DLLs are also +extracted and deployed in sub-directories where they are added to the +project NSIS plugin path in the project CMakeCPackOptions.cmake.in +template which is in turn used in generating the NSIS installer script +from the CMake/Modules/NSIS.template.in template file. diff --git a/contrib/NSIS/cryptoplg12.zip b/contrib/NSIS/cryptoplg12.zip new file mode 100644 index 000000000..e4b5da7cf Binary files /dev/null and b/contrib/NSIS/cryptoplg12.zip differ