[m-rev.] for review: remove compiler Unix dependencies

Simon Taylor stayl at cs.mu.OZ.AU
Sat Aug 2 02:07:57 AEST 2003


Estimated hours taken: 50
Branches: main

Remove Unix dependencies in the compiler.

Avoid calling passes_aux.invoke_shell_command, which
requires the presence of a Unix shell.

The implementation of fact tables still has dependencies
on Unix utilities (e.g. sort).

aclocal.m4:
	Don't pass Unix style paths to MSVC.

configure.in:
	Use `cygpath -m' rather than `cygpath -w'.
	`cygpath -m' uses '/' as the directory separator,
	so it doesn't cause quoting problems in shell
	scripts.

	Apply $CYGPATH to $PREFIX, $LIBDIR, $CONFIG_PREFIX
	and $CONFIG_LIBDIR.

	Don't pass `-lm' when linking with MSVC.

configure.in:
compiler/options.m:
scripts/Mercury.config.in:
	Add extra configuration options to deal with differences
	between linking with gcc and MSVC:
		--linker-opt-separator
		--linker-link-lib-flag
		--linker-link-lib-suffix
		--shlib-linker-link-lib-flag
		--shlib-linker-link-lib-suffix
		--linker-path-flag

NEWS:
doc/user_guide.texi:
compiler/options.m:
compiler/compile_target_code.m:
compiler/make.program_target.m:
	Instead of substituting in an arbitrary shell script when
	processing --pre-link-command and --extra-init-command,
	require that these options specify a command which will
	be passed the name of the source file containing the main
	module as the first argument, with the source files containing
	the remaining modules following. This avoids

	Fix quote_arg to handle Windows paths better.

	Add an option --no-make-implies-use-subdirs, which
	is handy when using `mmc --make' with a workspace
	built without `--use-subdirs'. This is not documented
	as it breaks library installation, so it's only useful
	for developers.

compiler/handle_options.m:
	Don't attempt to use symlinks if they're not available.

	Handle --no-make-implies-use-subdirs.

compiler/make.util.m:
	Handle --no-make-implies-use-subdirs.

compiler/compile_target_code.m:
	Be more careful about quoting.

	Don't call invoke_shell_command where invoke_system_command
	would do.

	Allow linking using MSVC.

compiler/modules.m:
	Remove make_directory, which is now implemented by dir.m.

	Use io.make_symlink rather than shell scripts.

	Implement mercury_update_interface in Mercury.

compiler/llds_out.m:
compiler/make.program_target.m:
	Use dir.make_directory, not modules.make_directory,
	which has been removed.

compiler/make.module_target.m:
	Invoke mercury_compiler directly, not through the
	mmc script to avoid shell dependencies.

	If we can't fork() child `mmc --make' processes,
	pass the arguments to the child process using a
	file to avoid overflowing system limits on Windows.

compiler/mercury_compile.m:
compiler/options_file.m:
	Read argument files.

	Handle backslash-newline in options files correctly.

compiler/passes_aux.m:
	invoke_system_command shouldn't set the exit status --
	the caller may be able to try something else.

compiler/process_util.m:
	Export can_fork for use by make.module_target.m.
	
	Remove hacks to work around bugs in the implementation
	of zero-arity foreign procs.

compiler/prog_io.m:
	Handle bizarre file names without aborting.

library/Mmakefile:
library/print_extra_inits:
	Move code to find extra initialization functions into
	print_extra_inits, due to the change to the handling
	of the --extra-init-command option described above.

scripts/mercury.bat.in:
	Make this actually work.

scripts/*.in:
	Quote 

tools/bootcheck:
	Set ANALYSIS_LIB_NAME.

	Apply cygpath (-m not -w) to $root.

	Link print_extra_inits into the stage2 and stage3
	library directories.

util/mkinit.c:
	Handle '\\' in path names.

	
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.315
diff -u -u -r1.315 NEWS
--- NEWS	21 Jul 2003 14:08:32 -0000	1.315
+++ NEWS	1 Aug 2003 08:56:13 -0000
@@ -201,11 +201,20 @@
 
 Changes to the Mercury compiler:
 
+* `mmc --make' now works correctly with Microsoft Visual C++.
+
 * It's now easier to use shared libraries on Linux/x86 systems with
   `mmc --make'.  See the documentation for the `--mercury-linkage'
   and `--linkage' options and the `MERCURY_LINKAGE' Mmake variable
   in the Mercury User's Guide.
 
+* The behaviour of the `--pre-link-command' and `--extra-init-command'
+  options has changed.  They now take a command which will be passed
+  the names of all source files in the program or library, with the
+  name of the main module's source file passed first.
+  See the "Build system options" section of the "Invocation" chapter
+  of the Mercury User's Guide for details.
+
 * It is now possible to reconfigure an existing Mercury installation
   to use a different C compiler.  See the "C compilers" chapter
   of the Mercury User's Guide for details.
@@ -213,6 +222,11 @@
 * Inlining of builtins can now be disabled using the `--no-inline-builtins'
   option.  This is done by default when debugging, as without this option the
   execution of builtins is not traced.
+
+* By default `mmc --make' implies `--use-subdirs'.
+  There is new option, `--no-make-implies-use-subdirs', to disable
+  that behaviour.  Library installation does not work with
+  `--no-make-implies-use-subdirs'.
 
 * The Mercury compiler now uses `.' and not `:' as the module separator
   in all output.
Index: aclocal.m4
===================================================================
RCS file: /home/mercury1/repository/mercury/aclocal.m4,v
retrieving revision 1.20
diff -u -u -r1.20 aclocal.m4
--- aclocal.m4	18 May 2003 15:59:45 -0000	1.20
+++ aclocal.m4	30 Jul 2003 14:27:55 -0000
@@ -96,9 +96,11 @@
 AC_MSG_CHECKING(whether to pass -I/usr/local/include to C compiler)
 ALL_LOCAL_C_INCL_DIRS=""
 ALL_LOCAL_C_INCL_DIR_MMC_OPTS=""
-if test "$GCC" = yes; then
+
+if test "$GCC" = yes -o "$USING_MICROSOFT_CL_COMPILER" = yes; then
 	# Don't add -I/usr/local/include, since it causes a warning
-	# with gcc 3.1, and gcc already searches /usr/local/include
+	# with gcc 3.1, and gcc already searches /usr/local/include.
+	# Microsoft compilers don't understand Unix pathnames.
 	AC_MSG_RESULT(no)
 else
 	# It's some other compiler.  We don't know if it searches
@@ -122,7 +124,9 @@
 AC_DEFUN(MERCURY_CHECK_LOCAL_C_LIB_DIRS,
 [
 AC_MSG_CHECKING(whether to pass -L/usr/local/lib to the linker)
-if test -d /usr/local/lib/.; then
+
+# Microsoft compilers don't understand Unix pathnames.
+if test "$USING_MICROSOFT_CL_COMPILER" = no -a -d /usr/local/lib/.; then
 	AC_MSG_RESULT(yes)
 	ALL_LOCAL_C_LIB_DIRS=/usr/local/lib
 	ALL_LOCAL_C_LIB_DIR_MMC_OPTS="-L/usr/local/lib -R/usr/local/lib"
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.371
diff -u -u -r1.371 configure.in
--- configure.in	26 Jul 2003 15:22:30 -0000	1.371
+++ configure.in	31 Jul 2003 13:57:58 -0000
@@ -68,14 +68,21 @@
 	;;
 esac
 
-LIBDIR="$PREFIX/lib/mercury"
-WINDOWS_LIBDIR="`cygpath -w $LIBDIR 2>/dev/null`"
+
+# Using `cygpath -m' gives a path that works under both
+# Cygwin and native Windows, without causing quoting
+# problems in shell scripts. (`cygpath -m' converts the
+# path to Windows format, with '/' as the directory
+# separator).
+AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+
+PREFIX="`$CYGPATH $PREFIX`"
+LIBDIR="`$CYGPATH $PREFIX/lib/mercury`"
 NONSHARED_LIB_DIR=${MERCURY_NONSHARED_LIB_DIR=$PREFIX/lib/nonshared}
 AC_SUBST(VERSION)
 AC_SUBST(PREFIX)
 AC_SUBST(NONSHARED_LIB_DIR)
 AC_SUBST(LIBDIR)
-AC_SUBST(WINDOWS_LIBDIR)
 DEFAULT_MERCURY_DEBUGGER_INIT_DIR=$LIBDIR/mdb
 AC_SUBST(DEFAULT_MERCURY_DEBUGGER_INIT_DIR)
 #-----------------------------------------------------------------------------#
@@ -144,6 +151,8 @@
 		exit 1
 		;;
 esac
+CONFIG_PREFIX="`$CYGPATH $CONFIG_PREFIX`"
+CONFIG_LIBDIR="`$CYGPATH $CONFIG_LIBDIR`"
 AC_SUBST(CONFIG_PREFIX)
 AC_SUBST(CONFIG_LIBDIR)
 #-----------------------------------------------------------------------------#
@@ -483,6 +492,7 @@
 		;;
 esac
 
+#-----------------------------------------------------------------------------#
 # Make sure we search /usr/local/include and /usr/local/lib for
 # header files and libraries.  GNU C normally searches /usr/local/include
 # by default, but (inconsistently) on some systems, such as Solaris,
@@ -501,16 +511,6 @@
 
 AC_PROG_CPP
 #-----------------------------------------------------------------------------#
-# Check for `-lm': some systems, e.g. MacOS X (Darwin), don't have it.
-# When cross-compiling from Cygwin to Mingw (and perhaps also on
-# native Mingw?), `-lm' exists, but it is not needed and in fact we must
-# not use it, because if we do then it causes cygwin1.dll to be linked in.
-AC_CHECK_LIB(m, sin, [MATH_LIB=-lm], [MATH_LIB=])
-case "$CC" in *"-mno-cygwin")
-	MATH_LIB=
-esac
-AC_SUBST(MATH_LIB)
-#-----------------------------------------------------------------------------#
 AC_MSG_CHECKING(for use of a Microsoft C compiler)
 AC_EGREP_CPP(yes,
 [
@@ -522,8 +522,6 @@
 ] AC_MSG_RESULT(yes), [ac_microsoft=no
 ] AC_MSG_RESULT(no))
 
-AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
-
 LDFLAGS_FOR_TRACE=
 LD_LIBFLAGS_FOR_TRACE=
 if test "$ac_microsoft" = "yes" ; then
@@ -533,6 +531,7 @@
 	LIB_PREFIX="lib"
 	LIB_LIBPATH="/LIBPATH:"
 	LINK_LIB=""
+	LINK_LIB_SUFFIX=".lib"
 	LINK_OPT_SEP="/link"
 
 	OBJFILE_OPT="/Fo"
@@ -542,6 +541,7 @@
 
 	LDFLAGS_FOR_DEBUG="/DEBUG"
 	LD_LIBFLAGS_FOR_DEBUG="/DEBUG"
+	LD_STRIP_FLAG=
 
 	USING_MICROSOFT_CL_COMPILER="yes"
 
@@ -560,6 +560,7 @@
 	LIB_PREFIX=""
 	LIB_LIBPATH="-L"
 	LINK_LIB="-l"
+	LINK_LIB_SUFFIX=""
 	LINK_OPT_SEP=""
 
 	OBJFILE_OPT="-o "
@@ -567,6 +568,7 @@
 	ARFLAGS="cr"
 	AR_LIBFILE_OPT=""
 
+	LD_STRIP_FLAG="-s"
 	LDFLAGS_FOR_DEBUG="-g"
 	LD_LIBFLAGS_FOR_DEBUG="-g"
 
@@ -608,6 +610,7 @@
 AC_SUBST(AR_LIBFILE_OPT)
 AC_SUBST(LDFLAGS_FOR_DEBUG)
 AC_SUBST(LD_LIBFLAGS_FOR_DEBUG)
+AC_SUBST(LD_STRIP_FLAG)
 AC_SUBST(LDFLAGS_FOR_TRACE)
 AC_SUBST(LD_LIBFLAGS_FOR_TRACE)
 AC_SUBST(USING_MICROSOFT_CL_COMPILER)
@@ -616,14 +619,24 @@
 AC_SUBST(LIB_PREFIX)
 AC_SUBST(LIB_LIBPATH)
 AC_SUBST(LINK_LIB)
+AC_SUBST(LINK_LIB_SUFFIX)
 AC_SUBST(LINK_OPT_SEP)
 AC_SUBST(FIX_PATH_FOR_CC)
 AC_SUBST(CYGPATH)
 
 #-----------------------------------------------------------------------------#
-# If we're producing a Win32 version of the compiler, don't use symlinks
-# when installing. The generated compiler executable will not be able to
-# follow them.
+# Check for `-lm': some systems, e.g. MacOS X (Darwin), don't have it.
+# The result of this check may be overridden below.
+AC_CHECK_LIB(m, sin, [MATH_LIB=-lm], [MATH_LIB=])
+
+#-----------------------------------------------------------------------------#
+# If we're compiling the compiler with MS Visual C++ or `gcc -mno-cygwin',
+# don't use symlinks when installing -- the generated compiler executable
+# will not be able to follow them.
+#
+# When cross-compiling from Cygwin to Mingw (and perhaps also on
+# native Mingw?), `-lm' exists, but it is not needed and in fact we must
+# not use it, because if we do then it causes cygwin1.dll to be linked in.
 MMC_USE_SYMLINKS_OPT=
 LN_S="ln -s"
 case "$host" in
@@ -632,11 +645,15 @@
 	    # cl is the Microsoft C compiler
 	    *gcc*-mno-cygwin* | *cl* | *CL*)
 		MMC_USE_SYMLINKS_OPT=--no-use-symlinks
-		LN_S=false ;;
+		MATH_LIB=
+		LN_S=false
+		;;
 	esac ;;
 esac
+
 AC_SUBST(LN_S)
 AC_SUBST(MMC_USE_SYMLINKS_OPT)
+AC_SUBST(MATH_LIB)
 
 #-----------------------------------------------------------------------------#
 # Microsoft.NET configuration
@@ -2752,11 +2769,8 @@
 # set up some default values that should work on most systems
 # see Mmake.common.in for documentation on the meaning of these variables
 LINK_EXE=$CC
-LD_STRIP_FLAG="-s"
 LINK_SHARED_OBJ="$CC -shared"
 LINK_SHARED_OBJ_SH="$CC -shared"
-LD_DEBUG_FLAGS="-g"
-LD_LIB_DEBUG_FLAGS="-g"
 if test "$GCC" = "yes"; then
 	SHARED_LIBS="\`$CC -print-libgcc-file-name\` \$(MATH_LIB) -lc"
 	SHARED_LIBS_SH="\`$CC -print-libgcc-file-name\` \$MATH_LIB -lc"
@@ -3123,7 +3137,6 @@
 #-----------------------------------------------------------------------------#
 
 AC_SUBST(LINK_EXE)
-AC_SUBST(LD_STRIP_FLAG)
 AC_SUBST(LD_STATIC_FLAGS)
 AC_SUBST(DEFAULT_LINKAGE)
 AC_SUBST(LINK_SHARED_OBJ)
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.45
diff -u -u -r1.45 compile_target_code.m
--- compiler/compile_target_code.m	21 Jul 2003 14:08:38 -0000	1.45
+++ compiler/compile_target_code.m	30 Jul 2003 14:38:23 -0000
@@ -140,15 +140,14 @@
 
 %-----------------------------------------------------------------------------%
 
-	% substitute_user_command(Command0, ModuleName,
-	%		AllModuleNames) = Command
+	% make_all_module_command(CommandName, MainModule,
+	%		AllModuleNames, CommandString)
 	%
-	% Replace all occurrences of `@' in Command with ModuleName,
-	% and replace occurrences of `%' in Command with AllModuleNames.
-	% This is used to implement the `--pre-link-command' and
-	% `--make-init-file-command' options.
-:- func substitute_user_command(string, module_name,
-		list(module_name)) = string.
+	% Create a command string which passes the source file names
+	% for AllModuleNames to CommandName, with MainModule given first.
+:- pred make_all_module_command(string, module_name,
+		list(module_name), string, io__state, io__state).
+:- mode make_all_module_command(in, in, in, out, di, uo) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -672,7 +671,7 @@
 		},
 		% javac won't create the destination directory for
 		% class files, so we need to do it.
-		make_directory(DirName),
+		dir__make_directory(DirName, _),
 		% Set destination directory for class files.
 		{ DestDir = "-d " ++ DirName ++ " " }
 	;
@@ -757,12 +756,11 @@
 		globals__io_lookup_maybe_string_option(extra_init_command,
 			MaybeInitFileCommand),
 		(
-			{ MaybeInitFileCommand = yes(InitFileCommand0) },
-			{ InitFileCommand = substitute_user_command(
-				InitFileCommand0, MainModuleName,
-				AllModules) },
-			invoke_shell_command(InitFileStream, verbose_commands,
-				InitFileCommand, Succeeded0)
+			{ MaybeInitFileCommand = yes(InitFileCommand) },
+			make_all_module_command(InitFileCommand,
+				MainModuleName, AllModules, CommandString),
+			invoke_system_command(InitFileStream, verbose_commands,
+				CommandString, Succeeded0)
 		;
 			{ MaybeInitFileCommand = no },
 			{ Succeeded0 = yes }
@@ -815,7 +813,7 @@
 	( { Target = asm } ->
 	    % for --target asm, we generate everything into a single object file
 	    ( { Modules = [FirstModule | _] } ->
-		join_module_list([FirstModule], Obj, [], ObjectsList)
+		join_module_list([FirstModule], Obj, ObjectsList)
 	    ;
 		{ error("link_module_list: no modules") }
 	    ),
@@ -825,13 +823,13 @@
 	    module_name_to_file_name(MainModuleName, LibExt,
 	    	yes, SplitLibFileName),
 	    { string__append(".dir/*", Obj, DirObj) },
-	    join_module_list(Modules, DirObj, [], ObjectList),
+	    join_module_list(Modules, DirObj, ObjectList),
 	    create_archive(OutputStream, SplitLibFileName,
 	    	ObjectList, MakeLibCmdOK),
 	    { ObjectsList = [SplitLibFileName] }
 	;
 	    { MakeLibCmdOK = yes },
-	    join_module_list(Modules, Obj, [], ObjectsList)
+	    join_module_list(Modules, Obj, ObjectsList)
 	),
 	( { MakeLibCmdOK = no } ->
     	    { Succeeded = no }
@@ -839,8 +837,8 @@
     	    ( { TargetType = executable } ->
 		{ list__map(
 		    (pred(ModuleStr::in, ModuleName::out) is det :-
-			ModuleStrBase = dir__basename_det(ModuleStr),
-			file_name_to_module_name(ModuleStrBase, ModuleName)
+			file_name_to_module_name(dir__basename_det(ModuleStr),
+				ModuleName)
 		    ),
 		    Modules, ModuleNames) },
 		{ MustCompile = yes },
@@ -904,7 +902,7 @@
 		module_name_to_file_name(ThisModuleName, ".c", no,
 			CFileName)
 	    ), ModuleNames, CFileNameList),
-	{ join_string_list(CFileNameList, "", "", " ", CFileNames) },
+	{ join_quoted_string_list(CFileNameList, "", "", " ", CFileNames) },
 
 	globals__io_lookup_accumulating_option(init_file_directories,
 		InitFileDirsList),
@@ -963,9 +961,9 @@
 	{ MkInitCmd = string__append_list(
 		[Mkinit,  " -g ", Grade, " ", TraceOpt, " ", ExtraInitsOpt,
 		" ", NoMainOpt, " ", AditiOpt, " ", RuntimeFlags,
-		" -o ", TmpInitCFileName, " ", InitFileDirs,
+		" -o ", quote_arg(TmpInitCFileName), " ", InitFileDirs,
 		" ", InitFileNames, " ", CFileNames]) },
-	invoke_shell_command(ErrorStream, verbose, MkInitCmd, MkInitOK0),
+	invoke_system_command(ErrorStream, verbose, MkInitCmd, MkInitOK0),
 	maybe_report_stats(Stats),
 	( { MkInitOK0 = yes } ->
 	    update_interface(InitCFileName, MkInitOK1),
@@ -1125,7 +1123,8 @@
 			mercury_standard_library_directory, MaybeStdLibDir),
 		(
 			{ MaybeStdLibDir = yes(StdLibDir) },
-			get_mercury_std_libs(StdLibDir, MercuryStdLibs)
+			get_mercury_std_libs(LinkTargetType,
+				StdLibDir, MercuryStdLibs)
 		;
 			{ MaybeStdLibDir = no },
 			{ MercuryStdLibs = "" }
@@ -1136,15 +1135,19 @@
 		%
 		get_system_libs(LinkTargetType, SystemLibs),
 
-		{ join_string_list(ObjectsList, "", "", " ", Objects) },
+		{ join_quoted_string_list(ObjectsList,
+				"", "", " ", Objects) },
 		globals__io_lookup_accumulating_option(LDFlagsOpt,
 				LDFlagsList),
 		{ join_string_list(LDFlagsList, "", "", " ", LDFlags) },
 		globals__io_lookup_accumulating_option(
 				link_library_directories,
 				LinkLibraryDirectoriesList),
-		{ join_quoted_string_list(LinkLibraryDirectoriesList, "-L", "",
-				" ", LinkLibraryDirectories) },
+		globals__io_lookup_string_option(linker_path_flag,
+				LinkerPathFlag),
+		{ join_quoted_string_list(LinkLibraryDirectoriesList,
+				LinkerPathFlag, "", " ",
+				LinkLibraryDirectories) },
 
 		%
 		% Set up the runtime library path.
@@ -1198,6 +1201,9 @@
 		list__map_foldl2(process_link_library(MercuryLibDirs),
 				LinkLibrariesList0, LinkLibrariesList,
 				yes, LibrariesSucceeded),	
+
+		globals__io_lookup_string_option(linker_opt_separator,
+				LinkOptSep),
 		(
 			{ LibrariesSucceeded = yes },
 			{ join_quoted_string_list(LinkLibrariesList,
@@ -1207,13 +1213,14 @@
 			% so it should come after Objects.
 			globals__io_lookup_string_option(CommandOpt, Command),
 			{ string__append_list(
-				[Command, " ", UndefOpt, " ", StripOpt,
-				" ", DebugOpts, " ", StaticOpts, " ",
+				[Command, " ",
+				StaticOpts, " ", StripOpt, " ", UndefOpt, " ",
 				ThreadOpts, " ", TraceOpts, " ",
-				LinkLibraryDirectories, " ", RpathOpts,
 				" -o ", OutputFileName, " ", Objects, " ",
-				LDFlags, " ", LinkLibraries, " ",
-				MercuryStdLibs, " ", SystemLibs],
+				LinkOptSep, " ", LinkLibraryDirectories, " ",
+				RpathOpts, " ", DebugOpts, " ", LDFlags, " ",
+				LinkLibraries, " ", MercuryStdLibs, " ",
+				SystemLibs],
 				LinkCmd) },
 
 			globals__io_lookup_bool_option(demangle, Demangle),
@@ -1225,7 +1232,7 @@
 				{ MaybeDemangleCmd = no }
 			),
 
-			invoke_shell_command(ErrorStream, verbose_commands,
+			invoke_system_command(ErrorStream, verbose_commands,
 				LinkCmd, MaybeDemangleCmd, LinkSucceeded)
 		;
 			{ LibrariesSucceeded = no },
@@ -1262,10 +1269,10 @@
 
 	% Find the standard Mercury libraries, and the system
 	% libraries needed by them.
-:- pred get_mercury_std_libs(dir_name::in, string::out,
-		io__state::di, io__state::uo) is det.
+:- pred get_mercury_std_libs(linked_target_type::in, dir_name::in,
+		string::out, io__state::di, io__state::uo) is det.
 
-get_mercury_std_libs(StdLibDir, StdLibs) -->
+get_mercury_std_libs(TargetType, StdLibDir, StdLibs) -->
 	globals__io_lookup_string_option(fullarch, FullArch),
 	globals__io_get_gc_method(GCMethod),
 	globals__io_lookup_string_option(library_extension, LibExt),
@@ -1294,14 +1301,14 @@
 		;
 			GCGrade = GCGrade0
 		},
-		{ SharedGCLibs = "-l" ++ GCGrade },
-		{ StaticGCLibs =
-			StdLibDir/"lib"/FullArch/("lib" ++ GCGrade ++ LibExt) }
+		make_link_lib(TargetType, GCGrade, SharedGCLibs),
+		{ StaticGCLibs = quote_arg(StdLibDir/"lib"/FullArch/
+					("lib" ++ GCGrade ++ LibExt)) }
 	;
 		{ GCMethod = mps },
-		{ SharedGCLibs = "-lmps" },
-		{ StaticGCLibs =
-			StdLibDir/"lib"/FullArch/("libmps" ++ LibExt) }
+		make_link_lib(TargetType, "mps", SharedGCLibs),
+		{ StaticGCLibs = quote_arg(StdLibDir/"lib"/FullArch/
+					("libmps" ++ LibExt) ) }
 	;
 		{ GCMethod = accurate },
 		{ StaticGCLibs = "" },
@@ -1317,27 +1324,54 @@
 		{ SharedTraceLibs = "" }
 	;
 		{ StaticTraceLibs =
-			StdLibDir/"lib"/GradeDir/FullArch/
-				("libmer_trace" ++ LibExt) ++
+			quote_arg(StdLibDir/"lib"/GradeDir/FullArch/
+				("libmer_trace" ++ LibExt)) ++
 			" " ++
-			StdLibDir/"lib"/GradeDir/FullArch/
-				("libmer_browser" ++ LibExt) },
-		{ SharedTraceLibs = "-lmer_trace -lmer_browser" }
+			quote_arg(StdLibDir/"lib"/GradeDir/FullArch/
+				("libmer_browser" ++ LibExt)) },
+		make_link_lib(TargetType, "mer_trace", TraceLib),
+		make_link_lib(TargetType, "mer_browser", BrowserLib),
+		{ SharedTraceLibs = string__join_list(" ",
+					[TraceLib, BrowserLib]) }
 	),
 
 	globals__io_lookup_string_option(mercury_linkage, MercuryLinkage),
-	{ MercuryLinkage = "static" ->
-	    StdLibs = string__join_list(" ",
+	( { MercuryLinkage = "static" } ->
+	    { StdLibs = string__join_list(" ",
 		[StaticTraceLibs,
-		StdLibDir/"lib"/GradeDir/FullArch/("libmer_std" ++ LibExt),
-		StdLibDir/"lib"/GradeDir/FullArch/("libmer_rt" ++ LibExt),
-		StaticGCLibs])
-	; MercuryLinkage = "shared" ->
-	    StdLibs = string__join_list(" ",
-		[SharedTraceLibs, "-lmer_std -lmer_rt", SharedGCLibs])
+		quote_arg(StdLibDir/"lib"/GradeDir/FullArch/
+			("libmer_std" ++ LibExt)),
+		quote_arg(StdLibDir/"lib"/GradeDir/FullArch/
+			("libmer_rt" ++ LibExt)),
+		StaticGCLibs]) }
+	; { MercuryLinkage = "shared" } ->
+	    make_link_lib(TargetType, "mer_std", StdLib),
+	    make_link_lib(TargetType, "mer_rt", RuntimeLib),
+	    { StdLibs = string__join_list(" ",
+		[SharedTraceLibs, StdLib, RuntimeLib, SharedGCLibs]) }
 	;
-		error("unknown linkage " ++ MercuryLinkage)
-	}.
+	    { error("unknown linkage " ++ MercuryLinkage) }
+	).
+
+:- pred make_link_lib(linked_target_type::in, string::in, string::out,
+		io__state::di, io__state::uo) is det.
+
+make_link_lib(TargetType, LibName, LinkOpt) -->
+	{
+		TargetType = executable,
+		LinkLibFlag = linker_link_lib_flag,
+		LinkLibSuffix = linker_link_lib_suffix
+	;
+		TargetType = shared_library,
+		LinkLibFlag = shlib_linker_link_lib_flag,
+		LinkLibSuffix = shlib_linker_link_lib_suffix
+	;
+		TargetType = static_library,
+		error("make_link_lib: static_library")
+	},
+	globals__io_lookup_string_option(LinkLibFlag, LinkLibOpt),
+	globals__io_lookup_string_option(LinkLibSuffix, Suffix),
+	{ LinkOpt = quote_arg(LinkLibOpt ++ LibName ++ Suffix) }.
 
 :- pred get_system_libs(linked_target_type::in, string::out,
 		io__state::di, io__state::uo) is det.
@@ -1445,7 +1479,7 @@
 		bool, io__state, io__state).
 :- mode create_archive(in, in, in, out, di, uo) is det.
 
-create_archive(ErrorStream, LibFileName, ObjectList, MakeLibCmdOK) -->
+create_archive(ErrorStream, LibFileName, ObjectList, Succeeded) -->
 	globals__io_lookup_string_option(create_archive_command, ArCmd),
 	globals__io_lookup_accumulating_option(
 		create_archive_command_flags, ArFlagsList),
@@ -1453,13 +1487,20 @@
 	globals__io_lookup_string_option(
 		create_archive_command_output_flag, ArOutputFlag),
 	globals__io_lookup_string_option(ranlib_command, RanLib),
-	{ join_string_list(ObjectList, "", "", " ", Objects) },
+	{ join_quoted_string_list(ObjectList, "", "", " ", Objects) },
 	{ MakeLibCmd = string__append_list([
 		ArCmd, " ", ArFlags, " ", ArOutputFlag, " ",
-		LibFileName, " ", Objects,  
-		" && ", RanLib, " ", LibFileName]) },
+		LibFileName, " ", Objects]) },
 	invoke_system_command(ErrorStream, verbose_commands,
-		MakeLibCmd, MakeLibCmdOK).
+		MakeLibCmd, MakeLibCmdSucceeded),
+	( { RanLib = "" ; MakeLibCmdSucceeded = no } ->
+		{ Succeeded = MakeLibCmdSucceeded }
+	;
+		{ RanLibCmd =
+			string__append_list([RanLib, " ", LibFileName]) },
+		invoke_system_command(ErrorStream, verbose_commands,
+			RanLibCmd, Succeeded)
+	).
 
 get_object_code_type(FileType, ObjectCodeType) -->
 	globals__io_lookup_string_option(pic_object_file_extension, PicObjExt),
@@ -1572,27 +1613,23 @@
 	join_string_list(map(quote_arg, Strings),
 		Prefix, Suffix, Separator, Result).
 
-	% join_module_list(ModuleNames, Extension, Terminator, Result)
+	% join_module_list(ModuleNames, Extension, Result)
 	%
 	% The list of strings `Result' is computed from the list of strings
 	% `ModuleNames', by removing any directory paths, and
 	% converting the strings to file names and then back,
 	% adding the specified Extension.  (This conversion ensures
 	% that we follow the usual file naming conventions.)
-	% Each file name is separated by a space from the next one, 
-	% and the result is followed by the list of strings `Terminator'.
 
-:- pred join_module_list(list(string), string, list(string), list(string),
+:- pred join_module_list(list(string), string, list(string),
 			io__state, io__state).
-:- mode join_module_list(in, in, in, out, di, uo) is det.
+:- mode join_module_list(in, in, out, di, uo) is det.
 
-join_module_list([], _Extension, Terminator, Terminator) --> [].
-join_module_list([Module | Modules], Extension, Terminator,
-			[FileName, " " | Rest]) -->
-	{ BaseName = dir__basename_det(Module) },
-	{ file_name_to_module_name(BaseName, ModuleName) },
+join_module_list([], _Extension, []) --> [].
+join_module_list([Module | Modules], Extension, [FileName | Rest]) -->
+	{ file_name_to_module_name(dir__basename_det(Module), ModuleName) },
 	module_name_to_file_name(ModuleName, Extension, no, FileName),
-	join_module_list(Modules, Extension, Terminator, Rest).
+	join_module_list(Modules, Extension, Rest).
 
 %-----------------------------------------------------------------------------%
 
@@ -1677,46 +1714,16 @@
 
 %-----------------------------------------------------------------------------%
 
-substitute_user_command(Command0, MainModule, AllModules) = Command :-
-	( string__contains_char(Command0, Char), (Char = ('@') ; Char = '%') ->
-		prog_out__sym_name_to_string(MainModule, ".", MainModuleStr),
-		AllModulesStrings = list__map(
-		    (func(Module) = ModuleStr :-
-			prog_out__sym_name_to_string(Module, ".", ModuleStr)
-		    ), AllModules),
-		join_string_list(AllModulesStrings,
-			"", "", " ", AllModulesStr),
-		Command = string__from_rev_char_list(substitute_user_command_2(
-			string__to_char_list(Command0),
-			reverse(string__to_char_list(MainModuleStr)),
-			reverse(string__to_char_list(AllModulesStr)),
-			[]))
-	;
-		Command = Command0
-	).
-
-:- func substitute_user_command_2(list(char), list(char),
-		list(char), list(char)) = list(char).
-
-substitute_user_command_2([], _, _, RevChars) = RevChars.
-substitute_user_command_2([Char | Chars], RevMainModule,
-		RevAllModules, RevChars0) =
-	(
-		( Char = ('@'), Subst = RevMainModule
-		; Char = '%', Subst = RevAllModules
-		)
-	->
-		( Chars = [Char | Chars2] ->
-			substitute_user_command_2(Chars2, RevMainModule,
-				RevAllModules, [Char | RevChars0])
-		;
-			substitute_user_command_2(Chars, RevMainModule,
-				RevAllModules, Subst ++ RevChars0)
-		)
-	;
-		substitute_user_command_2(Chars, RevMainModule,
-			RevAllModules, [Char | RevChars0])
-	).
+make_all_module_command(Command0, MainModule, AllModules, Command) -->
+	% Pass the main module first.
+	list__map_foldl(
+		(pred(Module::in, FileName::out, di, uo) is det -->
+			module_name_to_file_name(Module, ".m", no, FileName)
+		),
+		[MainModule | list__delete_all(AllModules, MainModule)],
+		ModuleNameStrings),
+	{ Command = string__join_list(" ",
+		list__map(quote_arg, [Command0 | ModuleNameStrings])) }.
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.185
diff -u -u -r1.185 handle_options.m
--- compiler/handle_options.m	14 May 2003 04:05:39 -0000	1.185
+++ compiler/handle_options.m	30 Jul 2003 14:27:55 -0000
@@ -513,8 +513,14 @@
 	% This is needed for library installation (the library grades
 	% are built using `--use-grade-subdirs', and assume that
 	% the interface files were built using `--use-subdirs').
-	option_implies(make, use_subdirs, bool(yes)),
-	option_implies(invoked_by_mmc_make, use_subdirs, bool(yes)),
+	globals__io_lookup_bool_option(make_implies_use_subdirs,
+		MakeImpliesUseSubdirs),
+	( { MakeImpliesUseSubdirs = yes } ->
+		option_implies(make, use_subdirs, bool(yes)),
+		option_implies(invoked_by_mmc_make, use_subdirs, bool(yes))
+	;
+		[]
+	),
 	option_implies(invoked_by_mmc_make, make, bool(no)),
 
 	% --make handles creation of the module dependencies itself,
@@ -527,6 +533,12 @@
 	% being rewritten anyway.
 	option_implies(make, transitive_optimization, bool(no)),
 	option_implies(invoked_by_mmc_make, transitive_optimization, bool(no)),
+
+	( { \+ io__have_symlinks } ->
+		globals__io_set_option(use_symlinks, bool(no))	
+	;
+		[]
+	),
 
 	option_implies(verbose_check_termination, check_termination,bool(yes)),
 	option_implies(check_termination, termination, bool(yes)),
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.215
diff -u -u -r1.215 llds_out.m
--- compiler/llds_out.m	3 Jul 2003 12:11:16 -0000	1.215
+++ compiler/llds_out.m	30 Jul 2003 14:27:55 -0000
@@ -200,7 +200,7 @@
 :- import_module parse_tree__prog_out.
 :- import_module parse_tree__prog_util.
 
-:- import_module int, char, string, std_util.
+:- import_module dir, int, char, string, std_util.
 :- import_module set, bintree_set, assoc_list, require.
 :- import_module varset, term.
 :- import_module library.	% for the version number.
@@ -226,7 +226,7 @@
 		{ C_File = c_file(ModuleName, C_HeaderInfo,
 			UserForeignCodes, Exports, Vars, Datas, Modules) },
 		module_name_to_file_name(ModuleName, ".dir", yes, ObjDirName),
-		make_directory(ObjDirName),
+		dir__make_directory(ObjDirName, _),
 
 		output_split_c_file_init(ModuleName, Modules, Datas,
 			StackLayoutLabels, MaybeRLFile),
Index: compiler/make.module_dep_file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.module_dep_file.m,v
retrieving revision 1.7
diff -u -u -r1.7 make.module_dep_file.m
--- compiler/make.module_dep_file.m	15 Mar 2003 03:08:56 -0000	1.7
+++ compiler/make.module_dep_file.m	30 Jul 2003 14:27:55 -0000
@@ -285,7 +285,7 @@
 		{ ProgDepResult = error(Error) },
 		{ io__error_message(Error, Msg) },
 		io__write_strings(["Error opening ", ProgDepFile,
-			"for output: ", Msg, "\n"]),
+			" for output: ", Msg, "\n"]),
 		io__set_exit_status(1)
 	).
 
@@ -546,7 +546,8 @@
 		    build_with_module_options(ModuleName,
 			["--make-short-interface"],
 			make_short_interfaces(ErrorStream,
-				SourceFileName, SubModuleList)), 
+				SourceFileName, SubModuleList)
+		    ), 
 		    cleanup_short_interfaces(SubModuleNames),
 		    Succeeded, Info2, Info3)
 	    ;
Index: compiler/make.module_target.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.module_target.m,v
retrieving revision 1.23
diff -u -u -r1.23 make.module_target.m
--- compiler/make.module_target.m	15 Mar 2003 03:08:56 -0000	1.23
+++ compiler/make.module_target.m	30 Jul 2003 14:27:55 -0000
@@ -257,28 +257,50 @@
 	maybe_make_target_message(TargetFile),
 	{ TargetFile = ModuleName - _FileType },
 	{ CompilationTask = Task - TaskOptions },
+	(
+		{ CompilationTask =
+			process_module(compile_to_target_code) - _ },
+		\+ { can_fork }
+	->
+		% We need a temporary file to pass the arguments to
+		% the mmc process which will do the compilation.
+		% It's created here (not in invoke_mmc) so it can be
+		% cleaned up by build_with_check_for_interrupt.
+		io__make_temp(ArgFileName),
+		{ MaybeArgFileName = yes(ArgFileName) }
+	;
+		{ MaybeArgFileName = no }	
+	),
 	{ Cleanup =
 		(pred(MakeInfo0::in, MakeInfo::out, di, uo) is det -->
 			% XXX Remove `.int.tmp' files.
 			list__foldl2(remove_target_file, TouchedTargetFiles,
 				MakeInfo0, MakeInfo1),
 			list__foldl2(remove_file, TouchedFiles,
-				MakeInfo1, MakeInfo)
+				MakeInfo1, MakeInfo),
+			(
+				{ MaybeArgFileName = yes(ArgFileName2) },
+				io__remove_file(ArgFileName2, _)
+			;
+				{ MaybeArgFileName = no }
+			)
 		) },
 	build_with_check_for_interrupt(
 	    build_with_module_options_and_output_redirect(ModuleName,
-		TaskOptions, build_target_2(ModuleName, Task, Imports)),
+		TaskOptions,
+		build_target_2(ModuleName, Task, MaybeArgFileName, Imports)),
 	    Cleanup, Succeeded, Info0, Info1),
     	record_made_target_2(Succeeded, TargetFile, TouchedTargetFiles,
 	    TouchedFiles, Info1, Info).
 
 :- pred build_target_2(module_name::in, compilation_task_type::in,
-	module_imports::in, list(string)::in, io__output_stream::in,
-	bool::out, make_info::in, make_info::out,
+	maybe(file_name)::in, module_imports::in, list(string)::in,
+	io__output_stream::in, bool::out, make_info::in, make_info::out,
 	io__state::di, io__state::uo) is det.
 
-build_target_2(ModuleName, process_module(ModuleTask), _Imports,
-		AllOptionArgs, ErrorStream, Succeeded, Info, Info) -->
+build_target_2(ModuleName, process_module(ModuleTask), ArgFileName,
+		_Imports, AllOptionArgs, ErrorStream,
+		Succeeded, Info, Info) -->
 	{ prog_out__sym_name_to_string(ModuleName, ".", ModuleArg) },
 
 	globals__io_lookup_bool_option(verbose_commands, Verbose),
@@ -306,7 +328,9 @@
 	io__set_output_stream(ErrorStream, OldOutputStream),
 	( { ModuleTask = compile_to_target_code } ->
 		call_in_forked_process(call_mercury_compile_main([ModuleArg]),
-			invoke_mmc(ErrorStream, AllOptionArgs), Succeeded)
+			invoke_mmc(ErrorStream, ArgFileName,
+				AllOptionArgs ++ [ModuleArg]),
+			Succeeded)
 	;
 		call_mercury_compile_main([ModuleArg], Succeeded)
 	),
@@ -325,7 +349,7 @@
 		[]
 	).
 
-build_target_2(ModuleName, target_code_to_object_code(PIC),
+build_target_2(ModuleName, target_code_to_object_code(PIC), _,
 		Imports, _, ErrorStream, Succeeded, Info, Info) -->
 	globals__io_get_target(CompilationTarget),
 
@@ -336,7 +360,7 @@
 				ErrorStream, Imports),
 			Succeeded).
 
-build_target_2(ModuleName, foreign_code_to_object_code(PIC, Lang),
+build_target_2(ModuleName, foreign_code_to_object_code(PIC, Lang), _,
 		Imports, _, ErrorStream, Succeeded, Info, Info) -->
 	foreign_code_file(ModuleName, PIC, Lang, ForeignCodeFile),
 
@@ -347,7 +371,7 @@
 					Imports, ForeignCodeFile),
 			Succeeded).
 
-build_target_2(ModuleName, fact_table_code_to_object_code(PIC),
+build_target_2(ModuleName, fact_table_code_to_object_code(PIC), _,
 		Imports, _, ErrorStream, Succeeded, Info, Info) -->
 	list__map_foldl(fact_table_foreign_code_file(ModuleName, PIC),
 			Imports ^ fact_table_deps, FactTableForeignCodes),
@@ -474,15 +498,67 @@
 	{ Succeeded = ( Status = 0 -> yes ; no ) },
 	io__set_exit_status(Status0).
 
-:- pred invoke_mmc(io__output_stream::in, list(string)::in, bool::out,
-		io__state::di, io__state::uo) is det.
+:- pred invoke_mmc(io__output_stream::in, maybe(file_name)::in,
+	list(string)::in, bool::out, io__state::di, io__state::uo) is det.
+
+invoke_mmc(ErrorStream, MaybeArgFileName, Args, Succeeded) -->
+	io__progname("", ProgName),
+	( { ProgName = "" } ->
+		io__get_environment_var("MERCURY_COMPILER",
+			MaybeMercuryCompiler),
+		{ MaybeMercuryCompiler = yes(MercuryCompiler)
+		; MaybeMercuryCompiler = no, MercuryCompiler = "mmc"
+		}
+	;
+		{ MercuryCompiler = ProgName }
+	),
+
+	{ QuotedArgs = list__map(quote_arg, Args) },
 
-invoke_mmc(ErrorStream, Args, Succeeded) -->
-	{ CommandVerbosity = verbose }, % We've already written the command.
-	{ Command = string__join_list(" ",
-			["mmc" | list__map(quote_arg, Args)]) },
-	invoke_shell_command(ErrorStream, CommandVerbosity,
-		Command, Succeeded).
+	% Some operating systems (e.g. Windows) have shells with
+	% ludicrously short limits on the length of command lines,
+	% so we need to write the arguments to a file which will
+	% be read by the child mmc process.
+	% This code is only called if fork() doesn't work, so there's
+	% no point checking whether the shell actually has this
+	% limitation.
+	% The temporary file is created by the caller so that it will be
+	% removed by build_with_check_for_interrupt if an interrupt occurs.
+	{
+		MaybeArgFileName = yes(ArgFileName)
+	;
+		MaybeArgFileName = no,
+		error(
+		"make.module_target.invoke_mmc: argument file not created")
+	},
+		
+	io__open_output(ArgFileName, ArgFileOpenRes),
+	(
+		{ ArgFileOpenRes = ok(ArgFileStream) },
+		io__write_string(ArgFileStream, "MCFLAGS = "),
+		io__write_list(ArgFileStream, QuotedArgs, " ",
+			io__write_string),
+		io__nl(ArgFileStream),
+		io__close_output(ArgFileStream),
+
+		{ Command = string__join_list(" ",
+			[quote_arg(MercuryCompiler),
+				"--arg-file", quote_arg(ArgFileName)]) },
+			
+		% We've already written the command.
+		{ CommandVerbosity = verbose },
+		invoke_system_command(ErrorStream,
+			CommandVerbosity, Command, Succeeded)
+	;
+		{ ArgFileOpenRes = error(Error) },
+		{ Succeeded = no },
+		io__write_string("Error opening `"),
+		io__write_string(ArgFileName),
+		io__write_string("' for output: "),
+		io__write_string(io__error_message(Error)),
+		io__nl
+	),
+	io__remove_file(ArgFileName, _).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/make.program_target.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.program_target.m,v
retrieving revision 1.20
diff -u -u -r1.20 make.program_target.m
--- compiler/make.program_target.m	15 Mar 2003 03:08:56 -0000	1.20
+++ compiler/make.program_target.m	1 Aug 2003 09:14:07 -0000
@@ -220,11 +220,11 @@
 		Info0, Info) -->
 	globals__io_lookup_maybe_string_option(pre_link_command,
 		MaybePreLinkCommand),
-	( { MaybePreLinkCommand = yes(PreLinkCommand0) } ->
-		{ PreLinkCommand = substitute_user_command(PreLinkCommand0,
-			MainModuleName, set__to_sorted_list(AllModules)) },
-		invoke_shell_command(ErrorStream, verbose, PreLinkCommand,
-			PreLinkSucceeded)
+	( { MaybePreLinkCommand = yes(PreLinkCommand) } ->
+		make_all_module_command(PreLinkCommand, MainModuleName,
+			to_sorted_list(AllModules), CommandString),
+		invoke_system_command(ErrorStream, verbose,
+			CommandString, PreLinkSucceeded)
 	;
 		{ PreLinkSucceeded = yes }
 	),	
@@ -520,13 +520,22 @@
 		)
 	;
 		{ TargetType = install_library },
-		make_misc_target(MainModuleName - build_library,
-			LibSucceeded, Info3, Info4),
-		( { LibSucceeded = yes } ->
-			install_library(MainModuleName, Succeeded, Info4, Info)
+		globals__io_lookup_bool_option(make_implies_use_subdirs,
+			MakeImpliesUseSubdirs),
+		( { MakeImpliesUseSubdirs = no } ->
+			io__write_string("Error: library installation does not work with `--no-make-implies-use-subdirs'.\n"),
+			{ Info = Info3 },
+			{ Succeeded = no }
 		;
-		    { Info = Info4 },
-		    { Succeeded = no }
+			make_misc_target(MainModuleName - build_library,
+				LibSucceeded, Info3, Info4),
+			( { LibSucceeded = yes } ->
+				install_library(MainModuleName, Succeeded,
+					Info4, Info)
+			;
+			    { Info = Info4 },
+			    { Succeeded = no }
+			)
 		)
 	).
 
@@ -832,7 +841,7 @@
 	{ Command = string__join_list("	", list__map(quote_arg,
 			[InstallCommand, FileName, InstallDir])) },
 	io__output_stream(OutputStream),
-	invoke_shell_command(OutputStream, verbose, Command, Succeeded).
+	invoke_system_command(OutputStream, verbose, Command, Succeeded).
 
 :- pred make_install_dirs(bool::out, bool::out,
 		io__state::di, io__state::uo) is det.
@@ -845,8 +854,7 @@
 
 	{ IntsSubdir = LibDir/"ints"/"Mercury" },
 	make_directory(IntsSubdir, Result3),
-
-	{ Result4 = Result1 `and` Result2 `and` Result3 },
+	{ Results0 = [Result1, Result2, Result3] },
 
 	{ Subdirs = ["int0", "int", "int2", "int3",
 			"opt", "trans_opt", "module_dep"] },
@@ -854,14 +862,16 @@
 		Subdirs, LinkResults),
 	{ LinkResult = bool__and_list(LinkResults) },
 	( { LinkResult = yes } ->
-		{ Result = Result4 }
+		{ Results = Results0 }
 	;
 		list__map_foldl(
 		    (pred(Ext::in, MkDirResult::out, di, uo) is det -->
-		    	make_directory(IntsSubdir/(Ext ++ "s"), MkDirResult)
+		    	make_directory(IntsSubdir/(Ext ++ "s"),
+				MkDirResult)
 		    ), Subdirs, MkDirResults),
-		{ Result = bool__and_list([Result4 | MkDirResults]) }
-	).
+		{ Results = Results0 ++ MkDirResults }
+	),
+	print_mkdir_errors(Results, Result).
 
 :- pred make_grade_install_dirs(string::in, bool::out, bool::out,
 		io__state::di, io__state::uo) is det.
@@ -877,30 +887,41 @@
 	{ GradeIncSubdir = LibDir/"lib"/Grade/FullArch/"inc"/"Mercury" },
 	make_directory(GradeIncSubdir, Result2),
 
-	{ Result3 = Result1 `and` Result2 },
+	{ Results0 = [Result1, Result2] },
 
 	make_install_symlink(GradeIncSubdir, "mih", LinkResult0),
 	list__map_foldl(make_install_symlink(GradeIntsSubdir),
 		["opt", "trans_opt"], LinkResults),
 	{ LinkResult = bool__and_list([LinkResult0 | LinkResults]) },
 	( { LinkResult = yes } ->
-		{ Result = Result3 }
+		{ Results = Results0 }
 	;
 		make_directory(GradeIncSubdir/"mih", Result4),
-		list__map_foldl(
-		    (pred(Ext::in, MkDirResult::out, di, uo) is det -->
-		    	make_directory(GradeIntsSubdir/(Ext ++ "s"),
-				MkDirResult)
-		    ), ["opt", "trans_opt"], MkDirResults),
-		{ Result = bool__and_list([Result3, Result4 | MkDirResults]) }
-	).
+		make_directory(GradeIntsSubdir/"opts", Result5),
+		make_directory(GradeIntsSubdir/"trans_opts",
+			Result6),
+		{ Results = [Result4, Result5, Result6 | Results0] }
+	),
+	print_mkdir_errors(Results, Result).
+
+:- pred print_mkdir_errors(list(io__res)::in, bool::out,
+		io__state::di, io__state::uo) is det.
+
+print_mkdir_errors([], yes) --> [].
+print_mkdir_errors([ok | Rest], Succeeded) -->
+	print_mkdir_errors(Rest, Succeeded).
+print_mkdir_errors([error(Error) | Rest], no) -->
+	io__write_string("Error creating installation directories: "),
+	io__write_string(io__error_message(Error)),
+	io__nl,
+	print_mkdir_errors(Rest, _).
 
 :- pred make_install_symlink(string::in, string::in, bool::out,
 		io__state::di, io__state::uo) is det.
 
-make_install_symlink(Subdir, Ext, Result) -->
+make_install_symlink(Subdir, Ext, Succeeded) -->
 	{ LinkName = Subdir/(Ext ++ "s") },
-	make_symlink("..", LinkName, Result).
+	maybe_make_symlink("..", LinkName, Succeeded).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/make.util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.util.m,v
retrieving revision 1.15
diff -u -u -r1.15 make.util.m
--- compiler/make.util.m	15 Mar 2003 03:08:56 -0000	1.15
+++ compiler/make.util.m	31 Jul 2003 15:02:50 -0000
@@ -330,16 +330,24 @@
 		{ Succeeded = no }
 	;
 		{ OptionsResult = yes(ModuleOptionArgs) }, 
+		globals__io_lookup_bool_option(make_implies_use_subdirs,
+			MakeImpliesUseSubdirs),
 		globals__io_get_globals(Globals),
 
-		% --invoked-by-mmc-make disables reading DEFAULT_MCFLAGS
-		% from the environment (DEFAULT_MCFLAGS is included in
-		% OptionArgs) and generation of `.d' files.
+		% --invoked-by-mmc-make disables reading the options file.
+		% (DEFAULT_MCFLAGS is included in OptionArgs) and generation
+		% of `.d' files.
 		% --use-subdirs is needed because the code to install
 		% libraries uses `--use-grade-subdirs' and assumes the
 		% interface files were built with `--use-subdirs'.
 		{ InvokedByMmcMake = yes ->
-			UseSubdirs = ["--use-subdirs"],
+			(
+				MakeImpliesUseSubdirs = yes,
+				UseSubdirs = ["--use-subdirs"]
+			;
+				MakeImpliesUseSubdirs = no,
+				UseSubdirs = []
+			),
 			InvokedByMake = ["--invoked-by-mmc-make"]
 		;
 			UseSubdirs = [],
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.288
diff -u -u -r1.288 mercury_compile.m
--- compiler/mercury_compile.m	23 Jul 2003 03:38:10 -0000	1.288
+++ compiler/mercury_compile.m	31 Jul 2003 15:04:44 -0000
@@ -168,18 +168,35 @@
 %-----------------------------------------------------------------------------%
 
 real_main -->
-	gc_init,
+    gc_init,
 
          % All messages go to stderr
     io__stderr_stream(StdErr),
     io__set_output_stream(StdErr, _),
     io__command_line_arguments(Args0),
 
-    ( { Args0 = ["--invoked-by-mmc-make" | _] } ->
-        % All the configuration options were passed
-        % on the command line.
-        { process_options(Args0, OptionArgs, NonOptionArgs, _) },
-        { MaybeMCFlags = yes([]) },
+    ( { Args0 = ["--arg-file", ArgFile] } ->
+	%
+	% All the configuration and options file options
+	% are passed in the given file, which is created
+	% by the parent `mmc --make' process.
+	%
+
+	% read_args_file may attempt to look up options,
+	% so we need to initialize the globals..
+	handle_options([], _, _, _, _),
+
+	options_file__read_args_file(ArgFile, MaybeArgs1),
+	{
+		MaybeArgs1 = yes(Args1),
+        	process_options(Args1, OptionArgs, NonOptionArgs, _),
+        	MaybeMCFlags = yes([])
+	;
+		MaybeArgs1 = no,
+		OptionArgs = [],
+		NonOptionArgs = [],
+        	MaybeMCFlags = yes([])
+	},
         { Variables = options_variables_init },
 	{ Link = no }
     ;
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.277
diff -u -u -r1.277 modules.m
--- compiler/modules.m	25 Jul 2003 02:27:22 -0000	1.277
+++ compiler/modules.m	30 Jul 2003 14:27:55 -0000
@@ -693,22 +693,12 @@
 :- pred update_interface(file_name, io__state, io__state).
 :- mode update_interface(in, di, uo) is det.
 
-	% make_directory(Dir, Succeeded)
+	% maybe_make_symlink(TargetFile, LinkName, Result).
 	%
-	% Make the directory Dir and all its parents.
-	% XXX This belongs in the standard library.
-:- pred make_directory(dir_name, bool, io__state, io__state).
-:- mode make_directory(in, out, di, uo) is det.
-
-:- pred make_directory(dir_name, io__state, io__state).
-:- mode make_directory(in, di, uo) is det.
-
-	% make_symlink(LinkTarget, LinkName, Succeeded)
-	%
-	% Make LinkName a symlink pointing to LinkTarget.
-	% XXX This belongs in the standard library.
-:- pred make_symlink(file_name, file_name, bool, io__state, io__state).
-:- mode make_symlink(in, in, out, di, uo) is det.
+	% If `--use-symlinks' is set, attempt to make LinkName a
+	% symlink pointing to LinkTarget.
+:- pred maybe_make_symlink(file_name, file_name, bool, io__state, io__state).
+:- mode maybe_make_symlink(in, in, out, di, uo) is det.
 
 	% copy_file(Source, Destination, Succeeded).
 	%
@@ -719,7 +709,8 @@
 	% make_symlink_or_copy_file(LinkTarget, LinkName, Succeeded).
 	%
 	% Attempt to make LinkName a symlink pointing to LinkTarget,
-	% copying LinkTarget to LinkName if that fails.
+	% copying LinkTarget to LinkName if that fails (or if
+	% `--use-symlinks' is not set).
 :- pred make_symlink_or_copy_file(file_name, file_name,
 		bool, io__state, io__state).
 :- mode make_symlink_or_copy_file(in, in, out, di, uo) is det.
@@ -1096,29 +1087,15 @@
 module_name_to_make_var_name(ModuleName, MakeVarName) :-
 	prog_out__sym_name_to_string(ModuleName, ".", MakeVarName).
 
-make_directory(DirName) -->
-	modules__make_directory(DirName, _Result).
-
-make_directory(DirName, Result) -->
-	( { dir__this_directory(DirName) } ->
-		{ Result = yes }
-	;
-		{ string__format("[ -d %s ] || mkdir -p %s",
-			[s(DirName), s(DirName)], Command) },
-		io__output_stream(ErrorStream),
-		invoke_shell_command(ErrorStream, verbose, Command, Result)
-	).
-
-make_symlink(LinkTarget, LinkName, Result) -->
-	io__output_stream(ErrorStream),
-	globals__io_lookup_bool_option(use_symlinks, SymLinks),
+maybe_make_symlink(LinkTarget, LinkName, Result) -->
+	globals__io_lookup_bool_option(use_symlinks, UseSymLinks),
 	(
-		{ SymLinks = yes },
-		{ string__format("rm -f %s && ln -s %s %s",
-			[s(LinkName), s(LinkTarget), s(LinkName)], Command) },
-		invoke_shell_command(ErrorStream, verbose, Command, Result)
+		{ UseSymLinks = yes },
+		io__remove_file(LinkName, _),
+		io__make_symlink(LinkTarget, LinkName, LinkResult),
+		{ Result = ( if LinkResult = ok then yes else no ) }
 	;
-		{ SymLinks = no },
+		{ UseSymLinks = no },
 		{ Result = no }
 	).
 
@@ -1148,28 +1125,32 @@
 	).
 
 make_symlink_or_copy_file(SourceFileName, DestinationFileName, Succeeded) -->
-	make_symlink(SourceFileName, DestinationFileName, SymlinkSucceeded),
-	( { SymlinkSucceeded = yes } ->
+	globals__io_lookup_bool_option(use_symlinks, UseSymLinks),
+	(
+		{ UseSymLinks = yes },
+		{ LinkOrCopy = "linking" },
+		io__make_symlink(SourceFileName, DestinationFileName, Result)
+	;
+		{ UseSymLinks = no },
+		{ LinkOrCopy = "copying" },
+		copy_file(SourceFileName, DestinationFileName, Result)
+	),
+	( 
+		{ Result = ok },
 		{ Succeeded = yes }
 	;
-		copy_file(SourceFileName, DestinationFileName,
-			CopyRes),
-		( 
-			{ CopyRes = ok },
-			{ Succeeded = yes }
-		;
-			{ CopyRes = error(CopyError) },
-			{ Succeeded = no },
-			io__progname_base("mercury_compile",
-				ProgName),
-			io__write_string(ProgName),
-			io__write_string(": error copying `"),
-			io__write_string(SourceFileName),
-			io__write_string("' to `"),
-			io__write_string(DestinationFileName),
-			io__write_string("': "),
-			io__write_string(io__error_message(CopyError))
-		)
+		{ Result = error(Error) },
+		{ Succeeded = no },
+		io__progname_base("mercury_compile", ProgName),
+		io__write_string(ProgName),
+		io__write_string(": error "),
+		io__write_string(LinkOrCopy),
+		io__write_string(" `"),
+		io__write_string(SourceFileName),
+		io__write_string("' to `"),
+		io__write_string(DestinationFileName),
+		io__write_string("': "),
+		io__write_string(io__error_message(Error))
 	).
 
 :- pred make_file_name(dir_name, bool, bool, file_name, string,
@@ -1209,7 +1190,7 @@
 		DirName = "Mercury"/SubDirName
 	},
 	( { MkDir = yes } ->
-		make_directory(DirName)
+		make_directory(DirName, _)
 	;
 		[]
 	),
@@ -1685,9 +1666,7 @@
 	globals__io_set_option(line_numbers, bool(LineNumbers)),
 	update_interface(OutputFileName).
 
-		% invoke the shell script `mercury_update_interface'
-		% to update <Module>.int from <Module>.int.tmp if
-		% necessary
+		% update <Module>.int from <Module>.int.tmp if necessary
 
 update_interface(OutputFileName) -->
 	update_interface(OutputFileName, Succeeded),
@@ -1700,14 +1679,128 @@
 update_interface(OutputFileName, Succeeded) -->
 	globals__io_lookup_bool_option(verbose, Verbose),
 	maybe_write_string(Verbose, "% Updating interface:\n"),
-	( { Verbose = yes } ->
-		{ Command = "mercury_update_interface -v " }
+	{ TmpOutputFileName = OutputFileName ++ ".tmp" },
+	io__open_binary_input(OutputFileName, OutputFileRes),
+	( 
+		{ OutputFileRes = ok(OutputFileStream) },
+		io__open_binary_input(TmpOutputFileName, TmpOutputFileRes),
+		(
+			{ TmpOutputFileRes = ok(TmpOutputFileStream) },	
+			binary_input_stream_cmp(OutputFileStream,
+				TmpOutputFileStream, FilesDiffer),
+			io__close_binary_input(OutputFileStream),
+			io__close_binary_input(TmpOutputFileStream),
+			(
+				{ FilesDiffer = ok(ok(no)) },
+				{ Succeeded = yes },
+				maybe_write_string(Verbose, "% "),
+				maybe_write_string(Verbose, OutputFileName),
+				maybe_write_string(Verbose,
+						"' has not changed.\n"),
+				io__remove_file(TmpOutputFileName, _)
+			;
+				{ FilesDiffer = ok(ok(yes)) },
+				update_interface_create_file("CHANGED",
+					OutputFileName, TmpOutputFileName,
+					Succeeded)
+			;
+				{ FilesDiffer = ok(error(TmpFileError)) },
+				{ Succeeded = no },
+				io__write_string("Error reading `"),
+				io__write_string(TmpOutputFileName),
+				io__write_string("': "),
+				io__write_string(
+					io__error_message(TmpFileError)),
+				io__nl
+			;
+				{ FilesDiffer = error(_, _) },
+				update_interface_create_file("been CREATED",
+					OutputFileName, TmpOutputFileName,
+					Succeeded)
+			)
+		;
+
+			{ TmpOutputFileRes = error(TmpOutputFileError) },
+			{ Succeeded = no },
+			io__close_binary_input(OutputFileStream),
+			io__write_string("Error creating `"),
+			io__write_string(OutputFileName),
+			io__write_string("': "),
+			io__write_string(
+				io__error_message(TmpOutputFileError)),
+			io__nl
+		)
 	;
-		{ Command = "mercury_update_interface " }
+		{ OutputFileRes = error(_) },
+		update_interface_create_file("been CREATED", OutputFileName,
+			TmpOutputFileName, Succeeded)
+	).
+
+:- pred binary_input_stream_cmp(io__binary_input_stream::in,
+	io__binary_input_stream::in, io__maybe_partial_res(io__res(bool))::out,
+	io__state::di, io__state::uo) is det.
+
+binary_input_stream_cmp(OutputFileStream, TmpOutputFileStream, FilesDiffer) -->
+    io__binary_input_stream_foldl2_io_maybe_stop(OutputFileStream,
+        (pred(Byte::in, Continue::out, _::in, Differ::out, di, uo) is det -->
+            io__read_byte(TmpOutputFileStream, TmpByteResult),
+            {
+                TmpByteResult = ok(TmpByte),
+                ( TmpByte = Byte ->
+                    Differ = ok(no),
+                    Continue = yes    
+                ;
+                    Differ = ok(yes),
+                    Continue = no
+                )
+            ;
+                TmpByteResult = eof,
+                Differ = ok(yes),
+                Continue = no
+            ;
+                TmpByteResult = error(TmpByteError),
+                Differ = error(TmpByteError) `with_type` io__res(bool),
+                Continue = no
+            }
+        ),
+        ok(no), FilesDiffer0),
+
+    % Check whether there is anything left in TmpOutputFileStream
+    ( { FilesDiffer0 = ok(ok(no)) } ->
+        io__read_byte(TmpOutputFileStream, TmpByteResult2),
+        { TmpByteResult2 = ok(_), FilesDiffer = ok(ok(yes))
+        ; TmpByteResult2 = eof, FilesDiffer = FilesDiffer0
+        ; TmpByteResult2 = error(Error), FilesDiffer = ok(error(Error))
+        }
+    ;
+        { FilesDiffer = FilesDiffer0 }
+    ).
+
+:- pred update_interface_create_file(string::in, string::in, string::in,
+		bool::out, io__state::di, io__state::uo) is det.
+
+update_interface_create_file(Msg, OutputFileName,
+			TmpOutputFileName, Succeeded) -->
+	globals__io_lookup_bool_option(verbose, Verbose),
+	maybe_write_string(Verbose, "% `"),
+	maybe_write_string(Verbose, OutputFileName),
+	maybe_write_string(Verbose, "' has "),
+	maybe_write_string(Verbose, Msg),
+	maybe_write_string(Verbose, ".\n"),
+	copy_file(TmpOutputFileName, OutputFileName, MoveRes),
+	(
+		{ MoveRes = ok },
+		{ Succeeded = yes }
+	;
+		{ MoveRes = error(MoveError) },
+		{ Succeeded = no },
+		io__write_string("Error creating `"),
+		io__write_string(OutputFileName),
+		io__write_string("': "),
+		io__write_string(io__error_message(MoveError)),
+		io__nl
 	),
-	{ string__append(Command, OutputFileName, ShellCommand) },
-	io__output_stream(OutputStream),
-	invoke_shell_command(OutputStream, verbose, ShellCommand, Succeeded).
+	io__remove_file(TmpOutputFileName, _).
 
 %-----------------------------------------------------------------------------%
 
@@ -2217,8 +2310,8 @@
 	% temporary name, and then rename it to the desired name
 	% when we've finished.
 	%
-	{ dir__dirname(DependencyFileName, DirName) },
-	io__make_temp(DirName, "tmp_d", TmpDependencyFileName),
+	io__make_temp(dir__dirname(DependencyFileName),
+		"tmp_d", TmpDependencyFileName),
 	maybe_write_string(Verbose, "% Writing auto-dependency file `"),
 	maybe_write_string(Verbose, DependencyFileName),
 	maybe_write_string(Verbose, "'..."),
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.414
diff -u -u -r1.414 options.m
--- compiler/options.m	23 Jul 2003 03:38:11 -0000	1.414
+++ compiler/options.m	1 Aug 2003 16:02:11 -0000
@@ -610,14 +610,20 @@
 		;	shared_libs
 		;	math_lib
 		;	readline_libs
+		;	linker_opt_separator
 		;	linker_thread_flags
 		;	shlib_linker_thread_flags
 		;	linker_static_flags
 		;	linker_strip_flag
+		;	linker_link_lib_flag
+		;	linker_link_lib_suffix
+		;	shlib_linker_link_lib_flag
+		;	shlib_linker_link_lib_suffix
 		;	linker_debug_flags
 		;	shlib_linker_debug_flags
 		;	linker_trace_flags
 		;	shlib_linker_trace_flags
+		;	linker_path_flag
 		;	linker_rpath_flag
 		;	linker_rpath_separator
 		;	shlib_linker_rpath_flag
@@ -627,6 +633,7 @@
 
 	% Build system options
 		;	make
+		;	make_implies_use_subdirs
 		;	keep_going
 		;	rebuild
 		;	invoked_by_mmc_make
@@ -1180,8 +1187,8 @@
 	mercury_library_directories -	accumulating([]),
 	mercury_library_special -	string_special,
 	mercury_libraries -		accumulating([]),
-					% The mmc script will set the default
-					% standard library directory.
+					% The Mercury.config file will set the
+					% default standard library directory.
 	mercury_standard_library_directory - maybe_string(no),
 	mercury_standard_library_directory_special - maybe_string_special,
 	init_file_directories -		accumulating([]),
@@ -1219,6 +1226,7 @@
 	shared_libs -			string(""),
 	math_lib -			string(""),
 	readline_libs -			string(""),
+	linker_opt_separator -		string(""),
 	linker_debug_flags -		string("-g"),
 	shlib_linker_debug_flags -	string("-g"),
 	linker_trace_flags -		string("-g"),
@@ -1227,6 +1235,11 @@
 	shlib_linker_thread_flags -	string(""),
 	linker_static_flags -		string("-static"),
 	linker_strip_flag -		string("-s"),
+	linker_link_lib_flag -		string("-l"),
+	linker_link_lib_suffix -	string(""),
+	shlib_linker_link_lib_flag -	string("-l"),
+	shlib_linker_link_lib_suffix -	string(""),
+	linker_path_flag -		string("-L"),
 	linker_rpath_flag -		string("-Wl,-rpath"),
 	linker_rpath_separator -	string(" -Wl,-rpath"),
 	shlib_linker_rpath_flag -	string("-Wl,-rpath"),
@@ -1237,6 +1250,7 @@
 option_defaults_2(build_system_option, [
 		% Build System Options
 	make			-	bool(no),
+	make_implies_use_subdirs -	bool(yes),
 	keep_going		-	bool(no),
 	rebuild			-	bool(no),
 	invoked_by_mmc_make	-	bool(no),
@@ -1876,6 +1890,7 @@
 long_option("shared-libs",		shared_libs).
 long_option("math-lib",			math_lib).
 long_option("readline-libs",		readline_libs).
+long_option("linker-opt-separator",	linker_opt_separator).
 long_option("linker-debug-flags",  	linker_debug_flags).
 long_option("shlib-linker-debug-flags",	shlib_linker_debug_flags).
 long_option("linker-trace-flags",  	linker_trace_flags).
@@ -1884,6 +1899,11 @@
 long_option("shlib-linker-thread-flags", shlib_linker_thread_flags).
 long_option("linker-static-flags",	linker_static_flags).
 long_option("linker-strip-flag",	linker_strip_flag).
+long_option("linker-link-lib-flag",	linker_link_lib_flag).
+long_option("linker-link-lib-suffix",	linker_link_lib_suffix).
+long_option("shlib-linker-link-lib-flag", shlib_linker_link_lib_flag).
+long_option("shlib-linker-link-lib-suffix", shlib_linker_link_lib_suffix).
+long_option("linker-path-flag",		linker_path_flag).
 long_option("linker-rpath-flag",	linker_rpath_flag).
 long_option("linker-rpath-separator",	linker_rpath_separator).
 long_option("shlib-linker-rpath-flag",	shlib_linker_rpath_flag).
@@ -1893,6 +1913,7 @@
 
 % build system options
 long_option("make",			make).
+long_option("make-implies-use-subdirs",	make_implies_use_subdirs).
 long_option("keep-going",		keep_going).
 long_option("rebuild",			rebuild).
 long_option("invoked-by-mmc-make",	invoked_by_mmc_make).
@@ -2364,17 +2385,6 @@
 	->
 		Arg = """"""
 	;
-		list__member(Char, ArgList),
-		\+ ( char__is_alnum_or_underscore(Char)
-		; Char = ('-')
-		; Char = ('/')
-		; Char = ('.')
-		; Char = (',')
-		; Char = (':')
-		)
-	->
-		Arg = """" ++ string__from_char_list(ArgList) ++ """"
-	;
 		Arg = string__from_char_list(ArgList)
 	).
 
@@ -2384,15 +2394,24 @@
 quote_arg_2([Char | Chars0]) = Chars :-
 	Chars1 = quote_arg_2(Chars0),
 	( quote_char(Char) ->
-		Chars = [('\\'), Char | Chars1]
+		% We want whitespace characters within an argument to not be
+		% treated as whitespace when splitting the command line
+		% into words. \newline is still treated as whitespace,
+		% and not all shells will understand "\n".
+		% Newlines and tabs within a word don't really make
+		% sense, so just convert them to spaces.
+		QuoteChar = ( char__is_whitespace(Char) -> ' ' ; Char ),
+		Chars = [('\\'), QuoteChar | Chars1]
 	;
-		Chars = [Char | Chars1]	
-	).	
-
+		Chars = [Char | Chars1]
+	).
 
 :- pred quote_char(char::in) is semidet.
 
-quote_char('\\').
+quote_char(' ').
+quote_char('\n').
+quote_char('\t').
+quote_char('\\') :- \+ dir__use_windows_paths.
 quote_char('"').
 quote_char('`').
 quote_char('$').
@@ -3889,14 +3908,21 @@
 		% --link-executable-command, --link-shared-lib-command,
 		% --mkinit-command, --demangle-command, --trace-libs,
 		% --thread-libs, --shared-libs, --math-lib, --readline-libs,
-		% linker-thread-flags, --shlib-linker-thread-flags,
+		% --linker-opt-separator,
+		% --linker-debug-flags, --shlib-linker-debug-flags,
+		% --linker-trace-flags, --shlib-linker-trace-flags,
+		% --linker-thread-flags, --shlib-linker-thread-flags,
 		% --linker-static-flags, --linker-strip-flag,
+		% --linker-link-lib-flag, --linker-link-lib-suffix,
+		% --shlib-linker-link-lib-flag, --shlib-linker-link-lib-suffix,
+		% --linker-path-flag, --linker-link-with-lib-flag,
 		% --linker-rpath-flag, --linker-rpath-separator,
+		% --shlib-linker-link-with-lib-flag,
 		% --shlib-linker-rpath-flag, --shlib-linker-rpath-separator,
 		% --linker-allow-undefined-flag and
 		% --linker-error-undefined-flag,
-		% options are are reserved for use by the `mmc' script;
-		% they are deliberately not documented.
+		% options are are reserved for use by the `Mercury.config'
+		% file; they are deliberately not documented.
 	]).
 
 :- pred options_help_build_system(io__state::di, io__state::uo) is det.
@@ -3922,16 +3948,17 @@
 		"\tSpecify a command to run before linking with `mmc --make'.",
 		"\tThis can be used to compile C source files which rely on",
 		"\theader files generated by the Mercury compiler.",
-		"\tOccurrences of `@' in the command will be replaced with",
-		"\tthe name of the main module with `.' as the module",
-		"\tqualifier. Occurrences of `%' in the command will be",
-		"\treplaced with the list of modules making up the library.",
-		"\tOccurrences of `@@' and `%%' will be replaced with `@'",
-		"\tand `%' respectively.",
+		"\tThe command will be passed the names of all of the source",
+		"\tfiles in the program or library, with the source file",
+		"\tcontaining the main module given first.",
+
 		"--extra-init-command <command>",
 		"\tSpecify a command to produce extra entries in the `.init'",
-		"\tfile for a library. Occurrences of `@' and `%' in the command",
-		"\tare substituted as for the `--pre-link-command' option.",
+		"\tfile for a library.",
+		"\tThe command will be passed the names of all of the source",
+		"\tfiles in the program or library, with the source file",
+		"\tcontaining the main module given first.",
+
 		"--install-prefix <dir>",
 		"\tThe directory under which to install Mercury libraries.",
 		
@@ -3983,7 +4010,13 @@
 		"\tExecutables and libraries will be symlinked or copied into",
 		"\tthe current directory.",
 		"\t`--use-grade-subdirs' does not work with Mmake (it does",
-		"\twork with `mmc --make')."
+		"\twork with `mmc --make').",
+
+		"--no-make-implies-use-subdirs",
+		"\tNormally, `--make' implies `--use-subdirs'.",
+		"\tThis option disables that behaviour.",
+		"\tLibrary installation does not work with",
+		"\t--no-make-implies-use-subdirs."
 	]).
 
 :- pred options_help_misc(io__state::di, io__state::uo) is det.
@@ -4011,7 +4044,7 @@
 		"\tdefaults to the string ""guest""."
 
 		% The `--fullarch' option is reserved for
-		% use by the mmc script.
+		% use by the `Mercury.config' file.
 	]).
 
 :- pred write_tabbed_lines(list(string), io__state, io__state).
Index: compiler/options_file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options_file.m,v
retrieving revision 1.19
diff -u -u -r1.19 options_file.m
--- compiler/options_file.m	21 Jul 2003 14:08:39 -0000	1.19
+++ compiler/options_file.m	30 Jul 2003 14:27:55 -0000
@@ -21,11 +21,21 @@
 
 :- func options_variables_init = options_variables.
 
-	% Read a single options file.  No searching will be done.
+	% Read a single options file, without searching
+	% --options-search-directories.
 	% This is used to read the configuration file.
 :- pred read_options_file(file_name::in, options_variables::in,
 	maybe(options_variables)::out, io__state::di, io__state::uo) is det.
 
+	% Read a single options file.  No searching will be done.
+	% The result is the value of the variable MCFLAGS obtained
+	% from the file, ignoring settings in the environment.
+	% This is used to pass arguments to child mmc processes
+	% without exceeding command line limits on crappy operating
+	% systems.
+:- pred read_args_file(file_name::in, maybe(list(string))::out,
+	io__state::di, io__state::uo) is det.
+
 	% Read all options files specified by `--options-file' options.
 :- pred read_options_files(options_variables::in,
 		maybe(options_variables)::out,
@@ -85,6 +95,35 @@
 
 options_variables_init = map__init.
 
+read_args_file(OptionsFile, MaybeMCFlags) -->
+	read_options_file(OptionsFile,
+		options_variables_init, MaybeVariables),	
+	(
+		{ MaybeVariables = yes(Variables) },
+		% Ignore settings in the environment -- the parent
+		% mmc process will have included those in the file.
+		lookup_variable_words(no, Variables,
+			"MCFLAGS", FlagsResult),
+		(
+			{ FlagsResult = set(MCFlags) },
+			{ MaybeMCFlags = yes(MCFlags) }
+		;	
+			{ FlagsResult = unset },
+			io__write_string(
+"mercury_compile: internal error: arguments file does not set MCFLAGS.\n"),
+			{ MaybeMCFlags = no }
+		;
+			{ FlagsResult = error(Msg) },
+			{ MaybeMCFlags = no },
+			io__write_string(Msg),
+			io__nl
+		)
+	;
+		{ MaybeVariables = no },
+		{ MaybeMCFlags = no }
+	).
+	
+
 read_options_file(OptionsFile, Variables0, MaybeVariables) -->
 	promise_only_solution_io(
 	    (pred(R::out, di, uo) is cc_multi -->
@@ -120,10 +159,10 @@
 			    (pred(OptionsFile::in, Vars0::in, Vars::out,
 					di, uo) is det -->
 				{ OptionsFile = "Mercury.options" ->
-					ErrorIfNotExist = error,
+					ErrorIfNotExist = no_error,
 					Search = no_search
 				;
-					ErrorIfNotExist = no_error,
+					ErrorIfNotExist = error,
 					Search = search
 				},
 				read_options_file(ErrorIfNotExist, Search, no,
@@ -162,27 +201,30 @@
 		maybe(dir_name)::in, string::in, options_variables::in,
 		options_variables::out, io__state::di, io__state::uo) is det.
 
-read_options_file(ErrorIfNotExist0, Search, MaybeDirName, OptionsFile0,
+read_options_file(ErrorIfNotExist, Search, MaybeDirName, OptionsFile0,
 		Variables0, Variables) -->
     ( { OptionsFile0 = "-" } ->
 	% Read from standard input.
 	debug_msg(
 		(pred(di, uo) is det -->
-			io__write_string("Reading options file from stdin.\n")
+			io__write_string("Reading options file from stdin...")
 		)),
-	read_options_lines(dir__this_directory, Variables0, Variables)
+	read_options_lines(dir__this_directory, Variables0, Variables),
+	debug_msg(
+		(pred(di, uo) is det -->
+			io__write_string("done.\n")
+		))
     ;
-	( { OptionsFile0 = "Mercury.options" } ->
-		% Don't complain if the "Mercury.options"
-		% file doesn't exist.
-		{ ErrorIfNotExist = no_error },
-		{ SearchDirs = [dir__this_directory] }
-	; { Search = search } ->
-		{ ErrorIfNotExist = ErrorIfNotExist0 },
+	debug_msg(
+		(pred(di, uo) is det -->
+			io__write_string("Reading options file "),
+			io__write_string(OptionsFile0),
+			io__write_string("...")
+		)),
+	( { Search = search } ->
 		globals__io_lookup_accumulating_option(
 			options_search_directories, SearchDirs)
 	;
-		{ ErrorIfNotExist = ErrorIfNotExist0 },
 		{ SearchDirs = [dir__this_directory] }
 	),
 	( { dir__split_name(OptionsFile0, OptionsDir, OptionsFile) } ->
@@ -216,8 +258,7 @@
 			)),
 
 		read_options_lines(FoundDir, Variables0, Variables),
-		io__input_stream(OptionsStream),
-		io__set_input_stream(OldInputStream, _),
+		io__set_input_stream(OldInputStream, OptionsStream),
 		io__close_input(OptionsStream)
 	;
 		{ MaybeDir = error(_) },
@@ -236,7 +277,11 @@
 		;
 			[]
 		)
-	)
+	),
+	debug_msg(
+		(pred(di, uo) is det -->
+			io__write_string("done.\n")
+		))
     ).
 
 :- func maybe_add_path_name(dir_name, file_name) = file_name.
@@ -343,7 +388,7 @@
 	    (
 		{ MaybeChar2 = yes(Char2) },
 		( { Char2 = '\n' } ->
-		    read_options_line_2(FoundEOF, ['\n' | Chars0], Chars)
+		    read_options_line_2(FoundEOF, [' ' | Chars0], Chars)
 		;
 		    read_options_line_2(FoundEOF,
 		    		[Char2, Char | Chars0], Chars)
@@ -1028,7 +1073,20 @@
 	io__state::di, io__state::uo) is det.
 
 lookup_variable_words(Vars, VarName, Result) -->
-	io__get_environment_var(VarName, MaybeEnvValue),
+	lookup_variable_words(yes, Vars, VarName, Result).
+
+:- pred lookup_variable_words(bool::in, options_variables::in,
+	options_variable::in, variable_result(list(string))::out,
+	io__state::di, io__state::uo) is det.
+
+lookup_variable_words(LookupEnv, Vars, VarName, Result) -->
+	(
+		{ LookupEnv = yes },
+		io__get_environment_var(VarName, MaybeEnvValue)
+	;
+		{ LookupEnv = no },
+		{ MaybeEnvValue = no }
+	),
 	( { MaybeEnvValue = yes(EnvValue) } ->
 		{ SplitResult = checked_split_into_words(
 			string__to_char_list(EnvValue)) },
Index: compiler/passes_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/passes_aux.m,v
retrieving revision 1.55
diff -u -u -r1.55 passes_aux.m
--- compiler/passes_aux.m	26 May 2003 09:00:04 -0000	1.55
+++ compiler/passes_aux.m	31 Jul 2003 14:01:37 -0000
@@ -199,6 +199,9 @@
 	% Invoke a shell script.
 	% Both standard and error output will go to the
 	% specified output stream.
+	% XXX Use of this predicate should be avoided -- it requires
+	% a Unix shell to be present, so it won't work properly 
+	% with native Windows.
 :- pred invoke_shell_command(io__output_stream::in,
 	command_verbosity::in, string::in, bool::out,
 	io__state::di, io__state::uo) is det.
@@ -210,6 +213,9 @@
 	% Both standard and error output will go to the
 	% specified output stream after being piped through
 	% `ProcessOutput'.
+	% XXX Use of this predicate should be avoided -- it requires
+	% a Unix shell to be present, so it won't work properly 
+	% with native Windows.
 :- pred invoke_shell_command(io__output_stream::in,
 	command_verbosity::in, string::in, maybe(string)::in, bool::out,
 	io__state::di, io__state::uo) is det.
@@ -506,6 +512,8 @@
 
 invoke_system_command(ErrorStream, Verbosity, Command,
 		MaybeProcessOutput, Succeeded) -->
+	% This predicate shouldn't alter the exit status of mercury_compile.
+	io__get_exit_status(OldStatus),
 	globals__io_lookup_bool_option(verbose, Verbose),
 	(
 		{ Verbosity = verbose },
@@ -629,7 +637,8 @@
 		report_error(ErrorStream, "error opening command output: "
 				++ io__error_message(TmpFileError))
 	),
-	io__remove_file(ProcessedTmpFile, _).
+	io__remove_file(ProcessedTmpFile, _),
+	io__set_exit_status(OldStatus).
 
 make_command_string(String0, QuoteType, String) :-
 	( use_win32 ->
Index: compiler/process_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/process_util.m,v
retrieving revision 1.10
diff -u -u -r1.10 process_util.m
--- compiler/process_util.m	15 Mar 2003 03:09:06 -0000	1.10
+++ compiler/process_util.m	31 Jul 2003 15:14:11 -0000
@@ -49,6 +49,9 @@
 :- type io_pred == pred(bool, io__state, io__state).
 :- inst io_pred == (pred(out, di, uo) is det).
 
+	% Does fork() work on the current platform.
+:- pred can_fork is semidet.
+
 	% call_in_forked_process(P, AltP, Succeeded)
 	%
 	% Execute `P' in a separate process.
@@ -260,7 +263,7 @@
 	call_in_forked_process(P, P, Success).
 
 call_in_forked_process(P, AltP, Success) -->
-	( { can_fork(1) } ->
+	( { can_fork } ->
 		call_in_forked_process_2(P, ForkStatus, CallStatus),
 		{ ForkStatus = 1 ->
 			Success = no
@@ -273,12 +276,9 @@
 		AltP(Success)
 	).
 
-	% Dummy argument to work around bug mixing Mercury and foreign clauses.
-:- pred can_fork(T::unused) is semidet.
-
-can_fork(_::unused) :- semidet_fail.
+can_fork :- semidet_fail.
 
-:- pragma foreign_proc("C", can_fork(_T::unused),
+:- pragma foreign_proc("C", can_fork,
 		[will_not_call_mercury, thread_safe, promise_pure],
 "
 #ifdef MC_CAN_FORK
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.223
diff -u -u -r1.223 prog_io.m
--- compiler/prog_io.m	25 Jul 2003 02:27:23 -0000	1.223
+++ compiler/prog_io.m	30 Jul 2003 14:27:55 -0000
@@ -590,8 +590,12 @@
 		;
 			PartialFileName = FileName
 		},
-		{ file_name_to_module_name(dir__basename_det(PartialFileName),
-			DefaultModuleName) },
+		{ dir__basename(PartialFileName, BaseName0) ->
+			BaseName = BaseName0
+		;
+			BaseName = ""
+		},
+		{ file_name_to_module_name(BaseName, DefaultModuleName) },
 		read_first_item(DefaultModuleName, FileName,
 			ModuleName, RevMessages, _, _, _),
 		{ MaybeModuleName = yes(ModuleName) },
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.372
diff -u -u -r1.372 user_guide.texi
--- doc/user_guide.texi	23 Jul 2003 03:38:45 -0000	1.372
+++ doc/user_guide.texi	1 Aug 2003 09:43:09 -0000
@@ -6335,19 +6335,18 @@
 Specify a command to run before linking with @samp{mmc --make}.
 This can be used to compile C source files which rely on
 header files generated by the Mercury compiler.
-Occurrences of @samp{@@} in the command will be replaced with
-the name of the main module with @samp{.} as the module
-qualifier. Occurrences of @samp{%} in the command will be
-replaced with the list of modules making up the library.
-Occurrences of @samp{@@@@} and @samp{%%} will be replaced
-with @samp{@@} and @samp{%} respectively.
+The command will be passed the names of all of the source files in
+the program or library, with the source file containing the main
+module given first.
 
 @sp 1
 @item --extra-init-command @var{command}
 @findex --extra-init-command
-Specify a command to produce extra entries in the @file{.init} file
-for a library. Occurrences of @samp{@@} and @samp{%} in the command
-are substituted as for the @samp{--pre-link-command} option.
+Specify a command to produce extra entries in the @file{.init}
+file for a library.
+The command will be passed the names of all of the source files in
+the program or library, with the source file containing the main
+module given first.
 
 @sp 1
 @item -k
@@ -6459,6 +6458,20 @@
 current directory.
 @samp{--use-grade-subdirs} does not work with Mmake (it does
 work with @samp{mmc --make}).
+
+ at sp 1
+ at item --no-make-implies-use-subdirs
+ at findex --no-make-implies-use-subdirs
+ at findex --make-implies-use-subdirs
+ at cindex File names
+ at cindex Directories
+ at cindex Subdirectories
+ at cindex @file{Mercury} subdirectory
+ at cindex Grades
+Normally, @samp{--make} implies @samp{--use-subdirs}.
+This option disables that behaviour.
+Library installation does not work with
+ at samp{--no-make-implies-use-subdirs}.
 @end table
 
 @node Miscellaneous options
Index: library/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mmakefile,v
retrieving revision 1.117
diff -u -u -r1.117 Mmakefile
--- library/Mmakefile	21 Jul 2003 14:08:40 -0000	1.117
+++ library/Mmakefile	30 Jul 2003 14:27:55 -0000
@@ -322,19 +322,12 @@
 
 ifeq ($(MMAKE_USE_MMC_MAKE),no)
 
-EXTRA_INIT_COMMAND = \
-	for file in $($(STD_LIB_NAME).ms); do \
-		grep '^INIT ' $$file; \
-		true; \
-	done
+EXTRA_INIT_COMMAND = print_extra_inits $($(STD_LIB_NAME).ms)
 
 else
 
-MCFLAGS += --extra-init-command \
-		"for module in %; do \
-			grep '^INIT ' $$$${module}.m; \
-			true; \
-		done"
+MCFLAGS += --extra-init-command print_extra_inits
+
 endif	# 
 
 endif	# GRADE != il && GRADE != java
Index: library/print_extra_inits
===================================================================
RCS file: library/print_extra_inits
diff -N library/print_extra_inits
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ library/print_extra_inits	30 Jul 2003 14:27:55 -0000
@@ -0,0 +1,24 @@
+#!/bin/sh
+#-----------------------------------------------------------------------------#
+# Copyright (C) 2003 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.
+#-----------------------------------------------------------------------------#
+# library/print_extra_inits - print extra .init file lines to stdout.
+#
+# Invocation:
+#	print_extra_inits <mer_std.ms>
+# 		where <mer_std.ms> is the names of all of the source files
+#		for the modules	in libmer_std.
+#
+#-----------------------------------------------------------------------------#
+
+for file; do
+	if [ -f $file ]; then
+		grep '^INIT ' $file
+	else
+		echo "source file $file not found" 1>&2
+		exit 1
+	fi
+done
+exit 0
Index: scripts/Mercury.config.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mercury.config.in,v
retrieving revision 1.6
diff -u -u -r1.6 Mercury.config.in
--- scripts/Mercury.config.in	22 May 2003 03:57:13 -0000	1.6
+++ scripts/Mercury.config.in	30 Jul 2003 14:36:02 -0000
@@ -61,6 +61,7 @@
 		--shared-libs "@SHARED_LIBS@" \
 		--math-lib "@MATH_LIB@" \
 		--readline-libs "@READLINE_LIBRARIES@" \
+		--linker-opt-separator "@LINK_OPT_SEP@" \
 		--linker-thread-flags "@LDFLAGS_FOR_THREADS@" \
 		--shlib-linker-thread-flags "@LD_LIBFLAGS_FOR_THREADS@" \
 		--linker-trace-flags "@LDFLAGS_FOR_TRACE@" \
@@ -69,6 +70,11 @@
 		--linker-strip-flag "@LD_STRIP_FLAG@" \
 		--linker-debug-flags "@LDFLAGS_FOR_DEBUG@" \
 		--shlib-linker-debug-flags "@LD_LIBFLAGS_FOR_DEBUG@" \
+		--linker-link-lib-flag "@LINK_LIB@" \
+		--linker-link-lib-suffix "@LINK_LIB_SUFFIX@" \
+		--shlib-linker-link-lib-flag "@LINK_LIB@" \
+		--shlib-linker-link-lib-suffix "@LINK_LIB_SUFFIX@" \
+		--linker-path-flag "@LIB_LIBPATH@" \
 		--linker-rpath-flag "@EXE_RPATH_OPT@" \
 		--linker-rpath-separator "@EXE_RPATH_SEP@" \
 		--shlib-linker-rpath-flag "@SHLIB_RPATH_OPT@" \
@@ -76,7 +82,7 @@
 		--linker-allow-undefined-flag "@ALLOW_UNDEFINED@" \
 		--linker-error-undefined-flag "@ERROR_UNDEFINED@" \
 		--fullarch "@FULLARCH@" \
-		--install-prefix "@prefix@" \
+		--install-prefix "@INSTALL_PREFIX@" \
 		--num-real-r-regs "@NUM_REAL_R_REGS@" \
 		--num-real-r-temps "@NUM_REAL_R_TEMPS@" \
 		--conf-low-tag-bits "@LOW_TAG_BITS@" \
Index: scripts/mercury.bat.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/mercury.bat.in,v
retrieving revision 1.1
diff -u -u -r1.1 mercury.bat.in
--- scripts/mercury.bat.in	27 May 2001 10:52:08 -0000	1.1
+++ scripts/mercury.bat.in	30 Jul 2003 14:27:55 -0000
@@ -10,64 +10,85 @@
 rem
 rem Use `mercury -h' for help.
 rem
-rem Environment variables: MERCURY_INT_DIR, MERCURY_C_INCL_DIR,
-rem MERCURY_ALL_MC_C_INCL_DIRS,
-rem MERCURY_COMPILER, MERCURY_C_COMPILER,
-rem MERCURY_DEFAULT_GRADE, MERCURY_DEFAULT_OPT_LEVEL.
+rem Environment variables: 
+rem MERCURY_COMPILER, MERCURY_CONFIG_DIR.
 rem ---------------------------------------------------------------------------
 rem This is a Windows batch file version of the `mmc' Bourne shell script.
 rem The idea is to eventually avoid the need to use Cygwin.
 rem XXX Note that currently Cygwin is still required:
-rem     (1) For `c2init' and `ml'.
-rem	(2) For `mmake'.
-rem	(3) For installation (`configure' and `make install').
-rem There are work-arounds for some but not all of these:
-rem	(1) Currently there's no work-around for `c2init' and `ml'
-rem	(2) `mmake' is not strictly necessary; you can always invoke the
-rem	    necessary commands by hand.  This is of course tedious and
-rem	    error-prone, so we might eventually include more of mmake's
-rem	    functionality into the Mercury compiler itself.
-rem	(3) This would be easy enough to avoid; if we're willing to hard-code
+rem	(1) For installation (`configure' and `make install').
+rem	    This would be easy enough to avoid; if we're willing to hard-code
 rem	    the installation path, we could easily package up the installation
 rem         in a WinZip file or something similar.
 rem ---------------------------------------------------------------------------
 
-set INTDIR=%MERCURY_INT_DIR%
-if "%INTDIR%"=="" set INTDIR=@WINDOWS_LIBDIR@\ints
+rem On Windows 98 an unset variable is treated as if it is set to ""
+if "%MERCURY_CONFIG_DIR%"=="" goto :config_dir_not_set
 
-set MERC_C_INCL_DIR=%MERCURY_C_INCL_DIR%
-if "%MERC_C_INCL_DIR%"=="" set MERC_C_INCL_DIR=@WINDOWS_LIBDIR@\inc
+rem On Windows XP an unset variable is not substituted.
+if "%MERCURY_CONFIG_DIR%"=="^%MERCURY_CONFIG_DIR^%" goto :config_dir_not_set
 
-set MERC_ALL_MC_C_INCL_DIRS=%MERCURY_ALL_MC_C_INCL_DIRS%
-if "%MERC_ALL_MC_C_INCL_DIRS%"=="" set MERC_ALL_MC_C_INCL_DIRS=--c-include-directory "%MERC_C_INCL_DIR%"
+goto :config_dir_set
 
-set MC=%MERCURY_COMPILER%
-if "%MC%"=="" set MC=@WINDOWS_LIBDIR@\bin\@FULLARCH@\mercury_compile
-
-set DEFAULT_GRADE=%MERCURY_DEFAULT_GRADE%
-if "%DEFAULT_GRADE%"=="" set DEFAULT_GRADE=@DEFAULT_GRADE@
-
-set CC=%MERCURY_C_COMPILER%
-if "%CC%"=="" set CC=@CC@
-
-set CFLAGS_FOR_REGS=@CFLAGS_FOR_REGS@
-set CFLAGS_FOR_GOTOS=@CFLAGS_FOR_GOTOS@
-set CFLAGS_FOR_THREADS=@CFLAGS_FOR_THREADS@
-set CFLAG_TO_NAME_OBJECT_FILE=@OBJFILE_OPT@
-set OBJECT_FILE_EXTENSION=@OBJ_SUFFIX@
-set LOW_TAG_BITS=@LOW_TAG_BITS@
-set BITS_PER_WORD=@BITS_PER_WORD@
-set BYTES_PER_WORD=@BYTES_PER_WORD@
-set NUM_REAL_R_REGS=@NUM_REAL_R_REGS@
-set NUM_REAL_R_TEMPS=@NUM_REAL_R_TEMPS@
-set HAVE_DELAY_SLOT=@HAVE_DELAY_SLOT@
-set HAVE_BOXED_FLOATS=@HAVE_BOXED_FLOATS@
+:config_dir_not_set
+
+if "%MERCURY_STDLIB_DIR%"=="" goto :stdlib_dir_not_set
+if "%MERCURY_STDLIB_DIR%"=="^%MERCURY_STDLIB_DIR^%" goto :stdlib_dir_not_set
+
+set MERCURY_CONFIG_DIR="%MERCURY_CONFIG_DIR%"
+
+goto :config_dir_set
+
+:stdlib_dir_not_set
+
+set MERCURY_CONFIG_DIR="@CONFIG_LIBDIR@"
+
+:config_dir_set
+
+if "%MERCURY_COMPILER%"=="" set MERCURY_COMPILER="@LIBDIR@\bin\@FULLARCH@\mercury_compile"
+if "%MERCURY_COMPILER%"=="^%MERCURY_COMPILER^%" set MERCURY_COMPILER="@LIBDIR@\bin\@FULLARCH@\mercury_compile"
+
+rem There is no equivalent of "$@" available on all Windows platforms.
+rem (Windows XP has `%*').
+
+set v1=%1
+set v2=%2
+set v3=%3
+set v4=%4
+set v5=%5
+set v6=%6
+set v7=%7
+set v8=%8
+set v9=%9
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+set v10=%0
+set v11=%1
+set v12=%2
+set v13=%3
+set v14=%4
+set v15=%5
+set v16=%6
+set v17=%7
+set v18=%8
+set v19=%9
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+shift
+shift
 
-set DEFAULT_OPT_LEVEL=%MERCURY_DEFAULT_OPT_LEVEL%
-if "%DEFAULT_OPT_LEVEL%"=="" set DEFAULT_OPT_LEVEL=-O2
-
-rem The default optimization level should be after
-rem all the options that describe the machine configuration.
-
-echo on
-%MC% %MERC_ALL_MC_C_INCL_DIRS% --cc "%CC%" --grade "%DEFAULT_GRADE%" --cflags-for-threads "%CFLAGS_FOR_THREADS%" --cflags-for-regs "%CFLAGS_FOR_REGS%" --cflags-for-gotos "%CFLAGS_FOR_GOTOS%" --c-flag-to-name-object-file "%CFLAG_TO_NAME_OBJECT_FILE%" --object-file-extension "%OBJECT_FILE_EXTENSION%" --num-real-r-regs "%NUM_REAL_R_REGS%" --num-real-r-temps "%NUM_REAL_R_TEMPS%" --conf-low-tag-bits "%LOW_TAG_BITS%" --bits-per-word "%BITS_PER_WORD%" --bytes-per-word "%BYTES_PER_WORD%" %HAVE_DELAY_SLOT% %HAVE_BOXED_FLOATS% %DEFAULT_OPT_LEVEL% -I "%INTDIR%" %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %20 %21 %22 %23 %24 %25 %26 %27 %28 %29 %30
+%MERCURY_COMPILER% %v1% %v2% %v3% %v4% %v5% %v6% %v7% %v8% %v9% %v10% %v11% %v12% %v13% %v14% %v15% %v16% %v17% %v18% %v19% %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
Index: scripts/mmc.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/mmc.in,v
retrieving revision 1.35
diff -u -u -r1.35 mmc.in
--- scripts/mmc.in	14 Apr 2003 06:50:13 -0000	1.35
+++ scripts/mmc.in	30 Jul 2003 14:27:55 -0000
@@ -14,12 +14,11 @@
 # MERCURY_COMPILER, MERCURY_C_COMPILER, MERCURY_DEFAULT_GRADE,
 # MERCURY_DEFAULT_OPT_LEVEL.
 
-MC=${MERCURY_COMPILER="@LIBDIR@/bin/@FULLARCH@/mercury_compile"}
-MERCURY_CONFIG_DIR=${MERCURY_CONFIG_DIR-${MERCURY_STDLIB_DIR- at LIBDIR@}}
-export MERCURY_CONFIG_DIR
+MERCURY_COMPILER=${MERCURY_COMPILER-'@LIBDIR@/bin/@FULLARCH@/mercury_compile'}
+MERCURY_CONFIG_DIR=${MERCURY_CONFIG_DIR-${MERCURY_STDLIB_DIR-'@CONFIG_LIBDIR@'}}
+export MERCURY_COMPILER MERCURY_CONFIG_DIR
 
 case $# in
-	0) exec $MC ;;
-	*) exec $MC "$@" ;;
+	0) exec $MERCURY_COMPILER ;;
+	*) exec $MERCURY_COMPILER "$@" ;;
 esac
-
Index: tools/bootcheck
===================================================================
RCS file: /home/mercury1/repository/mercury/tools/bootcheck,v
retrieving revision 1.153
diff -u -u -r1.153 bootcheck
--- tools/bootcheck	20 May 2003 03:18:14 -0000	1.153
+++ tools/bootcheck	30 Jul 2003 14:27:55 -0000
@@ -183,6 +183,7 @@
 STD_LIB_NAME=mer_std
 TRACE_LIB_NAME=mer_trace
 BROWSER_LIB_NAME=mer_browser
+ANALYSIS_LIB_NAME=mer_analysis
 
 while [ $# -gt 0 ]; do
 	case "$1" in
@@ -391,7 +392,7 @@
 
 if $windows
 then
-	CYGPATH='cygpath -w'
+	CYGPATH='cygpath -m'
 else
 	CYGPATH='echo'
 fi
@@ -416,6 +417,7 @@
 s:/mount/munkora/mercury:/home/mercury:
 s:/mount/munkora/home/mercury:/home/mercury:
 s:/mount/munkora/clp/mercury:/home/mercury:'`
+root=`$CYGPATH $root`
 PATH=$root/tools:$PATH
 export PATH
 
@@ -508,6 +510,7 @@
 		$LN_S $root/library/[m-z]*.m .
 		# See comment below for why we use $LN rather than $LN_S here
 		$LN $root/library/library_strong_name.sn .
+		$LN_S $root/library/print_extra_inits .
 		cp $root/library/Mmake* $root/library/Mercury.options .
 		$LN_S $root/library/$STD_LIB_NAME.init .
 		$LN_S $root/library/RESERVED_MACRO_NAMES .
@@ -840,6 +843,7 @@
 	cd library
 	$LN_S $root/library/[a-l]*.m .
 	$LN_S $root/library/[m-z]*.m .
+	$LN_S $root/library/print_extra_inits .
 	$LN_S $root/library/library_strong_name.sn .
 	cp $root/library/Mmake* $root/library/Mercury.options .
 	$LN_S $root/library/$STD_LIB_NAME.init .
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.89
diff -u -u -r1.89 mkinit.c
--- util/mkinit.c	25 Sep 2002 07:53:53 -0000	1.89
+++ util/mkinit.c	30 Jul 2003 14:27:55 -0000
@@ -876,6 +876,9 @@
 	if ((position = strrchr(filename, '/')) != NULL) {
 		filename = position + 1;
 	}
+	if ((position = strrchr(filename, '\\')) != NULL) {
+		filename = position + 1;
+	}
 
 	/*
 	** The func name is "mercury__<modulename>__init",
--------------------------------------------------------------------------
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