diff options
Diffstat (limited to 'tools/niminst')
-rw-r--r-- | tools/niminst/buildbat.tmpl | 6 | ||||
-rw-r--r-- | tools/niminst/buildsh.tmpl | 6 | ||||
-rw-r--r-- | tools/niminst/debcreation.nim | 4 | ||||
-rw-r--r-- | tools/niminst/deinstall.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/install.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/makefile.tmpl | 4 | ||||
-rw-r--r-- | tools/niminst/niminst.nim | 95 | ||||
-rw-r--r-- | tools/niminst/nsis.tmpl | 219 |
8 files changed, 271 insertions, 67 deletions
diff --git a/tools/niminst/buildbat.tmpl b/tools/niminst/buildbat.tmpl index 2a8da144d..278b6caea 100644 --- a/tools/niminst/buildbat.tmpl +++ b/tools/niminst/buildbat.tmpl @@ -1,5 +1,5 @@ #? stdtmpl(subsChar='?') | standard -#proc generateBuildBatchScript(c: ConfigData, winIndex, cpuIndex: int): string = +#proc generateBuildBatchScript(c: ConfigData, winIndex, cpuIndex: int): string = # result = "@echo off\nREM Generated by niminst\n" SET CC=gcc SET LINKER=gcc @@ -23,8 +23,8 @@ CALL %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")} IF ERRORLEVEL 1 (GOTO:END) # end for -ECHO %LINKER% -o ?{"%BIN_DIR%"\toLower(c.name)}.exe ?linkCmd %LINK_FLAGS% -CALL %LINKER% -o ?{"%BIN_DIR%"\toLower(c.name)}.exe ?linkCmd %LINK_FLAGS% +ECHO %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS% +CALL %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS% # end block diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl index 13dfe5226..f82fc0fee 100644 --- a/tools/niminst/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -92,6 +92,10 @@ case $uos in ;; *haiku* ) myos="haiku" + LINK_FLAGS="$LINK_FLAGS -lroot -lnetwork" + ;; + *mingw* ) + myos="windows" ;; *) echo 2>&1 "Error: unknown operating system: $uos" @@ -143,7 +147,7 @@ case $myos in $CC $COMP_FLAGS -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")} # add(linkCmd, " \\\n" & changeFileExt(f, "o")) # end for - $LINKER -o ?{"$binDir/" & toLower(c.name)} ?linkCmd $LINK_FLAGS + $LINKER -o ?{"$binDir/" & toLowerAscii(c.name)} ?linkCmd $LINK_FLAGS ;; # end for *) diff --git a/tools/niminst/debcreation.nim b/tools/niminst/debcreation.nim index 36b2a29ec..0ecea132f 100644 --- a/tools/niminst/debcreation.nim +++ b/tools/niminst/debcreation.nim @@ -148,7 +148,7 @@ proc prepDeb*(packName, version, mtnName, mtnEmail, shortDesc, desc: string, ## binaries/config/docs/lib: files relative to nim's root, that need to ## be installed. - let pkgName = packName.toLower() + let pkgName = packName.toLowerAscii() var workingDir = getTempDir() / "niminst" / "deb" var upstreamSource = (pkgName & "-" & version) @@ -168,7 +168,7 @@ proc prepDeb*(packName, version, mtnName, mtnEmail, shortDesc, desc: string, echo("Creating necessary files in debian/") createDir(workingDir / upstreamSource / "debian") - template writeDebian(f, s: string): expr = + template writeDebian(f, s: string) = writeFile(workingDir / upstreamSource / "debian" / f, s) var controlFile = createControl(pkgName, makeMtn(mtnName, mtnEmail), diff --git a/tools/niminst/deinstall.tmpl b/tools/niminst/deinstall.tmpl index 3cdfbf45d..bba310f76 100644 --- a/tools/niminst/deinstall.tmpl +++ b/tools/niminst/deinstall.tmpl @@ -1,7 +1,7 @@ #? stdtmpl(subsChar='?') | standard #proc generateDeinstallScript(c: ConfigData): string = # result = "#! /bin/sh\n# Generated by niminst\n" -# var proj = c.name.toLower +# var proj = c.name.toLowerAscii if [ $# -eq 1 ] ; then case $1 in diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl index 3f17840a8..d72b132ef 100644 --- a/tools/niminst/install.tmpl +++ b/tools/niminst/install.tmpl @@ -1,7 +1,7 @@ #? stdtmpl(subsChar = '?') | standard #proc generateInstallScript(c: ConfigData): string = # result = "#! /bin/sh\n# Generated by niminst\n" -# var proj = c.name.toLower +# var proj = c.name.toLowerAscii ## Current directory you start script from BASE_DIR=$(pwd) diff --git a/tools/niminst/makefile.tmpl b/tools/niminst/makefile.tmpl index 5c95ccda9..ce2db1c48 100644 --- a/tools/niminst/makefile.tmpl +++ b/tools/niminst/makefile.tmpl @@ -157,7 +157,7 @@ endif %.o: %.c $(CC) $(COMP_FLAGS) -Ic_code -c $< -o $@ -?{"$(binDir)/" & toLower(c.name)}: $(oFiles) +?{"$(binDir)/" & toLowerAscii(c.name)}: $(oFiles) @mkdir -p $(binDir) $(LINKER) -o $@ $^ $(LINK_FLAGS) @echo "SUCCESS" @@ -165,4 +165,4 @@ endif .PHONY: clean clean: - rm -f $(oFiles) ?{"$(binDir)/" & toLower(c.name)} + rm -f $(oFiles) ?{"$(binDir)/" & toLowerAscii(c.name)} diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 4c8dfcddf..e0b8ad9b3 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -313,7 +313,7 @@ proc parseIniFile(c: var ConfigData) = of cfgSectionStart: section = normalize(k.section) of cfgKeyValuePair: - var v = k.value % c.vars + var v = `%`(k.value, c.vars, {useEnvironment, useEmpty}) c.vars[k.key] = v case section @@ -447,7 +447,8 @@ proc readCFiles(c: var ConfigData, osA, cpuA: int) = # HACK: we conditionally add ``-lm -ldl``, so remove them from the # linker flags: c.linker.flags = c.linker.flags.replaceWord("-lm").replaceWord( - "-ldl").strip + "-ldl").replaceWord("-lroot").replaceWord( + "-lnetwork").strip else: if cmpIgnoreStyle(k.key, "libpath") == 0: c.libpath = k.value @@ -551,7 +552,7 @@ proc srcdist(c: var ConfigData) = # --------------------- generate inno setup ----------------------------------- proc setupDist(c: var ConfigData) = let scrpt = generateInnoSetup(c) - let n = "build" / "install_$#_$#.iss" % [toLower(c.name), c.version] + let n = "build" / "install_$#_$#.iss" % [toLowerAscii(c.name), c.version] writeFile(n, scrpt, "\13\10") when defined(windows): if c.innosetup.path.len == 0: @@ -568,7 +569,7 @@ proc setupDist(c: var ConfigData) = # --------------------- generate NSIS setup ----------------------------------- proc setupDist2(c: var ConfigData) = let scrpt = generateNsisSetup(c) - let n = "build" / "install_$#_$#.nsi" % [toLower(c.name), c.version] + let n = "build" / "install_$#_$#.nsi" % [toLowerAscii(c.name), c.version] writeFile(n, scrpt, "\13\10") when defined(windows): if c.nsisSetup.path.len == 0: @@ -585,7 +586,7 @@ proc setupDist2(c: var ConfigData) = # ------------------ generate ZIP file --------------------------------------- when haveZipLib: proc zipDist(c: var ConfigData) = - var proj = toLower(c.name) & "-" & c.version + var proj = toLowerAscii(c.name) & "-" & c.version var n = "$#.zip" % proj if c.outdir.len == 0: n = "build" / n else: n = c.outdir / n @@ -616,49 +617,64 @@ when haveZipLib: else: quit("Cannot open for writing: " & n) -proc xzDist(c: var ConfigData) = - let proj = toLower(c.name) & "-" & c.version - var n = "$#.tar.xz" % proj +proc xzDist(c: var ConfigData; windowsZip=false) = + let proj = toLowerAscii(c.name) & "-" & c.version let tmpDir = if c.outdir.len == 0: "build" else: c.outdir - template processFile(z, dest, src) = - let s = src - let d = dest - echo "Copying ", s, " to ", tmpDir / d - let destdir = tmpdir / d.splitFile.dir - if not dirExists(destdir): createDir(destdir) - copyFileWithPermissions(s, tmpDir / d) - - processFile(z, proj / buildBatFile32, "build" / buildBatFile32) - processFile(z, proj / buildBatFile64, "build" / buildBatFile64) - processFile(z, proj / buildShFile, "build" / buildShFile) - processFile(z, proj / makeFile, "build" / makeFile) - processFile(z, proj / installShFile, installShFile) - processFile(z, proj / deinstallShFile, deinstallShFile) - for f in walkFiles(c.libpath / "lib/*.h"): - processFile(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) - for k, f in walkDir("build" / dir): - if k == pcFile: processFile(z, proj / dir / extractFilename(f), f) + proc processFile(destFile, src: string) = + let dest = tmpDir / destFile + echo "Copying ", src, " to ", dest + if not existsFile(src): + echo "[Warning] Source file doesn't exist: ", src + let destDir = dest.splitFile.dir + if not dirExists(destDir): createDir(destDir) + copyFileWithPermissions(src, dest) + + if not windowsZip and not existsFile("build" / buildBatFile32): + quit("No C sources found in ./build/, please build by running " & + "./koch csource -d:release.") + + if not windowsZip: + processFile(proj / buildBatFile32, "build" / buildBatFile32) + processFile(proj / buildBatFile64, "build" / buildBatFile64) + processFile(proj / buildShFile, "build" / buildShFile) + processFile(proj / makeFile, "build" / makeFile) + processFile(proj / installShFile, installShFile) + processFile(proj / deinstallShFile, deinstallShFile) + for f in walkFiles(c.libpath / "lib/*.h"): + processFile(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) + for k, f in walkDir("build" / dir): + if k == pcFile: processFile(proj / dir / extractFilename(f), f) + else: + for f in items(c.cat[fcWinBin]): + let filename = f.extractFilename + processFile(proj / "bin" / filename, f) - for cat in items({fcConfig..fcOther, fcUnix, fcNimble}): + let osSpecific = if windowsZip: fcWindows else: fcUnix + for cat in items({fcConfig..fcOther, osSpecific, fcNimble}): echo("Current category: ", cat) - for f in items(c.cat[cat]): processFile(z, proj / f, f) + for f in items(c.cat[cat]): processFile(proj / f, f) # Copy the .nimble file over let nimbleFile = c.nimblePkgName & ".nimble" - processFile(z, proj / nimbleFile, nimbleFile) + processFile(proj / nimbleFile, nimbleFile) when true: let oldDir = getCurrentDir() setCurrentDir(tmpDir) try: - if execShellCmd("XZ_OPT=-9 gtar Jcf $1.tar.xz $1 --exclude=.DS_Store" % proj) != 0: - # try old 'tar' without --exclude feature: - if execShellCmd("XZ_OPT=-9 tar Jcf $1.tar.xz $1" % proj) != 0: + if windowsZip: + if execShellCmd("7z a -tzip $1.zip $1" % proj) != 0: echo("External program failed") + else: + if execShellCmd("XZ_OPT=-9 gtar Jcf $1.tar.xz $1 --exclude=.DS_Store" % + proj) != 0: + # try old 'tar' without --exclude feature: + if execShellCmd("XZ_OPT=-9 tar Jcf $1.tar.xz $1" % proj) != 0: + echo("External program failed") finally: setCurrentDir(oldDir) @@ -676,11 +692,11 @@ proc debDist(c: var ConfigData) = echo("Copying source to tmp/niminst/deb/") var currentSource = getCurrentDir() var workingDir = getTempDir() / "niminst" / "deb" - var upstreamSource = (c.name.toLower() & "-" & c.version) + var upstreamSource = (c.name.toLowerAscii() & "-" & c.version) createDir(workingDir / upstreamSource) - template copyNimDist(f, dest: string): stmt = + template copyNimDist(f, dest: string) = createDir((workingDir / upstreamSource / dest).splitFile.dir) copyFile(currentSource / f, workingDir / upstreamSource / dest) @@ -724,10 +740,7 @@ if actionCSource in c.actions: if actionScripts in c.actions: writeInstallScripts(c) if actionZip in c.actions: - when haveZipLib: - zipDist(c) - else: - quit("libzip is not installed") + xzDist(c, true) if actionXz in c.actions: xzDist(c) if actionDeb in c.actions: diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl index 0897d36a8..95d4652e3 100644 --- a/tools/niminst/nsis.tmpl +++ b/tools/niminst/nsis.tmpl @@ -11,10 +11,6 @@ ; 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" @@ -35,7 +31,7 @@ ; Default installation folder ; This is changed later (in .onInit) to the root directory, if possible. - InstallDir "$PROGRAMFILES?{when sizeof(int) == 8: "64" else: ""}\?{c.name}-?{c.version}" + InstallDir "$PROGRAMFILES?{when sizeof(int) == 8: "64" else: ""}\?{c.name}-?{c.version}\" ; Get installation folder from registry if available InstallDirRegKey HKCU "Software\c.name\c.version" "" @@ -44,7 +40,7 @@ RequestExecutionLevel user ; Allow installation to the root drive directory. - AllowRootDirInstall true + AllowRootDirInstall false ; Maximum compression! SetCompressor /SOLID /FINAL lzma @@ -156,10 +152,14 @@ ; 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\dist\mingw\bin" - ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\bin" - ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\dist\babel" + Push "$INSTDIR\bin" + Call AddToPath + Push "$INSTDIR\dist\mingw" + Call AddToPath + Push "$INSTDIR\dist\mingw\bin" + Call AddToPath + Push "$PROFILE\.nimble\bin" + Call AddToPath SectionEnd ; The downloadable sections. These sections are automatically generated by @@ -202,7 +202,7 @@ ; Shortcuts # if d.len >= 6: # let startMenuEntry = d[5] - # let e = splitFile(startMenuEntry).name.capitalize + # let e = splitFile(startMenuEntry).name.capitalizeAscii !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}" !insertmacro MUI_STARTMENU_WRITE_END @@ -243,10 +243,14 @@ 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\dist\mingw\bin" - ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\bin" - ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\dist\babel" + Push "$INSTDIR\bin" + Call un.RemoveFromPath + Push "$INSTDIR\dist\mingw" + Call un.RemoveFromPath + Push "$INSTDIR\dist\mingw\bin" + Call un.RemoveFromPath + Push "$PROFILE\.nimble\bin" + Call un.RemoveFromPath SectionEnd ;-------------------------------- @@ -254,5 +258,188 @@ Function .onInit ${GetRoot} "$EXEDIR" $R0 - strCpy $INSTDIR "$R0\?{c.name}" + ;strCpy $INSTDIR "$R0\?{c.name}" FunctionEnd + + +;-------------------------------------------------------------------- +; Path functions +; +; Based on example from: +; http://nsis.sourceforge.net/Path_Manipulation +; +; Actually based on: +; https://www.smartmontools.org/browser/trunk/smartmontools/os_win32/installer.nsi#L636 + + +!include "WinMessages.nsh" + +; Registry Entry for environment (NT4,2000,XP) +; All users: +;!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' +; Current user only: +!define Environ 'HKCU "Environment"' + + +; AddToPath - Appends dir to PATH +; (does not work on Win9x/ME) +; +; Usage: +; Push "dir" +; Call AddToPath + +Function AddToPath + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + + ; NSIS ReadRegStr returns empty string on string overflow + ; Native calls are used here to check actual length of PATH + + ; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3) + System::Call "advapi32::RegOpenKey(i 0x80000001, t'Environment', *i.r3) i.r4" + IntCmp $4 0 0 done done + ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2)) + ; RegCloseKey($3) + System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4" + System::Call "advapi32::RegCloseKey(i $3)" + + IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA + DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}" + MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" + Goto done + + IntCmp $4 0 +5 ; $4 != NO_ERROR + IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND + DetailPrint "AddToPath: unexpected error code $4" + Goto done + StrCpy $1 "" + + ; Check if already in PATH + Push "$1;" + Push "$0;" + Call StrStr + Pop $2 + StrCmp $2 "" 0 done + Push "$1;" + Push "$0\;" + Call StrStr + Pop $2 + StrCmp $2 "" 0 done + + ; Prevent NSIS string overflow + StrLen $2 $0 + StrLen $3 $1 + IntOp $2 $2 + $3 + IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";") + IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0 + DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}" + MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}." + Goto done + + ; Append dir to PATH + DetailPrint "Add to PATH: $0" + StrCpy $2 $1 1 -1 + StrCmp $2 ";" 0 +2 + StrCpy $1 $1 -1 ; remove trailing ';' + StrCmp $1 "" +2 ; no leading ';' + StrCpy $0 "$1;$0" + WriteRegExpandStr ${Environ} "PATH" $0 + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + +done: + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + + +; RemoveFromPath - Removes dir from PATH +; +; Usage: +; Push "dir" +; Call RemoveFromPath + +Function un.RemoveFromPath + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + + ReadRegStr $1 ${Environ} "PATH" + StrCpy $5 $1 1 -1 + StrCmp $5 ";" +2 + StrCpy $1 "$1;" ; ensure trailing ';' + Push $1 + Push "$0;" + Call un.StrStr + Pop $2 ; pos of our dir + StrCmp $2 "" done + + DetailPrint "Remove from PATH: $0" + 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 + StrCmp $5 ";" 0 +2 + StrCpy $3 $3 -1 ; remove trailing ';' + WriteRegExpandStr ${Environ} "PATH" $3 + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + +done: + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + + +; StrStr - find substring in a string +; +; Usage: +; Push "this is some string" +; Push "some" +; Call StrStr +; Pop $0 ; "some string" + +!macro StrStr un +Function ${un}StrStr + Exch $R1 ; $R1=substring, stack=[old$R1,string,...] + Exch ; stack=[string,old$R1,...] + Exch $R2 ; $R2=string, stack=[old$R2,old$R1,...] + Push $R3 + Push $R4 + Push $R5 + StrLen $R3 $R1 + StrCpy $R4 0 + ; $R1=substring, $R2=string, $R3=strlen(substring) + ; $R4=count, $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 ; $R1=old$R1, stack=[result,...] +FunctionEnd +!macroend +!insertmacro StrStr "" +!insertmacro StrStr "un." |