[m-rev.] for review: windows installer generator fixes

Ian MacLarty maclarty at cs.mu.OZ.AU
Wed Jan 4 03:48:25 AEDT 2006


Estimated hours taken: 10
Branches: main

Fix problems with the Windows installer generator.
The GUID's are now all pregenerated, which makes the generator a lot faster
(previously an external program needed to be called to generate each GUID).

Fix a problem with calling MinGW GCC from its installed location in
"Program Files/Mercury ...".  MinGW is configured to be installed in
c:\MinGW, so the Mercury compiler must pass extra arguments to gcc to
get it to find cc1 and the standard header files and libraries.

Allow installed shortcuts to be visible to all users.

extras/windows_installer_generator/wix.m:
extras/windows_installer_generator/wix_files.m:
	Read the GUIDs from a file instead of generating them on demand.

extras/windows_installer_generator/wix_gui.m:
	Allow more space for text in the welcome and finish steps.

extras/windows_installer_generator/wix_installer.m:
	Allow installed shortcuts to be visible to all users.

extras/windows_installer_generator/sample/Mercury.config:
	Add a customised version of Mercury.config for the WIndows installer.

extras/windows_installer_generator/sample/README:
extras/windows_installer_generator/sample/gen_merc_msi:
	Add a script to generate an .msi installer and mention it in the
	README.

extras/windows_installer_generator/sample/gen_merc_wxs.m:
	Set MERCURY_CONFIG_DIR on installation so that mercury_compile.exe
	(which we rename to mmc.exe) can find Mercury.config.
	Improve the messages in the installer wizard.

extras/windows_installer_generator/sample/mdb.c:
	Add a C version of mdb for the Windows installer.

extras/windows_installer_generator/sample/mdbrc:
	This file is used to generate a version of mdbrc that includes
	the stuff from mdb_doc, so that mdbrc doesn't need to know where
	mdb_doc is.
	
extras/windows_installer_generator/sample/images/banner.bmp:
extras/windows_installer_generator/sample/images/bg.bmp:
	Update installer images.

Index: wix.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/wix.m,v
retrieving revision 1.1
diff -u -r1.1 wix.m
--- wix.m	26 Oct 2005 05:04:15 -0000	1.1
+++ wix.m	2 Jan 2006 20:41:19 -0000
@@ -14,6 +14,7 @@
 
 :- interface.
 
+:- import_module bool.
 :- import_module int.
 :- import_module io.
 :- import_module list.
@@ -21,7 +22,7 @@
 
 :- import_module wix_gui.
 
-    % generate_installer(Installer, GUIDGenCommand, FileName, Result, !IO).
+    % generate_installer(Installer, GUIDFile, FileName, Result, !IO).
     %
     % Generate a Wix source file which can then be compiled into a
     % Windows installer (.msi) file.
@@ -30,11 +31,11 @@
     % By convention Wix source files have the suffix `.wxs'.
     % The Installer argument contains all the information necessary to 
     % generate the installer (see the installer type below).
-    % GUIDGenCommand is a command to execute to generate a GUID.
+    % GUIDFile is a file of GUIDs (one per line).  
     % A GUID is a unique identifier that Windows uses to keep track of
-    % each installed component.  A seperate GUID is generated for 
-    % each file installed.  `uuidgen.exe' is an example of a GUID generator
-    % and is available for both Windows and Linux.
+    % each installed component.  
+    % There should be at least as many GUIDs in the file as there are files in
+    % the product the installer is for.
     %
     % To compile the generated .wxs file into a windows installer first
     % download the Wix toolset from wix.sourceforge.net and then run:
@@ -94,6 +95,9 @@
                     % type below).
                 wix_shortcut_func           :: shortcut_function(L),
 
+                    % If yes then the shortcuts will be visible to all users.
+                wix_all_users               :: bool,
+
                     % A token representing the text to display in the
                     % title bar of the installer GUI.
                 wix_title                   :: L,
@@ -542,35 +546,42 @@
 :- import_module std_util.
 :- import_module term_to_xml.
 
-generate_installer(Installer, GUIDGenCmd, FileName, Result, !IO) :-
-    io.open_output(FileName, OpenResult, !IO),
+generate_installer(Installer, GUIDFile, FileName, Result, !IO) :-
+    io.open_output(FileName, OpenOutputResult, !IO),
     (
-        OpenResult = ok(OutStream),
-        %
-        % We know that, operationally, for a given input,
-        % gen_annotated_installer will either always throw an exception
-        % or always succeed.
-        %
-        promise_equivalent_solutions [TryResult, !:IO] (
-            try_io(
-                wix_installer.gen_annotated_installer(Installer, GUIDGenCmd), 
-                TryResult, 
-                !IO)
-        ),
+        OpenOutputResult = ok(OutStream),
+        io.open_input(GUIDFile, OpenInputResult, !IO),
         (
-            TryResult = succeeded(AnnInstaller),
-            write_xml_doc(OutStream, AnnInstaller, !IO),
-            Result = ok
-        ;
-            TryResult = exception(Univ),
-            ( if univ_to_type(Univ, WixError) then
-                Result = wix_error(WixError)
-            else
-                throw(Univ)
+            OpenInputResult = ok(GUIDStream),
+            %
+            % We know that, operationally, for a given input,
+            % gen_annotated_installer will either always throw an exception
+            % or always succeed.
+            %
+            promise_equivalent_solutions [TryResult, !:IO] (
+                try_io(
+                    wix_installer.gen_annotated_installer(Installer, GUIDStream), 
+                    TryResult, 
+                    !IO)
+            ),
+            (
+                TryResult = succeeded(AnnInstaller),
+                write_xml_doc(OutStream, AnnInstaller, !IO),
+                Result = ok
+            ;
+                TryResult = exception(Univ),
+                ( if univ_to_type(Univ, WixError) then
+                    Result = wix_error(WixError)
+                else
+                    throw(Univ)
+                )
             )
+        ;
+            OpenInputResult = error(IOError),
+            Result = wix_error(io_error(IOError))
         )
     ;
-        OpenResult = error(IOError),
+        OpenOutputResult = error(IOError),
         Result = wix_error(io_error(IOError))
     ).
 
Index: wix_files.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/wix_files.m,v
retrieving revision 1.1
diff -u -r1.1 wix_files.m
--- wix_files.m	26 Oct 2005 05:04:16 -0000	1.1
+++ wix_files.m	2 Jan 2006 20:41:19 -0000
@@ -55,7 +55,7 @@
     %
 :- pred annotate_files(language::in, list(file(L))::in, 
     id_supply::in, id_supply::out, 
-    string::in, string::in, list(annotated_file)::out, 
+    io.input_stream::in, string::in, list(annotated_file)::out, 
     io::di, io::uo) is det <= language_independent_tokens(L).
 
 :- pred gen_files(string::in, shortcut_function(L)::in,
@@ -73,7 +73,7 @@
     %
 :- pred is_shortcut_from_programs_menu(list(annotated_file)::in) is semidet.
 
-:- pred gen_guid(string::in, guid::out, io::di, io::uo) is det.
+:- pred gen_guid(io.input_stream::in, guid::out, io::di, io::uo) is det.
 
 %----------------------------------------------------------------------------%
 
@@ -136,15 +136,15 @@
     ).
 
 :- pred annotate_file(language::in, file(L)::in, id_supply::in, id_supply::out,
-    string::in, string::in, annotated_file::out, 
+    io.input_stream::in, string::in, annotated_file::out, 
     io::di, io::uo) is det <= language_independent_tokens(L).
 
-annotate_file(Language, file(Name, ShortCuts), !IdSupply, GUIDGenCmd, Path, 
+annotate_file(Language, file(Name, ShortCuts), !IdSupply, GUIDFile, Path, 
         AnnotatedFile, !IO) :-
     allocate_id(ComponentId, !IdSupply),
     allocate_id(FileId, !IdSupply),
     annotate_shortcuts(Language, ShortCuts, AnnShortCuts, !IdSupply),
-    gen_guid(GUIDGenCmd, GUID, !IO),
+    gen_guid(GUIDFile, GUID, !IO),
     AnnotatedFile = annotated_file(ComponentId, GUID, 
         FileId, Name, Path, AnnShortCuts).
 annotate_file(Language, directory(Name, Files), !IdStore, GUIDGenCmd, Path0,
@@ -156,11 +156,11 @@
     AnnotatedDir = annotated_directory(DirId, Name, AnnotatedFiles).
 
 annotate_files(_, [], !IdStore, _, _, [], !IO).
-annotate_files(Language, [File | Files], !IdStore, GUIDGenCmd, Path, 
+annotate_files(Language, [File | Files], !IdStore, GUIDStream, Path, 
         [AnnFile | AnnFiles], !IO) :-
-    annotate_file(Language, File, !IdStore, GUIDGenCmd, Path, AnnFile,
+    annotate_file(Language, File, !IdStore, GUIDStream, Path, AnnFile,
         !IO),
-    annotate_files(Language, Files, !IdStore, GUIDGenCmd, Path, AnnFiles,
+    annotate_files(Language, Files, !IdStore, GUIDStream, Path, AnnFiles,
         !IO).
 
 :- pred annotate_shortcuts(language::in, list(shortcut(L))::in, 
@@ -279,43 +279,14 @@
 is_shortcut_from_programs_menu_2([_ | Rest]) :-
     is_shortcut_from_programs_menu_2(Rest).
 
-gen_guid(Cmd, GUID, !IO) :-
-    io.make_temp(TempFile, !IO),
-    io.call_system_return_signal(Cmd ++ " > " ++ TempFile, CallRes, !IO),
+gen_guid(GUIDFile, GUID, !IO) :-
+    io.read_line_as_string(GUIDFile, Result, !IO), 
     (
-        CallRes = ok(ExitStatus),
-        ( if ExitStatus = exited(0) then
-            io.see(TempFile, SeeRes, !IO),
-            (
-                SeeRes = ok,
-                io.read_line_as_string(ReadRes, !IO),
-                (   
-                    ReadRes = ok(Line),
-                    GUID = string.to_upper(
-                        string.rstrip(Line)),
-                    io.seen(!IO),
-                    io.remove_file(TempFile, _, !IO)
-                ;
-                    ReadRes = eof,
-                    io.remove_file(TempFile, _, !IO),
-                    throw(guid_gen_error(guid_eof))
-                ;
-                    ReadRes = error(Err),
-                    io.remove_file(TempFile, _, !IO),
-                    throw(guid_gen_error(
-                        guid_io_error(Err)))
-                )
-            ;
-                SeeRes = error(Err),
-                io.remove_file(TempFile, _, !IO),
-                throw(guid_gen_error(guid_io_error(Err)))
-            )
-        else
-            io.remove_file(TempFile, _, !IO),
-            throw(guid_gen_error(guid_cmd_error(ExitStatus)))
-        )
+        Result = ok(GUID)
     ;
-        CallRes = error(Err),
-        io.remove_file(TempFile, _, !IO),
+        Result = error(Err),
         throw(guid_gen_error(guid_io_error(Err)))
+    ;
+        Result = eof,
+        throw(guid_gen_error(guid_eof))
     ).
Index: wix_gui.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/wix_gui.m,v
retrieving revision 1.1
diff -u -r1.1 wix_gui.m
--- wix_gui.m	26 Oct 2005 05:04:16 -0000	1.1
+++ wix_gui.m	2 Jan 2006 20:41:19 -0000
@@ -326,7 +326,7 @@
     dialog(finish_dlg, 370 - 270, Title, not_modeless, [
         button(236 - 243, 56 - 17, not_default, Finish, [exit]),
         bitmap(0 - 0, 370 - 234, BackgroundSrc),
-        text(135 - 70, 220 - 60, Message, normal),
+        text(135 - 70, 220 - 160, Message, normal),
         text(135 - 20, 220 - 60, Heading, heading),
         line(0 - 234, 370 - 0)]).
 
@@ -689,7 +689,7 @@
         WizardStep = wizard_start(Heading, Message),
         Background = [bitmap(0 - 0, 370 - 234, BackgroundSrc)],
         HeadingText = [text(135 - 20, 220 - 60, Heading, heading)],
-        MessageText = [text(135 - 70, 220 - 30, Message, normal)],
+        MessageText = [text(135 - 70, 220 - 160, Message, normal)],
         BottomLine = [line(0 - 234, 370 - 0)],
         WizControls = NextButton ++ CancelButton ++
             HeadingText ++ MessageText ++ Background ++
Index: wix_installer.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/wix_installer.m,v
retrieving revision 1.1
diff -u -r1.1 wix_installer.m
--- wix_installer.m	26 Oct 2005 05:04:16 -0000	1.1
+++ wix_installer.m	2 Jan 2006 20:41:19 -0000
@@ -26,10 +26,10 @@
 
 :- import_module wix.
 
-% gen_annotated_installer(Installer, GUIDGenCmd, AnnotatedInstaller, !IO).
+% gen_annotated_installer(Installer, GUIDStream, AnnotatedInstaller, !IO).
 %
 
-:- pred gen_annotated_installer(installer(L)::in, string::in,
+:- pred gen_annotated_installer(installer(L)::in, io.input_stream::in,
     annotated_installer::out, io::di, io::uo) is det 
     <= language_independent_tokens(L).
 
@@ -39,6 +39,7 @@
 
 :- implementation.
 
+:- import_module bool.
 :- import_module exception.
 :- import_module int.
 :- import_module list.
@@ -62,7 +63,8 @@
                 ann_installer_bitmaps       :: map(string, id),
                 ann_installer_removedlg_id  :: id,
                 ann_installer_finish_id     :: id,
-                ann_installer_checkifadmin  :: maybe(string)
+                ann_installer_checkifadmin  :: maybe(string),
+                ann_insatller_all_users     :: bool
             ).
 
 :- type ann_set_env_var
@@ -100,7 +102,8 @@
 
 annotated_installer_to_xml(Installer) = XML :-
     Installer = annotated_installer(Product, LanguageId, EnvVarsGUID, EnvVars,
-        WizardSteps, BitMaps, RemoveDlgId, FinishDlgId, CheckIfAdmin),
+        WizardSteps, BitMaps, RemoveDlgId, FinishDlgId, CheckIfAdmin,
+        AllUsers),
     language_to_lcid(LanguageId, LCID),
     Product = annotated_product(
         GUID,
@@ -112,6 +115,14 @@
         Comments,
         Contents,
         DefInstallLoc),
+    (
+        AllUsers = yes,
+        AllUsersPropertyList = [elem("Property", [id_attr("ALLUSERS")],
+            [data("2")])]
+    ;
+        AllUsers = no,
+        AllUsersPropertyList = []
+    ),
     XML = elem("Wix", [
             attr("xmlns","http://schemas.microsoft.com/wix/2003/01/wix")],
         [
@@ -139,6 +150,7 @@
             else
                 []
             ) ++
+            AllUsersPropertyList ++
             [elem("Media", [
                 id_attr("1"),
                 attr("Cabinet", "contents.cab"),
@@ -185,7 +197,7 @@
         attr("System", system_or_user_to_string(SysOrUser)),
         attr("Value", Value)], []).
 
-gen_annotated_installer(Installer, GUIDGenCmd, AnnotatedInstaller, !IO) :-
+gen_annotated_installer(Installer, GUIDStream, AnnotatedInstaller, !IO) :-
     some [!IdSupply, !DialogIdMap, !BitMaps] (
         !:IdSupply = init_id_supply,
         !:DialogIdMap = map.init,
@@ -194,7 +206,7 @@
             Product, 
             Language, 
             EnvVars, 
-            ShortCuts, 
+            ShortCuts, AllUsers,
             Title, InstallHeading, InstallDescr,
             Next, Back, Cancel, Install, CancelMessage, 
             RemoveHeading, RemoveConfirm, Remove,
@@ -251,12 +263,10 @@
 
         annotate_env_vars(Language, EnvVars, AnnEnvVars, !IdSupply,
             RequiredPrivilege),
-        (
-            RequiredPrivilege = admin,
+        ( if ( RequiredPrivilege = admin ; AllUsers = yes ) then
             det_translate(MustBeAdminMessage, Language, MustBeAdminMsgStr),
             CheckForAdmin = yes(MustBeAdminMsgStr)
-        ;
-            RequiredPrivilege = normal,
+        else
             CheckForAdmin = no
         ),
         det_translate(ManufacturerToken, Language, Manufacturer),
@@ -265,11 +275,11 @@
         det_translate(CommentsToken, Language, Comments),
         det_translate(DefaultInstallToken, Language, DefInsLoc),
         gen_files(FilesPath, ShortCuts, Files, !IO),
-        annotate_files(Language, Files, !.IdSupply, _, GUIDGenCmd, FilesPath, 
+        annotate_files(Language, Files, !.IdSupply, _, GUIDStream, FilesPath, 
             AnnotatedFiles, !IO),
-        gen_guid(GUIDGenCmd, ProductGUID, !IO),
-        gen_guid(GUIDGenCmd, UpgradeGUID, !IO),
-        gen_guid(GUIDGenCmd, EnvVarsGUID, !IO),
+        gen_guid(GUIDStream, ProductGUID, !IO),
+        gen_guid(GUIDStream, UpgradeGUID, !IO),
+        gen_guid(GUIDStream, EnvVarsGUID, !IO),
         AnnotatedInstaller = 
             annotated_installer(
                 annotated_product(
@@ -290,7 +300,8 @@
                 !.BitMaps,
                 RemoveDlgId,
                 FinishDlgId,
-                CheckForAdmin
+                CheckForAdmin,
+                AllUsers
             )
     ).
 
Index: sample/Mercury.config
===================================================================
RCS file: sample/Mercury.config
diff -N sample/Mercury.config
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sample/Mercury.config	2 Jan 2006 20:41:19 -0000
@@ -0,0 +1,114 @@
+#! /bin/sh
+#---------------------------------------------------------------------------#
+# Copyright (C) 2005 The University of Melbourne.
+# This file may only be copied under the terms of the GNU General
+# Public License - see the file COPYING in the Mercury distribution.
+#---------------------------------------------------------------------------#
+#
+# Mercury.config
+#
+# Configuration file for the Melbourne Mercury Compiler.
+#
+# This is a custom configuration file written specifically for 
+# the Windows installer.
+#
+# Environment variables: MERCURY_STDLIB_DIR, MERCURY_C_COMPILER,
+# MERCURY_DEFAULT_GRADE, MERCURY_DEFAULT_OPT_LEVEL,
+# MERCURY_JAVA_COMPILER, MERCURY_JAVA_INTERPRETER.
+
+# These settings won't override settings in the environment.
+MERCURY_STDLIB_DIR=$(MERCURY_CONFIG_DIR)
+MERCURY_DEFAULT_OPT_LEVEL=-O2
+MERCURY_DEFAULT_GRADE=asm_fast.gc
+MERCURY_C_COMPILER=gcc
+MERCURY_MATH_LIB=
+MERCURY_JAVA_COMPILER=/c/MinGW/bin/gcj -C
+MERCURY_JAVA_INTERPRETER=/c/WINDOWS/system32/java
+# $(MATH_LIB) needs to be defined because it may
+# be used by the substitution for SHARED_LIBS.
+MATH_LIB=$(MERCURY_MATH_LIB)
+
+# This needed for Java classpath.
+INSTALL_JAVA_LIBRARY_DIR=$(MERCURY_STDLIB_DIR)/lib/java
+
+# If you change these, you will also need to change the files indicated in
+# scripts/c2init.in.
+RT_LIB_NAME=mer_rt
+STD_LIB_NAME=mer_std
+
+DEFAULT_MERCURY_LINKAGE=static
+
+# The default optimization level should be after
+# all the options that describe the machine configuration.
+DEFAULT_MCFLAGS=\
+		 \
+		 \
+		--cc "$(MERCURY_C_COMPILER)" \
+		--java-compiler "$(MERCURY_JAVA_COMPILER)" \
+		--java-interpreter "$(MERCURY_JAVA_INTERPRETER)" \
+		--grade "$(MERCURY_DEFAULT_GRADE)" \
+		--cflags-for-ansi "-ansi" \
+		--cflags-for-optimization "-O2 -fomit-frame-pointer -fno-strict-aliasing" \
+		--cflags-for-warnings "-Wall -Wwrite-strings -Wshadow -Wno-unused -Wno-uninitialized -Wstrict-prototypes" \
+		--cflags-for-threads "-DGC_WIN32_THREADS -DMR_THREAD_SAFE" \
+		--cflags-for-debug "-g" \
+		--cflags-for-regs "-fno-builtin -fno-omit-frame-pointer" \
+		--cflags-for-gotos "-fno-defer-pop -fno-function-cse -fno-gcse" \
+		--cflags-for-pic "" \
+		--cflags " -B %MERCURY_CONFIG_DIR%/../../libexec/gcc/mingw32/3.4.2 -I %MERCURY_CONFIG_DIR%/../../include -I %MERCURY_CONFIG_DIR%/../gcc/mingw32/3.4.2/include -B %MERCURY_CONFIG_DIR%/../../bin -B %MERCURY_CONFIG_DIR%/../../lib -B %MERCURY_CONFIG_DIR%/../gcc/mingw32/3.4.2" \
+		--ld-flags " -B %MERCURY_CONFIG_DIR%/../../libexec/gcc/mingw32/3.4.2 -I %MERCURY_CONFIG_DIR%/../../include -I %MERCURY_CONFIG_DIR%/../gcc/mingw32/3.4.2/include -B %MERCURY_CONFIG_DIR%/../../bin -B %MERCURY_CONFIG_DIR%/../../lib -B %MERCURY_CONFIG_DIR%/../gcc/mingw32/3.4.2" \
+		--c-flag-to-name-object-file "-o " \
+		--object-file-extension ".o" \
+		--pic-object-file-extension ".o" \
+		--link-with-pic-object-file-extension ".o" \
+		--executable-file-extension ".exe" \
+		--shared-library-extension ".a" \
+		--library-extension ".a" \
+		--create-archive-command "ar" \
+		--create-archive-command-output-flag "" \
+		--create-archive-command-flags "cr" \
+		--ranlib-command "ranlib" \
+		--link-executable-command "$(MERCURY_C_COMPILER)" \
+		--link-shared-lib-command "$(MERCURY_C_COMPILER) -shared" \
+		--trace-libs "  " \
+		--thread-libs "" \
+		--shared-libs "`gcc -print-libgcc-file-name` $(MATH_LIB) -lc" \
+		--math-lib "" \
+		--readline-libs "" \
+		--linker-opt-separator "" \
+		--linker-thread-flags "" \
+		--shlib-linker-thread-flags "" \
+		--linker-trace-flags "" \
+		--shlib-linker-trace-flags "" \
+		--linker-static-flags "-static" \
+		--linker-strip-flag "-s" \
+		--linker-debug-flags "-g" \
+		--shlib-linker-debug-flags "-g" \
+		--linker-link-lib-flag "-l" \
+		--linker-link-lib-suffix "" \
+		--shlib-linker-link-lib-flag "-l" \
+		--shlib-linker-link-lib-suffix "" \
+		--linker-path-flag "-L" \
+		--linker-rpath-flag "-Wl,-rpath," \
+		--linker-rpath-separator " -Wl,-rpath," \
+		--shlib-linker-rpath-flag "-Wl,-rpath," \
+		--shlib-linker-rpath-separator " -Wl,-rpath," \
+		 \
+		--shlib-linker-install-name-flag "-install_name " \
+		--linker-allow-undefined-flag "" \
+		--linker-error-undefined-flag "" \
+		--fullarch "i686-pc-mingw32" \
+		--install-prefix "@INSTALL_PREFIX@" \
+		--num-real-r-regs "1" \
+		--num-real-r-temps "0" \
+		--conf-low-tag-bits "2" \
+		--bits-per-word "32" \
+		--bytes-per-word "4" \
+		--dotnet-library-version "1.0.2411.0" \
+		 \
+		--no-unboxed-float \
+		 \
+		$(MERCURY_DEFAULT_OPT_LEVEL) \
+		--no-use-symlinks \
+		 --libgrade asm_fast.gc 
+
Index: sample/README
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/sample/README,v
retrieving revision 1.1
diff -u -r1.1 README
--- sample/README	26 Oct 2005 05:04:17 -0000	1.1
+++ sample/README	2 Jan 2006 20:41:19 -0000
@@ -6,17 +6,5 @@
 
 mmc --make gen_merc_wxs
 
-
-Usage: gen_merc_wxs <version> <path to merc files> <guid command> <out file>
-
-For example the command:
-
-gen_merc_wxs 0.12.0 c:\mercury uuidgen installer.wxs
-
-will produce the file installer.wxs based on the files in c:\mercury.
-The .wxs file can then be compiled into a Microsoft installer (.msi) 
-file using the Wix compiler and linker (candle.exe and light.exe), available
-from wix.sourceforge.net:
-
-candle installer.wxs
-light installer.wixobj
+The script gen_merc_msi can then be used to generate a Windows installer
+for Mercury.  See the comments in that script for usage information.
Index: sample/gen_merc_msi
===================================================================
RCS file: sample/gen_merc_msi
diff -N sample/gen_merc_msi
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sample/gen_merc_msi	2 Jan 2006 20:41:19 -0000
@@ -0,0 +1,95 @@
+#!/bin/sh
+# This script will generate a windows installer for Mercury.
+#
+
+USAGE="Usage: gen_merc_msi VERSION INSTALL_DIR MINGW_DIR"
+
+# Before running this script perform the following actions:
+# 1. Compile and install Mercury, under MSYS, to INSTALL_DIR.
+# 2. Build the pdf and html documentation and install it to 
+#    INSTALL_DIR/lib/mercury/doc.
+#    (you may need to build the pdf documentation on a Linux machine, since
+#    pdftex doesn't work very well under Cygwin or MSYS).
+# 3. Checkout tutorial/book/book.pdf to INSTALL_DIR/lib/mercury/doc.
+# 4. Install a minimal version of MinGW 3.4.2 (www.mingw.org) to MINGW_DIR.
+# 4. Make sure light and candle (available from wix.sourceforge.org) are
+#    in the PATH.
+# 5. Make sure uuidgen is in the PATH.
+# 6. Compile gen_merc_wxs.m (in this directory) on a system that generates
+#    unix style newlines such as an appropriately configured version of 
+#    Cygwin.
+#
+# Note that INSTALL_DIR has no relationship to where the compiler will be
+# installed on the user's machine when they run the installer, so can be 
+# anywhere.  INSTALL_DIR should be specified with a path that windows will
+# understand (such as c:/mercury, not /cygdrive/c/mercury).
+# VERSION is the version number the user will see in the generated installer.
+# It should match the version number of the compiler in INSTALL_DIR.
+#
+# This script should be run from the same directory it resides in.
+#
+
+VERSION=$1 ; shift
+INSTALL_DIR=$1 ; shift
+MINGW_DIR=$1 ; shift
+
+case $VERSION in
+	"")
+		echo $USAGE
+		exit 1
+		;;
+esac
+
+case $INSTALL_DIR in
+	"")
+		echo $USAGE
+		exit 1
+		;;
+esac
+
+case $MINGW_DIR in
+	"")
+		echo $USAGE
+		exit 1
+		;;
+esac
+
+# Install a new configuration file
+cp -f Mercury.config $INSTALL_DIR/lib/mercury/conf || exit 1
+
+# Copy mercury_compile.exe to mmc.exe so that mmc can be invoked from the
+# command prompt.
+mv -f $INSTALL_DIR/bin/mercury_compile.exe $INSTALL_DIR/bin/mmc.exe || \
+	mv -f $INSTALL_DIR/lib/mercury/bin/i686-pc-mingw32/mercury_compile.exe \
+	$INSTALL_DIR/bin/mmc.exe # || exit 1
+
+# Install a C version of mdb.
+echo Copying mdb...
+$MINGW_DIR/bin/gcc -o mdb.exe mdb.c | exit 1
+cp -f mdb.exe $INSTALL_DIR/bin | exit 1
+
+# Combine a special purpose mdbrc and the installed mdb_doc script
+# into one script, so that mdbrc doesn't have to know where mdb_doc resides.
+cat $INSTALL_DIR/lib/mercury/mdb/mdb_doc ./mdbrc > \
+	$INSTALL_DIR/lib/mercury/mdb/mdbrc || exit 1
+
+# Copy MinGW files.
+echo Copying MinGW...
+cp -rf $MINGW_DIR/bin/* $INSTALL_DIR/bin && \
+cp -rf $MINGW_DIR/lib/* $INSTALL_DIR/lib && \
+cp -rf $MINGW_DIR/include $INSTALL_DIR && \
+cp -rf $MINGW_DIR/libexec $INSTALL_DIR || exit 1
+
+# Generate GUIDs
+echo Generating GUIDs...
+uuidgen -n10000 > uuids
+
+# Generate the installer.
+echo Generating mercury-compiler-$VERSION.wxs...
+./gen_merc_wxs $VERSION $INSTALL_DIR uuids mercury-compiler-$VERSION.wxs || exit 1
+sleep 1
+echo Generating mercury-compiler-$VERSION.wixobj ...
+candle mercury-compiler-$VERSION.wxs || exit 1
+sleep 1
+echo Generating mercury-compiler-$VERSION.msi ...
+light mercury-compiler-$VERSION.wixobj || exit 1
Index: sample/gen_merc_wxs.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/sample/gen_merc_wxs.m,v
retrieving revision 1.1
diff -u -r1.1 gen_merc_wxs.m
--- sample/gen_merc_wxs.m	26 Oct 2005 05:04:17 -0000	1.1
+++ sample/gen_merc_wxs.m	2 Jan 2006 20:41:19 -0000
@@ -22,6 +22,7 @@
 
 :- implementation.
 
+:- import_module bool.
 :- import_module list.
 :- import_module string.
 
@@ -29,7 +30,7 @@
 
 main(!IO) :-
 	io.command_line_arguments(Args, !IO),
-	( if Args = [Version, Path, GUIDGenCmd, OutFile] then
+	( if Args = [Version, Path, GUIDFile, OutFile] then
 		Product = product(
 			merc_group,
 			merc_comp(Version),
@@ -43,8 +44,12 @@
 		Installer ^ wix_product_info            = Product,
 		Installer ^ wix_language                = english_south_africa, 
 		Installer ^ wix_set_env_vars            = 
-			[set_env_var("PATH", path, prepend, system)],
+			[set_env_var("PATH", path, prepend, system),
+			 set_env_var("MERCURY_CONFIG_DIR", merc_conf_dir, 
+			 	replace, system)
+			],
 		Installer ^ wix_shortcut_func           = doc_shortcuts,
+		Installer ^ wix_all_users		= yes,
 		Installer ^ wix_title                   = title, 
 		Installer ^ wix_install_heading         = install_heading, 
 		Installer ^ wix_install_descr           = install_descr, 
@@ -71,11 +76,11 @@
 		Installer ^ wix_banner_source           = "images\\banner.bmp", 
 		Installer ^ wix_background_source       = "images\\bg.bmp",
 		Installer ^ wix_wizard_steps            = [
-			welcome_wizard_step(welcome, welcome_message),
+			welcome_wizard_step(welcome, welcome_message(Version)),
 			license_wizard_step(license_heading, blank, notice_src)
 		],
 
-		generate_installer(Installer, GUIDGenCmd, OutFile, Result,
+		generate_installer(Installer, GUIDFile, OutFile, Result,
 			!IO),
 		(
 			Result = ok
@@ -94,8 +99,9 @@
 	;	merc_comp(string)
 	;	product_comments
 	;	path
+	;	merc_conf_dir
 	;	welcome
-	;	welcome_message
+	;	welcome_message(string)
 	;	title
 	;	next
 	;	back
@@ -124,9 +130,11 @@
 	;	html_ref_man
 	;	html_lib_ref
 	;	html_user_guide
+	;	html_trans
 	;	pdf_ref_man
 	;	pdf_lib_ref
 	;	pdf_user_guide
+	;	pdf_trans
 	;	pdf_tutorial
 	;	blank.
 
@@ -142,12 +150,16 @@
 		Shortcuts = [shortcut(programs, html_user_guide)]
 	else if FileName = "mercury_library.html" then
 		Shortcuts = [shortcut(programs, html_lib_ref)]
+	else if FileName = "mercury_trans_guide.html" then
+		Shortcuts = [shortcut(programs, html_trans)]
 	else if FileName = "reference_manual.pdf" then
 		Shortcuts = [shortcut(programs, pdf_ref_man)]
 	else if FileName = "user_guide.pdf" then
 		Shortcuts = [shortcut(programs, pdf_user_guide)]
 	else if FileName = "library.pdf" then
 		Shortcuts = [shortcut(programs, pdf_lib_ref)]
+	else if FileName = "transition_guide.pdf" then
+		Shortcuts = [shortcut(programs, pdf_trans)]
 	else if FileName = "book.pdf" then
 		Shortcuts = [shortcut(programs, pdf_tutorial)]
 	else
@@ -213,10 +225,16 @@
 token_to_english(merc_comp(Version), "Mercury " ++ Version).
 token_to_english(product_comments, "").
 token_to_english(path, "\"[INSTALLDIR]bin\"").
+token_to_english(merc_conf_dir, "\"[INSTALLDIR]lib\\mercury\"").
 token_to_english(welcome, "Welcome.").
-token_to_english(welcome_message, 
-	"This program will install the Melbourne Mercury distribution " ++
-	"to your computer. Click Next to continue.").
+token_to_english(welcome_message(Version), 
+	"You are about to install the Melbourne Mercury distribution " ++
+	"(version " ++ Version ++ ") onto your computer.\r\n\r\n" ++
+	"The compiler (mmc) and debugger (mdb) will be added to your PATH " ++
+	"and the MERCURY_CONFIG_DIR environment variable will be set " ++
+	"to the configuration directory of the newly installed compiler."++
+	"\r\n\r\n" ++
+	"Click Next to continue.").
 token_to_english(title, "Mercury installer").
 token_to_english(next, "Next >").
 token_to_english(back, "< Back").
@@ -231,7 +249,7 @@
 token_to_english(install_descr, 
 	"Installation may take a few minutes, please be patient.").
 token_to_english(remove_heading, "Uninstall").
-token_to_english(remove_confirm, "Are you sure you wish to uninstall?").
+token_to_english(remove_confirm, "Are you sure you wish to uninstall Mercury?").
 token_to_english(remove, "Remove").
 token_to_english(files_in_use_heading, 
 	"Some files that need to be updated are currently in use.").
@@ -245,20 +263,34 @@
 token_to_english(remove_prog_descr, 
 	"Uninstallation may take a few minutes, please be patient.").
 token_to_english(admin_message, 
-	"You need to be an administrator to install this software.").
-token_to_english(finish_heading, "All done.").
+	"You need to be an administrator to install Mercury, " ++
+	"because the installer needs to set the PATH "++
+	"environment variable at the system level.").
+token_to_english(finish_heading, "Thank you for installing Mercury.").
 token_to_english(finish_message, 
-	"Thank you for installing Mercury. " ++
-	"Online documentation is avalible from www.cs.mu.oz.au/mercury. " ++
-	"Please email any bug reports to mercury-bugs at cs.mu.oz.au. " ++
+	"Shortcuts to the online documentation have been placed " ++
+	"under the Start/Programs menu. " ++
+	"You can get additional help from the Mercury user's mailing list. " ++
+	"For details on how to subscribe to this mailing list go to " ++
+	"http://www.cs.mu.oz.au/mercury and click on the \"Mailing Lists\" " ++
+	"link.  " ++
+	"Please email any bug reports to mercury-bugs at cs.mu.oz.au. \r\n\r\n" ++
+	"NOTE: The installer has set the environment variable " ++
+	"MERCURY_CONFIG_DIR.  " ++
+	"If you are already running Mercury under Cygwin or MSYS " ++
+	"then you will need to unset MERCURY_CONFIG_DIR " ++
+	"before running mmc under " ++
+	"these environments.\r\n\r\n" ++
 	"Click finish to exit the Mercury installer.").
 token_to_english(finish, "Finish").
 token_to_english(html_ref_man, "Reference Manual (HTML)").
 token_to_english(pdf_ref_man, "Reference Manual (PDF)").
 token_to_english(html_lib_ref, "Library Reference (HTML)").
+token_to_english(html_trans, "Prolog to Mercury transition guide (HTML)").
 token_to_english(pdf_lib_ref, "Library Reference (PDF)").
 token_to_english(html_user_guide, "User Guide (HTML)").
 token_to_english(pdf_user_guide, "User Guide (PDF)").
+token_to_english(pdf_trans, "Prolog to Mercury transition guide (PDF)").
 token_to_english(pdf_tutorial, "Introductory Tutorial (PDF)").
 
 :- func merc_installer_usage_message = string.
Index: sample/mdb.c
===================================================================
RCS file: sample/mdb.c
diff -N sample/mdb.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sample/mdb.c	2 Jan 2006 20:41:19 -0000
@@ -0,0 +1,82 @@
+/*
+** Copyright (C) 2005 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING in the Mercury distribution.
+**
+** Main author: Ian MacLarty (maclarty at cs.mu.oz.au).
+**
+** A C version of mdb for use with the Windows installer package.
+** We use a C program instead of a batch file so that we
+** can remove the quotes from MERCURY_CONFIG_DIR before
+** setting MERCURY_DEBUGGER_INIT and so that an arbitrary number
+** of arguments can be supported.
+** We use a C program instead of a Mercury program, because the
+** statically linked Mercury program would be too big.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static	void	delete_quotes(char* str);
+
+int main(int argc, char **argv)
+{
+	char*	mercury_config_dir;
+	char*	mercury_options;
+	char	set_debugger_init[8196];
+	char	set_mercury_options[8196];
+	char	command_string[8196];
+	int	command_string_pos;
+	int	arg_num;
+
+	mercury_config_dir = getenv("MERCURY_CONFIG_DIR");
+	if (mercury_config_dir == NULL) {
+		fprintf(stderr, "MERCURY_CONFIG_DIR not set.\n");
+		exit(EXIT_FAILURE);
+	}
+	delete_quotes(mercury_config_dir);
+	sprintf(set_debugger_init, "MERCURY_DEBUGGER_INIT=%s\\mdb\\mdbrc",
+		mercury_config_dir);
+	putenv(set_debugger_init);
+
+	mercury_options = getenv("MERCURY_OPTIONS");
+	if (mercury_options == NULL) {
+		mercury_options = "";
+	}
+	sprintf(set_mercury_options, "MERCURY_OPTIONS=-Di %s", mercury_options);
+	putenv(set_mercury_options);
+
+	command_string_pos = 0;
+	for (arg_num = 1; argv[arg_num] != NULL; arg_num++) {
+		strcpy(&command_string[command_string_pos], argv[arg_num]);
+		command_string_pos += strlen(argv[arg_num]);
+		strcpy(&command_string[command_string_pos], " ");
+		command_string_pos++;
+	}
+
+	command_string[command_string_pos] = '\0';
+
+	/*
+	** We must use system and not execv, because Windows forks off another
+	** process and returns to the command prompt with execv.
+	*/
+	return system(command_string);
+}
+
+static	void
+delete_quotes(char* str)
+{
+	int	read_pos;
+	int	write_pos;
+	int	len;
+
+	len = strlen(str);
+	write_pos = 0;
+	for (read_pos = 0; read_pos < len; read_pos++) {
+		if (str[read_pos] != '\"') {
+			str[write_pos] = str[read_pos];
+			write_pos++;
+		}
+	}
+	str[write_pos] = '\0';
+}
Index: sample/mdbrc
===================================================================
RCS file: sample/mdbrc
diff -N sample/mdbrc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sample/mdbrc	2 Jan 2006 20:41:19 -0000
@@ -0,0 +1,16 @@
+alias	s	step
+alias	g	goto
+alias	f	finish
+alias	r	retry
+alias	v	vars
+alias	p	print
+alias	P	print *
+alias	d	stack
+alias	c	continue
+alias	b	break
+alias	h	help
+alias	?	help
+alias	excp	exception
+alias	e	exception
+alias	EMPTY	step
+alias	NUMBER	step
Index: sample/images/banner.bmp
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/sample/images/banner.bmp,v
retrieving revision 1.1
diff -u -r1.1 banner.bmp
Binary files /tmp/cvsKFjMbl and banner.bmp differ
Index: sample/images/bg.bmp
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/windows_installer_generator/sample/images/bg.bmp,v
retrieving revision 1.1
diff -u -r1.1 bg.bmp
Binary files /tmp/cvsItXqBQ and bg.bmp differ
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list