From fe57a7e582aea2a92e12d9b34cdec678f11edd6f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Jan 2012 16:02:53 -0800 Subject: [PATCH] Add Inno Setup installer script rather than NSIS --- LICENSE.txt | 11 ++ Makefile.in | 2 +- configure | 2 +- mk/dist.mk | 32 +++--- src/etc/pkg/modpath.iss | 219 ++++++++++++++++++++++++++++++++++++++ src/etc/pkg/rust-logo.ico | Bin 0 -> 94339 bytes src/etc/pkg/rust.iss | 50 +++++++++ 7 files changed, 300 insertions(+), 16 deletions(-) create mode 100644 src/etc/pkg/modpath.iss create mode 100644 src/etc/pkg/rust-logo.ico create mode 100644 src/etc/pkg/rust.iss diff --git a/LICENSE.txt b/LICENSE.txt index 826bcd17c124..102d019dbe3d 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -186,6 +186,17 @@ included: USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* The auxiliary file src/etc/pkg/modpath.iss contains a + library routine compiled, by Inno Setup, into the Windows + installer binary. This file is licensed under the LGPL, + but, in our legal interpretation, this does not affect the + aggregate "collected work" license of the Rust + distribution (MIT) nor any other components of it. We + believe that the terms governing distribution of the + binary Windows installer built from modpath.iss are + therefore LGPL, but not the terms governing distribution + of any of the files installed by such an installer (such + as the Rust compiler or runtime libraries themselves). * The libuv asynchronous I/O library. Code for this package is found in the src/rt/libuv directory, within this diff --git a/Makefile.in b/Makefile.in index e7d5650a881d..6f77629bbf3c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -114,7 +114,7 @@ LIBRUSTC_GLOB :=$(call CFG_LIB_GLOB,rustc) # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git -CFG_RELEASE = 0.2pre +CFG_RELEASE = 0.1.1 CFG_VERSION = $(CFG_RELEASE) ifneq ($(wildcard $(CFG_GIT)),) diff --git a/configure b/configure index 5d94b854ea28..a9bf251223af 100755 --- a/configure +++ b/configure @@ -289,7 +289,7 @@ probe CFG_GCC gcc probe CFG_LLVM_CONFIG llvm-config probe CFG_VALGRIND valgrind probe CFG_PERF perf -probe CFG_MAKENSIS makensis +probe CFG_ISCC iscc probe CFG_NATURALDOCS NaturalDocs naturaldocs probe CFG_LLNEXTGEN LLnextgen probe CFG_PANDOC pandoc diff --git a/mk/dist.mk b/mk/dist.mk index 82ba2a82a680..339e3efebd05 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -6,8 +6,9 @@ PKG_NAME := rust PKG_DIR = $(PKG_NAME)-$(CFG_RELEASE) PKG_TAR = $(PKG_DIR).tar.gz -ifdef CFG_MAKENSIS -PKG_NSI = $(S)src/etc/pkg/rust.nsi +ifdef CFG_ISCC +PKG_ISS = $(wildcard $(S)src/etc/pkg/*.iss) +PKG_ICO = $(S)src/etc/pkg/rust-logo.ico PKG_EXE = $(PKG_DIR)-install.exe endif @@ -38,18 +39,23 @@ PKG_FILES := \ UNROOTED_PKG_FILES := $(patsubst $(S)%,./%,$(PKG_FILES)) -lic.txt: $(S)LICENSE.txt - @$(call E, crlf: $@) - @$(Q)perl -pe 's@\r\n|\n@\r\n@go' <$< >$@ +ifdef CFG_ISCC +LICENSE.txt: $(S)LICENSE.txt + cp $< $@ -ifdef CFG_MAKENSIS -$(PKG_EXE): $(PKG_NSI) $(PKG_FILES) all rustc-stage3 lic.txt - @$(call E, makensis: $@) - $(Q)"$(CFG_MAKENSIS)" -NOCD -V1 "-XOutFile $@" \ - "-XLicenseData lic.txt" $< - $(Q)rm -f lic.txt +%.iss: $(S)src/etc/pkg/%.iss + cp $< $@ + +%.ico: $(S)src/etc/pkg/%.ico + cp $< $@ + +$(PKG_EXE): rust.iss modpath.iss LICENSE.txt rust-logo.ico \ + $(PKG_FILES) all rustc-stage3 + @$(call E, ISCC: $@) + $(Q)"$(CFG_ISCC)" $< endif + $(PKG_TAR): $(PKG_FILES) @$(call E, making dist dir) $(Q)rm -Rf dist @@ -68,7 +74,7 @@ $(PKG_TAR): $(PKG_FILES) $(Q)tar -czf $(PKG_TAR) -C dist $(PKG_DIR) $(Q)rm -Rf dist -.PHONY: dist nsis-dist distcheck +.PHONY: dist distcheck ifdef CFG_WINDOWSY @@ -84,8 +90,6 @@ else dist: $(PKG_TAR) -nsis-dist: $(PKG_EXE) - distcheck: $(PKG_TAR) $(Q)rm -Rf dist $(Q)mkdir -p dist diff --git a/src/etc/pkg/modpath.iss b/src/etc/pkg/modpath.iss new file mode 100644 index 000000000000..c0b4475ad05e --- /dev/null +++ b/src/etc/pkg/modpath.iss @@ -0,0 +1,219 @@ +// ---------------------------------------------------------------------------- +// +// Inno Setup Ver: 5.4.2 +// Script Version: 1.4.1 +// Author: Jared Breland +// Homepage: http://www.legroom.net/software +// License: GNU Lesser General Public License (LGPL), version 3 +// http://www.gnu.org/licenses/lgpl.html +// +// Script Function: +// Allow modification of environmental path directly from Inno Setup installers +// +// Instructions: +// Copy modpath.iss to the same directory as your setup script +// +// Add this statement to your [Setup] section +// ChangesEnvironment=true +// +// Add this statement to your [Tasks] section +// You can change the Description or Flags +// You can change the Name, but it must match the ModPathName setting below +// Name: modifypath; Description: &Add application directory to your environmental path; Flags: unchecked +// +// Add the following to the end of your [Code] section +// ModPathName defines the name of the task defined above +// ModPathType defines whether the 'user' or 'system' path will be modified; +// this will default to user if anything other than system is set +// setArrayLength must specify the total number of dirs to be added +// Result[0] contains first directory, Result[1] contains second, etc. +// const +// ModPathName = 'modifypath'; +// ModPathType = 'user'; +// +// function ModPathDir(): TArrayOfString; +// begin +// setArrayLength(Result, 1); +// Result[0] := ExpandConstant('{app}'); +// end; +// #include "modpath.iss" +// ---------------------------------------------------------------------------- + +procedure ModPath(); +var + oldpath: String; + newpath: String; + updatepath: Boolean; + pathArr: TArrayOfString; + aExecFile: String; + aExecArr: TArrayOfString; + i, d: Integer; + pathdir: TArrayOfString; + regroot: Integer; + regpath: String; + +begin + // Get constants from main script and adjust behavior accordingly + // ModPathType MUST be 'system' or 'user'; force 'user' if invalid + if ModPathType = 'system' then begin + regroot := HKEY_LOCAL_MACHINE; + regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; + end else begin + regroot := HKEY_CURRENT_USER; + regpath := 'Environment'; + end; + + // Get array of new directories and act on each individually + pathdir := ModPathDir(); + for d := 0 to GetArrayLength(pathdir)-1 do begin + updatepath := true; + + // Modify WinNT path + if UsingWinNT() = true then begin + + // Get current path, split into an array + RegQueryStringValue(regroot, regpath, 'Path', oldpath); + oldpath := oldpath + ';'; + i := 0; + + while (Pos(';', oldpath) > 0) do begin + SetArrayLength(pathArr, i+1); + pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); + oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); + i := i + 1; + + // Check if current directory matches app dir + if pathdir[d] = pathArr[i-1] then begin + // if uninstalling, remove dir from path + if IsUninstaller() = true then begin + continue; + // if installing, flag that dir already exists in path + end else begin + updatepath := false; + end; + end; + + // Add current directory to new path + if i = 1 then begin + newpath := pathArr[i-1]; + end else begin + newpath := newpath + ';' + pathArr[i-1]; + end; + end; + + // Append app dir to path if not already included + if (IsUninstaller() = false) AND (updatepath = true) then + newpath := newpath + ';' + pathdir[d]; + + // Write new path + RegWriteStringValue(regroot, regpath, 'Path', newpath); + + // Modify Win9x path + end else begin + + // Convert to shortened dirname + pathdir[d] := GetShortName(pathdir[d]); + + // If autoexec.bat exists, check if app dir already exists in path + aExecFile := 'C:\AUTOEXEC.BAT'; + if FileExists(aExecFile) then begin + LoadStringsFromFile(aExecFile, aExecArr); + for i := 0 to GetArrayLength(aExecArr)-1 do begin + if IsUninstaller() = false then begin + // If app dir already exists while installing, skip add + if (Pos(pathdir[d], aExecArr[i]) > 0) then + updatepath := false; + break; + end else begin + // If app dir exists and = what we originally set, then delete at uninstall + if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then + aExecArr[i] := ''; + end; + end; + end; + + // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path + if (IsUninstaller() = false) AND (updatepath = true) then begin + SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); + + // If uninstalling, write the full autoexec out + end else begin + SaveStringsToFile(aExecFile, aExecArr, False); + end; + end; + end; +end; + +// Split a string into an array using passed delimeter +procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String); +var + i: Integer; +begin + i := 0; + repeat + SetArrayLength(Dest, i+1); + if Pos(Separator,Text) > 0 then begin + Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1); + Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text)); + i := i + 1; + end else begin + Dest[i] := Text; + Text := ''; + end; + until Length(Text)=0; +end; + + +procedure CurStepChanged(CurStep: TSetupStep); +var + taskname: String; +begin + taskname := ModPathName; + if CurStep = ssPostInstall then + if IsTaskSelected(taskname) then + ModPath(); +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +var + aSelectedTasks: TArrayOfString; + i: Integer; + taskname: String; + regpath: String; + regstring: String; + appid: String; +begin + // only run during actual uninstall + if CurUninstallStep = usUninstall then begin + // get list of selected tasks saved in registry at install time + appid := '{#emit SetupSetting("AppId")}'; + if appid = '' then appid := '{#emit SetupSetting("AppName")}'; + regpath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+appid+'_is1'); + RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring); + if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring); + + // check each task; if matches modpath taskname, trigger patch removal + if regstring <> '' then begin + taskname := ModPathName; + Explode(aSelectedTasks, regstring, ','); + if GetArrayLength(aSelectedTasks) > 0 then begin + for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin + if comparetext(aSelectedTasks[i], taskname) = 0 then + ModPath(); + end; + end; + end; + end; +end; + +function NeedRestart(): Boolean; +var + taskname: String; +begin + taskname := ModPathName; + if IsTaskSelected(taskname) and not UsingWinNT() then begin + Result := True; + end else begin + Result := False; + end; +end; diff --git a/src/etc/pkg/rust-logo.ico b/src/etc/pkg/rust-logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..4749b398c2d2c063219f8e5b5c99bf1547ec0d99 GIT binary patch literal 94339 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