diff options
author | Araq <rumpf_a@web.de> | 2014-10-20 08:44:00 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-10-20 08:44:00 +0200 |
commit | 53a9d6f5cd199382957188cd8a1a7f0aa5035033 (patch) | |
tree | 9873032461904538e21cbff3417882d1b54ef881 /tools | |
parent | c7570dcd3e4202bd339a2ebbc09952a546c62269 (diff) | |
parent | b0179f9af5c5ed3cc63c5cd3b9d1055b742a3b79 (diff) | |
download | Nim-53a9d6f5cd199382957188cd8a1a7f0aa5035033.tar.gz |
Merge branch 'devel' into bigbreak
Conflicts: compiler/nim.ini doc/manual.txt doc/tut2.txt koch.nim lib/system/channels.nim readme.txt tools/niminst/niminst.nim tools/nimweb.nim web/download.txt web/news.txt
Diffstat (limited to 'tools')
-rw-r--r-- | tools/niminst/EnvVarUpdate.nsh | 346 | ||||
-rw-r--r-- | tools/niminst/inno.tmpl | 6 | ||||
-rw-r--r-- | tools/niminst/niminst.nim | 49 | ||||
-rw-r--r-- | tools/niminst/nsis.tmpl | 255 | ||||
-rw-r--r-- | tools/nimweb.nim | 18 |
5 files changed, 654 insertions, 20 deletions
diff --git a/tools/niminst/EnvVarUpdate.nsh b/tools/niminst/EnvVarUpdate.nsh new file mode 100644 index 000000000..4340b8f3c --- /dev/null +++ b/tools/niminst/EnvVarUpdate.nsh @@ -0,0 +1,346 @@ +/** + * EnvVarUpdate.nsh + * : Environmental Variables: append, prepend, and remove entries + * + * WARNING: If you use StrFunc.nsh header then include it before this file + * with all required definitions. This is to avoid conflicts + * + * Usage: + * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" + * + * Credits: + * Version 1.0 + * * Cal Turney (turnec2) + * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this + * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, + * WriteEnvStr, and un.DeleteEnvStr + * * Diego Pedroso (deguix) for StrTok + * * Kevin English (kenglish_hi) for StrContains + * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry + * (dandaman32) for StrReplace + * + * Version 1.1 (compatibility with StrFunc.nsh) + * * techtonik + * + * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries + * + */ + + +!ifndef ENVVARUPDATE_FUNCTION +!define ENVVARUPDATE_FUNCTION +!verbose push +!verbose 3 +!include "LogicLib.nsh" +!include "WinMessages.NSH" +!include "StrFunc.nsh" + +; ---- Fix for conflict if StrFunc.nsh is already includes in main file ----------------------- +!macro _IncludeStrFunction StrFuncName + !ifndef ${StrFuncName}_INCLUDED + ${${StrFuncName}} + !endif + !ifndef Un${StrFuncName}_INCLUDED + ${Un${StrFuncName}} + !endif + !define un.${StrFuncName} "${Un${StrFuncName}}" +!macroend + +!insertmacro _IncludeStrFunction StrTok +!insertmacro _IncludeStrFunction StrStr +!insertmacro _IncludeStrFunction StrRep + +; ---------------------------------- Macro Definitions ---------------------------------------- +!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString + Push "${EnvVarName}" + Push "${Action}" + Push "${RegLoc}" + Push "${PathString}" + Call EnvVarUpdate + Pop "${ResultVar}" +!macroend +!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' + +!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString + Push "${EnvVarName}" + Push "${Action}" + Push "${RegLoc}" + Push "${PathString}" + Call un.EnvVarUpdate + Pop "${ResultVar}" +!macroend +!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' +; ---------------------------------- Macro Definitions end------------------------------------- + +;----------------------------------- EnvVarUpdate start---------------------------------------- +!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' +!define hkcu_current_user 'HKCU "Environment"' + +!macro EnvVarUpdate UN + +Function ${UN}EnvVarUpdate + + Push $0 + Exch 4 + Exch $1 + Exch 3 + Exch $2 + Exch 2 + Exch $3 + Exch + Exch $4 + Push $5 + Push $6 + Push $7 + Push $8 + Push $9 + Push $R0 + + /* After this point: + ------------------------- + $0 = ResultVar (returned) + $1 = EnvVarName (input) + $2 = Action (input) + $3 = RegLoc (input) + $4 = PathString (input) + $5 = Orig EnvVar (read from registry) + $6 = Len of $0 (temp) + $7 = tempstr1 (temp) + $8 = Entry counter (temp) + $9 = tempstr2 (temp) + $R0 = tempChar (temp) */ + + ; Step 1: Read contents of EnvVarName from RegLoc + ; + ; Check for empty EnvVarName + ${If} $1 == "" + SetErrors + DetailPrint "ERROR: EnvVarName is blank" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Check for valid Action + ${If} $2 != "A" + ${AndIf} $2 != "P" + ${AndIf} $2 != "R" + SetErrors + DetailPrint "ERROR: Invalid Action - must be A, P, or R" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ${If} $3 == HKLM + ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5 + ${ElseIf} $3 == HKCU + ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5 + ${Else} + SetErrors + DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Check for empty PathString + ${If} $4 == "" + SetErrors + DetailPrint "ERROR: PathString is blank" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + Push $6 + Push $7 + Push $8 + StrLen $7 $4 + StrLen $6 $5 + IntOp $8 $6 + $7 + ${If} $5 == "" + ${OrIf} $8 >= ${NSIS_MAX_STRLEN} + SetErrors + DetailPrint "Current $1 length ($6) too long to modify in NSIS; set manually if needed" + Pop $8 + Pop $7 + Pop $6 + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + Pop $8 + Pop $7 + Pop $6 + + ; Make sure we've got some work to do + ${If} $5 == "" + ${AndIf} $2 == "R" + SetErrors + DetailPrint "$1 is empty - Nothing to remove" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Step 2: Scrub EnvVar + ; + StrCpy $0 $5 ; Copy the contents to $0 + ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or + ; after the last one are not removed here but instead in Step 3) + ${If} $0 != "" ; If EnvVar is not empty ... + ${Do} + ${${UN}StrStr} $7 $0 " ;" + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 " ;" ";" ; Remove '<space>;' + ${Loop} + ${Do} + ${${UN}StrStr} $7 $0 "; " + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';<space>' + ${Loop} + ${Do} + ${${UN}StrStr} $7 $0 ";;" + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 ";;" ";" + ${Loop} + + ; Remove a leading or trailing semicolon from EnvVar + StrCpy $7 $0 1 0 + ${If} $7 == ";" + StrCpy $0 $0 "" 1 ; Change ';<EnvVar>' to '<EnvVar>' + ${EndIf} + StrLen $6 $0 + IntOp $6 $6 - 1 + StrCpy $7 $0 1 $6 + ${If} $7 == ";" + StrCpy $0 $0 $6 ; Change ';<EnvVar>' to '<EnvVar>' + ${EndIf} + ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug + ${EndIf} + + /* Step 3. Remove all instances of the target path/string (even if "A" or "P") + $6 = bool flag (1 = found and removed PathString) + $7 = a string (e.g. path) delimited by semicolon(s) + $8 = entry counter starting at 0 + $9 = copy of $0 + $R0 = tempChar */ + + ${If} $5 != "" ; If EnvVar is not empty ... + StrCpy $9 $0 + StrCpy $0 "" + StrCpy $8 0 + StrCpy $6 0 + + ${Do} + ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter + + ${If} $7 == "" ; If we've run out of entries, + ${ExitDo} ; were done + ${EndIf} ; + + ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) + ${Do} + StrCpy $R0 $7 1 + ${If} $R0 != " " + ${ExitDo} + ${EndIf} + StrCpy $7 $7 "" 1 ; Remove leading space + ${Loop} + ${Do} + StrCpy $R0 $7 1 -1 + ${If} $R0 != " " + ${ExitDo} + ${EndIf} + StrCpy $7 $7 -1 ; Remove trailing space + ${Loop} + ${If} $7 == $4 ; If string matches, remove it by not appending it + StrCpy $6 1 ; Set 'found' flag + ${ElseIf} $7 != $4 ; If string does NOT match + ${AndIf} $0 == "" ; and the 1st string being added to $0, + StrCpy $0 $7 ; copy it to $0 without a prepended semicolon + ${ElseIf} $7 != $4 ; If string does NOT match + ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, + StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon + ${EndIf} ; + + IntOp $8 $8 + 1 ; Bump counter + ${Loop} ; Check for duplicates until we run out of paths + ${EndIf} + + ; Step 4: Perform the requested Action + ; + ${If} $2 != "R" ; If Append or Prepend + ${If} $6 == 1 ; And if we found the target + DetailPrint "Target is already present in $1. It will be removed and" + ${EndIf} + ${If} $0 == "" ; If EnvVar is (now) empty + StrCpy $0 $4 ; just copy PathString to EnvVar + ${If} $6 == 0 ; If found flag is either 0 + ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) + DetailPrint "$1 was empty and has been updated with the target" + ${EndIf} + ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), + StrCpy $0 $0;$4 ; append PathString + ${If} $6 == 1 + DetailPrint "appended to $1" + ${Else} + DetailPrint "Target was appended to $1" + ${EndIf} + ${Else} ; If Prepend (and EnvVar is not empty), + StrCpy $0 $4;$0 ; prepend PathString + ${If} $6 == 1 + DetailPrint "prepended to $1" + ${Else} + DetailPrint "Target was prepended to $1" + ${EndIf} + ${EndIf} + ${Else} ; If Action = Remove + ${If} $6 == 1 ; and we found the target + DetailPrint "Target was found and removed from $1" + ${Else} + DetailPrint "Target was NOT found in $1 (nothing to remove)" + ${EndIf} + ${If} $0 == "" + DetailPrint "$1 is now empty" + ${EndIf} + ${EndIf} + + ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change + ; + ClearErrors + ${If} $3 == HKLM + WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section + ${ElseIf} $3 == HKCU + WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section + ${EndIf} + + IfErrors 0 +4 + MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" + DetailPrint "Could not write updated $1 to $3" + Goto EnvVarUpdate_Restore_Vars + + ; "Export" our change + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + EnvVarUpdate_Restore_Vars: + ; + ; Restore the user's variables and return ResultVar + Pop $R0 + Pop $9 + Pop $8 + Pop $7 + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Push $0 ; Push my $0 (ResultVar) + Exch + Pop $0 ; Restore his $0 + +FunctionEnd + +!macroend ; EnvVarUpdate UN +!insertmacro EnvVarUpdate "" +!insertmacro EnvVarUpdate "un." +;----------------------------------- EnvVarUpdate end---------------------------------------- + +!verbose pop +!endif diff --git a/tools/niminst/inno.tmpl b/tools/niminst/inno.tmpl index b9d04755e..3460c22a2 100644 --- a/tools/niminst/inno.tmpl +++ b/tools/niminst/inno.tmpl @@ -44,9 +44,9 @@ Name: modifypath; Description: &Add $c.displayName to your system path (if not i [Code] function GiveMeAPath(const DefaultPathName: string): string; begin - if IsAdminLoggedOn then Result := ExpandConstant('{pf}') - else Result := ExpandConstant('{userdocs}'); - Result := Result + '\' + DefaultPathName; + if IsAdminLoggedOn then result := ExpandConstant('{pf}') + else result := ExpandConstant('{userdocs}'); + result := result + '\' + DefaultPathName; end; #if c.binPaths.len > 0: diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 614009c24..022b14209 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -31,6 +31,7 @@ type actionNone, # action not yet known actionCSource # action: create C sources actionInno, # action: create Inno Setup installer + actionNsis, # action: create NSIS installer actionScripts # action: create install and deinstall scripts actionZip, # action: create zip file actionDeb # action: prepare deb package @@ -50,10 +51,10 @@ type TConfigData = object of TObject actions: set[TAction] cat: array[TFileCategory, seq[string]] - binPaths, authors, oses, cpus: seq[string] + binPaths, authors, oses, cpus, downloads: seq[string] cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]] platforms: array[1..maxOS, array[1..maxCPU, bool]] - ccompiler, linker, innosetup: tuple[path, flags: string] + ccompiler, linker, innosetup, nsisSetup: tuple[path, flags: string] name, displayName, version, description, license, infile, outdir: string libpath: string innoSetupFlag, installScript, uninstallScript: bool @@ -75,9 +76,11 @@ proc initConfigData(c: var TConfigData) = c.authors = @[] c.oses = @[] c.cpus = @[] + c.downloads = @[] c.ccompiler = ("", "") c.linker = ("", "") c.innosetup = ("", "") + c.nsisSetup = ("", "") c.name = "" c.displayName = "" c.version = "" @@ -117,6 +120,7 @@ proc skipRoot(f: string): string = if result.len == 0: result = f include "inno.tmpl" +include "nsis.tmpl" include "buildsh.tmpl" include "buildbat.tmpl" include "install.tmpl" @@ -125,10 +129,10 @@ include "deinstall.tmpl" # ------------------------- configuration file ------------------------------- const - Version = "0.9" + Version = "1.0" Usage = "niminst - Nim Installation Generator Version " & Version & """ - (c) 2013 Andreas Rumpf + (c) 2014 Andreas Rumpf Usage: niminst [options] command[;command2...] ini-file[.ini] [compile_options] Command: @@ -136,6 +140,7 @@ Command: scripts build install and deinstall scripts zip build the ZIP file inno build the Inno Setup installer + nsis build the NSIS Setup installer deb create files for debhelper Options: -o, --output:dir set the output directory @@ -162,6 +167,7 @@ proc parseCmdLine(c: var TConfigData) = of "scripts": incl(c.actions, actionScripts) of "zip": incl(c.actions, actionZip) of "inno": incl(c.actions, actionInno) + of "nsis": incl(c.actions, actionNsis) of "deb": incl(c.actions, actionDeb) else: quit(Usage) else: @@ -190,7 +196,7 @@ proc walkDirRecursively(s: var seq[string], root: string) = case k of pcFile, pcLinkToFile: add(s, unixToNativePath(f)) of pcDir: walkDirRecursively(s, f) - of pcLinkToDir: nil + of pcLinkToDir: discard proc addFiles(s: var seq[string], patterns: seq[string]) = for p in items(patterns): @@ -288,7 +294,7 @@ proc parseIniFile(c: var TConfigData) = else: quit(errorStr(p, "expected: console or gui")) of "license": c.license = unixToNativePath(k.value) else: quit(errorStr(p, "unknown variable: " & k.key)) - of "var": nil + of "var": discard of "winbin": filesOnly(p, k.key, v, c.cat[fcWinBin]) of "config": filesOnly(p, k.key, v, c.cat[fcConfig]) of "data": filesOnly(p, k.key, v, c.cat[fcData]) @@ -304,6 +310,7 @@ proc parseIniFile(c: var TConfigData) = of "files": addFiles(c.cat[fcWindows], split(v, {';'})) of "binpath": c.binPaths = split(v, {';'}) of "innosetup": c.innoSetupFlag = yesno(p, v) + of "download": c.downloads.add(v) else: quit(errorStr(p, "unknown variable: " & k.key)) of "unix": case normalize(k.key) @@ -313,6 +320,7 @@ proc parseIniFile(c: var TConfigData) = else: quit(errorStr(p, "unknown variable: " & k.key)) of "unixbin": filesOnly(p, k.key, v, c.cat[fcUnixBin]) of "innosetup": pathFlags(p, k.key, v, c.innosetup) + of "nsis": pathFlags(p, k.key, v, c.nsisSetup) of "ccompiler": pathFlags(p, k.key, v, c.ccompiler) of "linker": pathFlags(p, k.key, v, c.linker) of "deb": @@ -479,14 +487,14 @@ proc srcdist(c: var TConfigData) = # --------------------- generate inno setup ----------------------------------- proc setupDist(c: var TConfigData) = - var scrpt = generateInnoSetup(c) - var n = "build" / "install_$#_$#.iss" % [toLower(c.name), c.version] + let scrpt = generateInnoSetup(c) + let n = "build" / "install_$#_$#.iss" % [toLower(c.name), c.version] writeFile(n, scrpt, "\13\10") when defined(windows): if c.innosetup.path.len == 0: c.innosetup.path = "iscc.exe" - var outcmd = if c.outdir.len == 0: "build" else: c.outdir - var cmd = "$# $# /O$# $#" % [quoteShell(c.innosetup.path), + let outcmd = if c.outdir.len == 0: "build" else: c.outdir + let cmd = "$# $# /O$# $#" % [quoteShell(c.innosetup.path), c.innosetup.flags, outcmd, n] echo(cmd) if execShellCmd(cmd) == 0: @@ -494,6 +502,23 @@ proc setupDist(c: var TConfigData) = else: quit("External program failed") +# --------------------- generate NSIS setup ----------------------------------- +proc setupDist2(c: var TConfigData) = + let scrpt = generateNsisSetup(c) + let n = "build" / "install_$#_$#.nsi" % [toLower(c.name), c.version] + writeFile(n, scrpt, "\13\10") + when defined(windows): + if c.nsisSetup.path.len == 0: + c.nsisSetup.path = "makensis.exe" + let outcmd = if c.outdir.len == 0: "build" else: c.outdir + let cmd = "$# $# /O$# $#" % [quoteShell(c.nsisSetup.path), + c.nsisSetup.flags, outcmd, n] + echo(cmd) + if execShellCmd(cmd) == 0: + removeFile(n) + else: + quit("External program failed") + # ------------------ generate ZIP file --------------------------------------- when haveZipLib: proc zipDist(c: var TConfigData) = @@ -509,7 +534,7 @@ when haveZipLib: addFile(z, proj / installShFile, installShFile) addFile(z, proj / deinstallShFile, deinstallShFile) for f in walkFiles(c.libpath / "lib/*.h"): - addFile(z, proj / "build" / extractFilename(f), f) + addFile(z, proj / "c_code" / extractFilename(f), f) for osA in 1..c.oses.len: for cpuA in 1..c.cpus.len: var dir = buildDir(osA, cpuA) @@ -576,6 +601,8 @@ parseCmdLine(c) parseIniFile(c) if actionInno in c.actions: setupDist(c) +if actionNsis in c.actions: + setupDist2(c) if actionCSource in c.actions: srcdist(c) if actionScripts in c.actions: diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl new file mode 100644 index 000000000..c4270081e --- /dev/null +++ b/tools/niminst/nsis.tmpl @@ -0,0 +1,255 @@ +#! stdtmpl(subsChar='?') | standard +#proc generateNsisSetup(c: TConfigData): string = +# result = "; NSIS script generated by niminst\n" & +# "; To regenerate run ``niminst nsis`` or ``koch nsis``\n" + +;-------------------------------- +; Included headers + ; Modern User Interface 2.0 Header + !include "MUI2.nsh" + + ; File Functions Header, used to get the current drive root. + !include "FileFunc.nsh" + + ; *Patched* Environment Variable Manipulation Header, used to add + ; tools to the user's PATH environment variable. + !include "EnvVarUpdate.nsh" + +;-------------------------------- +; Global variables and defines + !define PRODUCT_NAME "?c.displayName" + !define PRODUCT_VERSION "?c.version" + !define PRODUCT_PUBLISHER "?c.authors" + !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\?{c.name}.exe" + !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + !define PRODUCT_UNINST_ROOT_KEY "HKCU" + !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir" + + +;-------------------------------- +; General Setup Information + + ; Name and output file + Name "?{c.name} ?{c.version}" + OutFile "?{c.name}_?{c.version}.exe" + + ; Default installation folder + ; This is changed later (in .onInit) to the root directory, if possible. + InstallDir "$LOCALAPPDATA\?{c.name}" + + ; Get installation folder from registry if available + InstallDirRegKey HKCU "Software\c.name\c.version" "" + + ; Request user level application privileges. + RequestExecutionLevel user + + ; Allow installation to the root drive directory. + AllowRootDirInstall true + + ; Maximum compression! + SetCompressor /SOLID /FINAL lzma + + ; Installer and Uninstaller Icons + ; Icon "nimrod.ico" + ; UninstallIcon "nimrod.ico" + + ; Set installation details to be shown by default + ShowInstDetails show + ShowUnInstDetails show + +;-------------------------------- +; Interface Settings + + ; Warn the user if aborting during installation/uninstallation + !define MUI_ABORTWARNING + !define MUI_UNABORTWARNING + + ; Don't show a description for sections + !define MUI_COMPONENTSPAGE_NODESC + +;-------------------------------- +; Pages + + ; Setup the installer pages + !insertmacro MUI_PAGE_WELCOME + !insertmacro MUI_PAGE_LICENSE "?{expandFilename(c.license)}" + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + + ; Setup the start menu entry page + var ICONS_GROUP + !define MUI_STARTMENUPAGE_DEFAULTFOLDER "?{c.displayName}" + !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}" + !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" + !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}" + !insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP + + !insertmacro MUI_PAGE_INSTFILES + !insertmacro MUI_PAGE_FINISH + + ; Setup the uninstaller pages + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Installer Sections + + ; The core section. This is comprised of a base Nim installation, + ; such as what would be retrieved via git, and an already bootstrapped + ; Nim binary. + Section "Core Files" CoreSection + ; This is a mandotory section + SectionIn RO + + ; Output files to the base installation directory + SetOutPath "$INSTDIR" + + ; Only overwrite newer files + SetOverwrite ifnewer + + ; Write all the files to the output directory. + #for i in low(TFileCategory)..fcWindows: + # for f in items(c.cat[i]): + SetOutPath "$INSTDIR\?{splitFile(f).dir.toWin}" + File "?{expandFilename(f).toWin}" + # end for + #end for + + ; Write out the uninstaller + WriteUninstaller "$INSTDIR\uninstaller.exe" + SectionEnd + + Section "-Add Registry Keys" RegistrySection + ; Write application registry keys + WriteRegStr HKCU "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\?{c.name}.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\?{c.name}.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" + ; Reset the output path + SetOutPath "$INSTDIR" + SectionEnd + + ; Section for adding the shortcuts related to files and applications + Section "-Setup Shortcuts" ShortcutsSection + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + CreateDirectory "$SMPROGRAMS\$ICONS_GROUP" + + #if c.app == appConsole: + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{c.displayName}.lnk" "$INSTDIR\start.bat" + CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\start.bat" + #else: + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe" + CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe" + #end if + + ; Add shortcuts for the documentation + #for f in items(c.cat[fcDocStart]): + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{splitFile(f).name}.lnk" "$INSTDIR\?{f.toWin}" + #end for + + ; Write the shortcut to the uninstaller + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninstaller.exe" + !insertmacro MUI_STARTMENU_WRITE_END + SectionEnd + + ; Section for adding tools to the PATH variable + Section "Setup Path Environment" PathSection + ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\dist\mingw" + ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\bin" + ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\dist\babel" + SectionEnd + + ; The downloadable sections. These sections are automatically generated by + ; niminst and the template filters. + #var i = 0 + #for download in c.downloads: + # inc i + # let d = download.split('|') + # if d.len != 5 and d.len != 6: + # quit("download string needs 5..6 parts: " & download) + # end if + # let sectionName = d[0] + # let dir = d[1] + # let zipName = d[2] + # let size = d[3] + # let url = d[4] + Section /o "?sectionName" ?{i}Section + ; Add the section size to the total size. + AddSize ?size + + ; Download the file, and if successful, extract it to the given directory + ; otherwise, + retry: + NSISdl::download "?url" "$TEMP\?zipName" + Pop $0 + ${If} $0 == "success" + ZipDLL::extractall "$TEMP\?zipName" "$INSTDIR\?dir" + Delete "$TEMP\?zipName" + ${Else} + MessageBox MB_ICONSTOP|MB_ABORTRETRYIGNORE "Error: $0" IDRETRY retry IDIGNORE ignore + abort + ${EndIf} + + # if d.len >= 6: + # let startMenuEntry = d[5] + # let e = splitFile(startMenuEntry).name.capitalize + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}" + # end if + + ; Shortcuts + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + !insertmacro MUI_STARTMENU_WRITE_END + ignore: + SectionEnd + #end + +;-------------------------------- +; Section Descriptions + ; Series of strings describing each section + ; LangString DESC_CoreSection ${LANG_ENGLISH} "Core Nim files" + + ; The macros to actually insert the descriptions into the sections. + ; Each description above should have a corresponding MUI_DESCRIPTION_TEXT + ; macro linking the section to the description. + ; !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + ; !insertmacro MUI_DESCRIPTION_TEXT ${CoreSection} $(DESC_CoreSection) + ; !insertmacro MUI_FUNCTION_DESCRIPTION_END + + +;-------------------------------- +; Uninstaller Sections + + Section "Uninstall" + ; Remove previously created shortcuts + !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP + Delete "$DESKTOP\?{c.displayName}.lnk" + + ; Remove installed application files + RMDir /r "$SMPROGRAMS\$ICONS_GROUP" + RMDir /r "$INSTDIR" + + ; Remove the previously created registry key + DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" + DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}" + SetAutoClose true + + ; Remove entries from the PATH environment variable + ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\dist\mingw" + ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\bin" + ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\dist\babel" + SectionEnd + +;-------------------------------- +; Function hooks + + Function .onInit + ${GetRoot} "$EXEDIR" $R0 + strCpy $INSTDIR "$R0\?{c.name}" + FunctionEnd \ No newline at end of file diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 24ade58fc..6312dace4 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -45,9 +45,10 @@ proc initConfigData(c: var TConfigData) = c.gitCommit = "master" c.numProcessors = countProcessors() # Attempts to obtain the git current commit. - let (output, code) = execCmdEx("git log -n 1 --format=%H") - if code == 0 and output.strip.len == 40: - c.gitCommit = output.strip + when false: + let (output, code) = execCmdEx("git log -n 1 --format=%H") + if code == 0 and output.strip.len == 40: + c.gitCommit = output.strip c.quotations = initTable[string, tuple[quote, author: string]]() include "website.tmpl" @@ -285,8 +286,10 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = exec("pdflatex " & changeFileExt(d, "tex")) exec("pdflatex " & changeFileExt(d, "tex")) # delete all the crappy temporary files: - var pdf = splitFile(d).name & ".pdf" - moveFile(dest=destPath / pdf, source=pdf) + let pdf = splitFile(d).name & ".pdf" + let dest = destPath / pdf + removeFile(dest) + moveFile(dest=dest, source=pdf) removeFile(changeFileExt(pdf, "aux")) if existsFile(changeFileExt(pdf, "toc")): removeFile(changeFileExt(pdf, "toc")) @@ -428,4 +431,7 @@ var c: TConfigData initConfigData(c) parseCmdLine(c) parseIniFile(c) -main(c) +when false: + buildPdfDoc(c, "doc") +else: + main(c) |