diff: add support for putting files in subdirs

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Mar 18 17:00:09 AEDT 1998


If anyone wants to review this, they are of course welcome to go ahead.

Estimated hours taken: 12

Finish off the centralization of the file name handling code, and
add support for generating intermediate files in subdirectories.

scripts/mmake.in:
	Add a new boolean option `--use-subdirs';
	if enabled, it just sets the environment variable MMAKE_USE_SUBDIRS
	to `yes' before invoking Make.
	Also add negative versions of the various options
	(`--no-use-subdirs', `--no-verbose', `--no-save-makefile').

scripts/Mmake.rules:
	Add code to handle generating intermediate file names
	in subdirectories.  If MMAKE_USE_SUBDIRS=yes, we add
	`--use-subdirs' to MCFLAGS, and most of the pattern rules
	are changed to use subdirectories.

	Note that getting this to work required a bit of a hack:
	due to what seem to be bugs in GNU Make, `mmake depend'
	needs to do `mmc --make-short-interface *.m' to get things
	started.  But once the int3s are there, the dependencies
	seem to work OK.

compiler/options.m:
	Add a new boolean option `--use-subdirs'. 

compiler/modules.m:
	Add new predicate `fact_table_file_name'.
	Add an extra argument to `module_name_to_file_name',
	specifying whether or not to create any directories
	needed for the file name.
	Change all the file-name-creating predicates here
	to go through a single new predicate `choose_file_name',
	and add code in that predicate to handle the `--use-subdirs'
	option.
	Also if the `--use-subdirs' option is set, don't use the
	compact dependencies format, since it can't work in that case.

compiler/fact_table.m:
	Call `fact_table_file_name' rather than using `string__append'.

compiler/mercury_compile.m:
	Change `link_module_list' and `join_module_list'
	so that they create file names by calling `module_name_to_file_name'.

compiler/export.m:
compiler/intermod.m:
compiler/llds_out.m:
compiler/mercury_compile.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/termination.m:
compiler/trans_opt.m:
compiler/unused_args.m:
	Change all calls to `module_name_to_file_name' to pass
	the extra argument specifying whether or not to make
	any directories needed for the file name.

library/Mmakefile:
	Change the rule for `mmake install_ints' so that it
	creates a `Mercury' subdirectory with symbolic links
	`ints', `int2s', `int3s', `opts', and `trans_opts'
	which just point to `..'.  This is needed for the
	`--use-subdirs' option to work, because Mmake currently
	does not support mixing libraries compiled with and
	without `--use-subdirs'.

doc/user_guide.texi:
	Document the above changes.

cvs diff  compiler/export.m compiler/fact_table.m compiler/intermod.m compiler/llds_out.m compiler/mercury_compile.m compiler/module_qual.m compiler/modules.m compiler/options.m compiler/termination.m compiler/trans_opt.m compiler/unused_args.m doc/user_guide.texi library/Mmakefile scripts/Mmake.rules scripts/mmake.in
Index: compiler/export.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/export.m,v
retrieving revision 1.20
diff -u -r1.20 export.m
--- export.m	1998/03/17 00:27:58	1.20
+++ export.m	1998/03/17 03:16:43
@@ -449,12 +449,12 @@
 	->
 		{ module_info_get_predicate_table(Module, PredicateTable) },
 		{ predicate_table_get_preds(PredicateTable, Preds) },
-		module_name_to_file_name(ModuleName, ".h", FileName),
+		module_name_to_file_name(ModuleName, ".h", yes, FileName),
 		io__tell(FileName, Result),
 		(
 			{ Result = ok }
 		->
-			module_name_to_file_name(ModuleName, ".m",
+			module_name_to_file_name(ModuleName, ".m", no,
 				SourceFileName),
 			{ library__version(Version) },
 			io__write_strings(
Index: compiler/fact_table.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/fact_table.m,v
retrieving revision 1.17
diff -u -r1.17 fact_table.m
--- fact_table.m	1998/03/03 17:34:13	1.17
+++ fact_table.m	1998/03/17 04:52:10
@@ -52,7 +52,7 @@
 :- import_module io, list.
 :- import_module prog_data, hlds_pred, hlds_module.
 
-	% compile the fact table into a separate .o file.
+	% compile the fact table into a separate .c file.
 	% fact_table_compile_facts(PredName, Arity, FileName, PredInfo0, 
 	% 	PredInfo, Context, ModuleInfo, C_HeaderCode, PrimaryProcID)
 :- pred fact_table_compile_facts(sym_name, arity, string, pred_info, pred_info,
@@ -90,7 +90,7 @@
 :- import_module float, math, getopt, term, string.
 :- import_module parser, term_io.
 
-:- import_module prog_util, prog_out, llds_out, hlds_out, hlds_data.
+:- import_module prog_util, prog_out, llds_out, modules, hlds_out, hlds_data.
 :- import_module globals, options, passes_aux, arg_info, llds, mode_util.
 :- import_module code_util, export, inst_match.
 
@@ -177,7 +177,8 @@
     io__see(FileName, Result0),
     (
 	{ Result0 = ok },
-	{ string__append(FileName, ".c", OutputFileName) },
+	{ module_info_name(ModuleInfo, ModuleName) },
+	fact_table_file_name(ModuleName, FileName, ".c", OutputFileName),
 	io__open_output(OutputFileName, Result1),
 	(
 	    { Result1 = ok(OutputStream) },
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.47
diff -u -r1.47 intermod.m
--- intermod.m	1998/03/17 00:28:01	1.47
+++ intermod.m	1998/03/17 03:16:57
@@ -79,7 +79,7 @@
 
 intermod__write_optfile(ModuleInfo0, ModuleInfo) -->
 	{ module_info_name(ModuleInfo0, ModuleName) },
-	module_name_to_file_name(ModuleName, ".opt.tmp", TmpName),
+	module_name_to_file_name(ModuleName, ".opt.tmp", yes, TmpName),
 	io__tell(TmpName, Result2),
 	(
 		{ Result2 = error(Err2) },
@@ -1320,7 +1320,7 @@
 	maybe_flush_output(VeryVerbose),
 	maybe_write_string(VeryVerbose, "% done.\n"),
 
-	module_name_to_file_name(Import, ".opt", FileName),
+	module_name_to_file_name(Import, ".opt", no, FileName),
 	prog_io__read_module(FileName, Import, yes,
 			ModuleError, Messages, Items1),
 	update_error_status(FileName, ModuleError, Messages, Error0, Error1),
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.76
diff -u -r1.76 llds_out.m
--- llds_out.m	1998/03/17 00:28:04	1.76
+++ llds_out.m	1998/03/17 03:17:51
@@ -139,7 +139,7 @@
 	globals__io_lookup_bool_option(split_c_files, SplitFiles),
 	( { SplitFiles = yes } ->
 		{ C_File = c_file(ModuleName, C_HeaderInfo, C_Modules) },
-		module_name_to_file_name(ModuleName, ".dir", ObjDirName),
+		module_name_to_file_name(ModuleName, ".dir", yes, ObjDirName),
 		make_directory(ObjDirName),
 		output_c_file_init(ModuleName, C_Modules),
 		output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo)
@@ -170,7 +170,7 @@
 :- mode output_c_file_init(in, in, di, uo) is det.
 
 output_c_file_init(ModuleName, C_Modules) -->
-	module_name_to_file_name(ModuleName, ".m", SourceFileName),
+	module_name_to_file_name(ModuleName, ".m", no, SourceFileName),
 	module_name_to_split_c_file_name(ModuleName, 0, ".c", FileName),
 
 	io__tell(FileName, Result),
@@ -214,14 +214,14 @@
 		module_name_to_split_c_file_name(ModuleName, Num, ".c",
 			FileName)
 	;
-		module_name_to_file_name(ModuleName, ".c", FileName)
+		module_name_to_file_name(ModuleName, ".c", yes, FileName)
 	),
 	io__tell(FileName, Result),
 	(
 		{ Result = ok }
 	->
 		{ library__version(Version) },
-		module_name_to_file_name(ModuleName, ".m", SourceFileName),
+		module_name_to_file_name(ModuleName, ".m", no, SourceFileName),
 		io__write_strings(
 			["/*\n",
 			"** Automatically generated from `", SourceFileName,
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.77
diff -u -r1.77 mercury_compile.m
--- mercury_compile.m	1998/03/17 00:28:07	1.77
+++ mercury_compile.m	1998/03/17 03:42:36
@@ -162,7 +162,7 @@
 process_module_2(ModuleName) -->
 	globals__io_lookup_bool_option(verbose, Verbose),
 	maybe_write_string(Verbose, "% Parsing `"),
-	module_name_to_file_name(ModuleName, ".m", FileName),
+	module_name_to_file_name(ModuleName, ".m", no, FileName),
 	maybe_write_string(Verbose, FileName),
 	maybe_write_string(Verbose, "' and imported interfaces...\n"),
 	read_mod(ModuleName, ".m", "Reading module", yes, Items0, Error), !,
@@ -188,7 +188,8 @@
 	; { MakePrivateInterface = yes } ->
 		make_private_interface(ModuleName, Items0)
 	; { ConvertToMercury = yes } ->
-		module_name_to_file_name(ModuleName, ".ugly", OutputFileName),
+		module_name_to_file_name(ModuleName, ".ugly", yes,
+					OutputFileName),
 		convert_to_mercury(ModuleName, OutputFileName, Items0)
 	; { ConvertToGoedel = yes } ->
 		convert_to_goedel(ModuleName, Items0)
@@ -257,12 +258,13 @@
 		mercury_compile__middle_pass(ModuleName, HLDS25, HLDS50), !,
 		globals__io_lookup_bool_option(highlevel_c, HighLevelC),
 		( { HighLevelC = yes } ->
-			module_name_to_file_name(ModuleName, ".c", C_File),
-			module_name_to_file_name(ModuleName, ".o", O_File),
+			module_name_to_file_name(ModuleName, ".c", no, C_File),
 			mercury_compile__gen_hlds(C_File, HLDS50),
 			globals__io_lookup_bool_option(compile_to_c,
 				CompileToC),
 			( { CompileToC = no } ->
+				module_name_to_file_name(ModuleName, ".o", yes,
+					O_File),
 				mercury_compile__single_c_to_obj(
 					C_File, O_File, _CompileOK)
 			;
@@ -594,7 +596,7 @@
 			{ HLDS = HLDS1 }
 		),
 		{ module_info_name(HLDS, ModuleName) },
-		module_name_to_file_name(ModuleName, ".opt", OptName),
+		module_name_to_file_name(ModuleName, ".opt", yes, OptName),
 		update_interface(OptName),
 		touch_interface_datestamp(ModuleName, ".optdate")
 	;
@@ -1215,7 +1217,7 @@
 	( { ShowDepGraph = yes } ->
 		maybe_write_string(Verbose, "% Writing dependency graph..."),
 		{ module_info_name(ModuleInfo0, ModuleName) },
-		module_name_to_file_name(ModuleName, ".dependency_graph",
+		module_name_to_file_name(ModuleName, ".dependency_graph", yes,
 			FileName),
 		io__tell(FileName, Res),
 		( { Res = ok } ->
@@ -1250,7 +1252,8 @@
 		maybe_write_string(Verbose, "% Outputing profiling call graph..."),
 		maybe_flush_output(Verbose),
 		{ module_info_name(ModuleInfo0, ModuleName) },
-		module_name_to_file_name(ModuleName, ".prof", ProfFileName),
+		module_name_to_file_name(ModuleName, ".prof", yes,
+						ProfFileName),
 		io__tell(ProfFileName, Res),
 		(
 			{ Res = ok }
@@ -1338,7 +1341,7 @@
 		bytecode_gen__module(HLDS1, Bytecode),
 		maybe_write_string(Verbose, "% done.\n"),
 		maybe_report_stats(Stats),
-		module_name_to_file_name(ModuleName, ".bytedebug",
+		module_name_to_file_name(ModuleName, ".bytedebug", yes,
 			BytedebugFile),
 		maybe_write_string(Verbose,
 			"% Writing bytecodes to `"),
@@ -1347,7 +1350,7 @@
 		maybe_flush_output(Verbose),
 		debug_bytecode_file(BytedebugFile, Bytecode),
 		maybe_write_string(Verbose, " done.\n"),
-		module_name_to_file_name(ModuleName, ".mbc", BytecodeFile),
+		module_name_to_file_name(ModuleName, ".mbc", yes, BytecodeFile),
 		maybe_write_string(Verbose,
 			"% Writing bytecodes to `"),
 		maybe_write_string(Verbose, BytecodeFile),
@@ -1731,12 +1734,12 @@
 
 maybe_add_header_file_include(PragmaExports, ModuleName, 
 		C_HeaderCode0, C_HeaderCode) -->
-	module_name_to_file_name(ModuleName, ".h", HeaderFileName),
 	(
 		{ PragmaExports = [] },
 		{ C_HeaderCode = C_HeaderCode0 }
 	;
 		{ PragmaExports = [_|_] },
+		module_name_to_file_name(ModuleName, ".h", no, HeaderFileName),
                 globals__io_lookup_bool_option(split_c_files, SplitFiles),
                 { 
 			SplitFiles = yes,
@@ -1794,7 +1797,7 @@
 mercury_compile__output_llds(ModuleName, LLDS, Verbose, Stats) -->
 	maybe_write_string(Verbose,
 		"% Writing output to `"),
-	module_name_to_file_name(ModuleName, ".c", FileName),
+	module_name_to_file_name(ModuleName, ".c", yes, FileName),
 	maybe_write_string(Verbose, FileName),
 	maybe_write_string(Verbose, "'..."),
 	maybe_flush_output(Verbose),
@@ -1845,8 +1848,8 @@
 		mercury_compile__c_to_obj_list(ModuleName, 0, NumChunks,
 			Succeeded)
 	;
-		module_name_to_file_name(ModuleName, ".c", C_File),
-		module_name_to_file_name(ModuleName, ".o", O_File),
+		module_name_to_file_name(ModuleName, ".c", no, C_File),
+		module_name_to_file_name(ModuleName, ".o", yes, O_File),
 		mercury_compile__single_c_to_obj(C_File, O_File, Succeeded)
 	).
 
@@ -2054,31 +2057,35 @@
 mercury_compile__link_module_list(Modules) -->
 	globals__io_lookup_bool_option(verbose, Verbose),
 	globals__io_lookup_bool_option(statistics, Stats),
-	globals__io_lookup_string_option(output_file_name, OutputFile0),
-	( { OutputFile0 = "" } ->
+	globals__io_lookup_string_option(output_file_name, OutputFileName0),
+	( { OutputFileName0 = "" } ->
 	    ( { Modules = [Module | _] } ->
-		{ dir__basename(Module, OutputFile) }
+		{ OutputFileName = Module }
 	    ;
 		{ error("link_module_list: no modules") }
 	    )
 	;
-	    { OutputFile = OutputFile0 }
+	    { OutputFileName = OutputFileName0 }
 	),
-	{ dir__basename(OutputFile, OutputFileBase) },
+
+	{ file_name_to_module_name(OutputFileName, ModuleName) },
+	module_name_to_file_name(ModuleName, "_init.c", yes, InitCFileName),
+	module_name_to_file_name(ModuleName, "_init.o", yes, InitObjFileName),
 
 	globals__io_lookup_bool_option(split_c_files, SplitFiles),
 	( { SplitFiles = yes } ->
-	    { join_module_list(Modules, ".dir/*.o ", [], ObjectList) },
+	    module_name_to_file_name(ModuleName, ".a", yes, SplitLibFileName),
+	    join_module_list(Modules, ".dir/*.o", [], ObjectList),
 	    { list__append(
-		["ar cr ", OutputFileBase, ".a " | ObjectList],
-		[" && ranlib ", OutputFileBase, ".a"],
+		["ar cr ", SplitLibFileName, " " | ObjectList],
+		[" && ranlib ", SplitLibFileName],
 		MakeLibCmdList) },
 	    { string__append_list(MakeLibCmdList, MakeLibCmd) },
 	    invoke_system_command(MakeLibCmd, MakeLibCmdOK),
-	    { string__append(OutputFileBase, ".a", Objects) }
+	    { Objects = SplitLibFileName }
 	;
 	    { MakeLibCmdOK = yes },
-	    { join_module_list(Modules, ".o ", [], ObjectsList) },
+	    join_module_list(Modules, ".o", [], ObjectsList),
 	    { string__append_list(ObjectsList, Objects) }
 	),
 	( { MakeLibCmdOK = no } ->
@@ -2086,9 +2093,7 @@
 	;
 	    % create the initialization C file
 	    maybe_write_string(Verbose, "% Creating initialization file...\n"),
-	    { string__append(OutputFileBase, "_init", C_Init_Base) },
-	    { join_module_list(Modules, ".m ", ["> ", C_Init_Base, ".c"],
-				MkInitCmd0) },
+	    join_module_list(Modules, ".m", ["> ", InitCFileName], MkInitCmd0),
 	    { string__append_list(["c2init " | MkInitCmd0], MkInitCmd) },
 	    invoke_system_command(MkInitCmd, MkInitOK),
 	    maybe_report_stats(Stats),
@@ -2098,9 +2103,7 @@
 		% compile it
 		maybe_write_string(Verbose,
 			"% Compiling initialization file...\n"),
-		{ string__append(C_Init_Base, ".c", C_InitSrc) },
-		{ string__append(C_Init_Base, ".o", C_InitObj) },
-		mercury_compile__single_c_to_obj(C_InitSrc, C_InitObj,
+		mercury_compile__single_c_to_obj(InitCFileName, InitObjFileName,
 			CompileOK),
 		maybe_report_stats(Stats),
 		( { CompileOK = no } ->
@@ -2127,8 +2130,8 @@
 				LinkObjects) },
 		    { string__append_list(
 			["ml --grade ", Grade, " ", LinkFlags,
-			" -o ", OutputFile, " ",
-			OutputFileBase, "_init.o ", Objects, " ",
+			" -o ", OutputFileName, " ",
+			InitObjFileName, " ", Objects, " ",
 			LinkObjects, " ",
 			LinkLibraryDirectories, " ", LinkLibraries],
 			LinkCmd) },
@@ -2162,21 +2165,27 @@
 			Result0], Result)
 	).
 
-	% join_module_list(Strings, Separator, Terminator, Result)
+	% join_module_list(ModuleNames, Extension, Terminator, Result)
 	%
-	% The list of strings `Result' is the list of strings `Strings',
-	% where each string in `Strings' has had any directory path 
-	% removed, and is separated by `Separator' from the next string, 
-	% followed by the list of strings `Terminator'.
-
-:- pred join_module_list(list(string), string, list(string), list(string)).
-:- mode join_module_list(in, in, in, out) is det.
-
-join_module_list([], _Separator, Terminator, Terminator).
-join_module_list([Module0 | Modules0], Separator, Terminator,
-			[Basename0, Separator | Rest]) :-
-	dir__basename(Module0, Basename0),
-	join_module_list(Modules0, Separator, Terminator, Rest).
+	% 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),
+			io__state, io__state).
+:- mode join_module_list(in, in, in, out, di, uo) is det.
+
+join_module_list([], _Extension, Terminator, Terminator) --> [].
+join_module_list([Module | Modules], Extension, Terminator,
+			[FileName, " " | Rest]) -->
+	{ dir__basename(Module, BaseName) },
+	{ file_name_to_module_name(BaseName, ModuleName) },
+	module_name_to_file_name(ModuleName, Extension, no, FileName),
+	join_module_list(Modules, Extension, Terminator, Rest).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -2200,7 +2209,7 @@
 		}
 	->
 		{ module_info_name(HLDS, ModuleName) },
-		module_name_to_file_name(ModuleName, ".hlds_dump",
+		module_name_to_file_name(ModuleName, ".hlds_dump", yes,
 			BaseFileName),
 		{ string__append_list(
 			[BaseFileName, ".", StageNum, "-", StageName],
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.34
diff -u -r1.34 module_qual.m
--- module_qual.m	1998/03/17 00:28:10	1.34
+++ module_qual.m	1998/03/17 03:21:51
@@ -1003,7 +1003,7 @@
 	->
 		[]
 	;
-		module_name_to_file_name(ModuleName, ".m", FileName),
+		module_name_to_file_name(ModuleName, ".m", no, FileName),
 		{ term__context_init(FileName, 1, Context) },
 		prog_out__write_context(Context),
 		io__write_string("In module `"),
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.62
diff -u -r1.62 modules.m
--- modules.m	1998/03/17 00:28:12	1.62
+++ modules.m	1998/03/18 04:06:04
@@ -44,9 +44,10 @@
 
 %-----------------------------------------------------------------------------%
 
-	% module_name_to_file_name(Module, Extension, FileName):
+	% module_name_to_file_name(Module, Extension, Mkdir, FileName):
 	%	Convert a module name and file extension to the
-	%	corresponding file name.
+	%	corresponding file name.  If `MkDir' is yes, then
+	%	create any directories needed.
 	%
 	%	Currently we use the convention that the module
 	%	`foo:bar:baz' should be named `foo.bar.baz.m',
@@ -57,19 +58,20 @@
 	%	some "phony" Makefile targets that do not have
 	%	corresponding files, e.g. `<foo>.clean'.
 	%
-:- pred module_name_to_file_name(module_name, string, file_name,
+:- pred module_name_to_file_name(module_name, string, bool, file_name,
 				io__state, io__state).
-:- mode module_name_to_file_name(in, in, out, di, uo) is det.
+:- mode module_name_to_file_name(in, in, in, out, di, uo) is det.
 
-	% module_name_to_lib_file_name(Prefix, Module, Extension, FileName):
+	% module_name_to_lib_file_name(Prefix, Module, Extension, MkDir,
+	%		FileName):
 	%	Like module_name_to_file_name, but also allows a prefix.
 	%
 	%	Used for creating library names, e.g. `lib<foo>.a'
 	%	and `lib<foo>.so'.
 	%
-:- pred module_name_to_lib_file_name(string, module_name, string, file_name,
-				io__state, io__state).
-:- mode module_name_to_lib_file_name(in, in, in, out, di, uo)
+:- pred module_name_to_lib_file_name(string, module_name, string, bool,
+				file_name, io__state, io__state).
+:- mode module_name_to_lib_file_name(in, in, in, in, out, di, uo)
 	is det.
 
 	% module_name_to_split_c_file_name(Module, Num, Extension, FileName):
@@ -77,6 +79,7 @@
 	%	number.  The files produced by this predicate will all be
 	%	in a subdirectory DirName, which be obtained by calling
 	%	`module_name_to_file_name(Module, ".dir", DirName)'.
+	%	This predicate does not create that directory.
 	%
 	%	This predicate is used for the names of .c and .o files
 	%	for --split-c-files.
@@ -85,6 +88,13 @@
 				io__state, io__state).
 :- mode module_name_to_split_c_file_name(in, in, in, out, di, uo) is det.
 
+	% fact_table_file_name(Module, FactTableFileName, Ext, FileName):
+	%	Returns the filename to use when compiling fact table
+	%	files.
+:- pred fact_table_file_name(module_name, file_name, string, file_name,
+				io__state, io__state).
+:- mode fact_table_file_name(in, in, in, out, di, uo) is det.
+
 	% convert a file name (excluding the trailing `.m')
 	% to the corresponding module name
 	% 
@@ -376,28 +386,156 @@
 	% `foo:bar:baz' will be in files `foo.bar.baz.{m,int,etc.}'.
 	% It would be nice to allow a more flexible mapping.
 
-module_name_to_file_name(ModuleName, Ext, FileName) -->
+module_name_to_file_name(ModuleName, Ext, MkDir, FileName) -->
 	{ prog_out__sym_name_to_string(ModuleName, ".", BaseFileName) },
-	{ string__append(BaseFileName, Ext, FileName) }.
+	{ string__append_list([BaseFileName, Ext], BaseName) },
+	choose_file_name(ModuleName, BaseName, Ext, MkDir, FileName).
 
-module_name_to_lib_file_name(Prefix, ModuleName, Ext, FileName) -->
+module_name_to_lib_file_name(Prefix, ModuleName, Ext, MkDir, FileName) -->
 	{ prog_out__sym_name_to_string(ModuleName, ".", BaseFileName) },
-	{ string__append_list([Prefix, BaseFileName, Ext], FileName) }.
+	{ string__append_list([Prefix, BaseFileName, Ext], BaseName) },
+	choose_file_name(ModuleName, BaseName, Ext, MkDir, FileName).
+
+fact_table_file_name(ModuleName, FactTableFileName, Ext, FileName) -->
+	{ string__append(FactTableFileName, Ext, BaseName) },
+	choose_file_name(ModuleName, BaseName, Ext, no, FileName).
+
+:- pred choose_file_name(module_name, string, string, bool, file_name,
+			io__state, io__state).
+:- mode choose_file_name(in, in, in, in, out, di, uo) is det.
+
+choose_file_name(_ModuleName, BaseName, Ext, MkDir, FileName) -->
+	globals__io_lookup_bool_option(use_subdirs, UseSubdirs),
+	( { UseSubdirs = no } ->
+		{ FileName = BaseName }
+	;
+		%
+		% the source files, the final executables,
+		% output files intended for use by the user,
+		% and phony Mmake targets names go in the current directory
+		%
+		{ Ext = ".m"
+		% executable files
+		; Ext = ""
+		; Ext = ".split"
+		; Ext = ".nu"
+		; Ext = ".nu.debug"
+		; Ext = ".sicstus"
+		; Ext = ".sicstus.debug"
+		% output files intended for use by the user
+		; Ext = ".err"
+		; Ext = ".ugly"
+		; Ext = ".hlds_dump"
+		; Ext = ".dependency_graph"
+		; Ext = ".order"
+		% Mmake targets
+		; Ext = ".clean"
+		; Ext = ".clean_nu"
+		; Ext = ".clean_sicstus"
+		; Ext = ".change_clean"
+		; Ext = ".realclean"
+		; Ext = ".depend"
+		; Ext = ".check"
+		; Ext = ".ints"
+		; Ext = ".int3s"
+		; Ext = ".opts"
+		; Ext = ".trans_opts"
+		}
+	->
+		{ FileName = BaseName }
+	;
+		%
+		% we need to handle a few cases specially
+		%
+		{
+			Ext = ".dir/*.o"
+		->
+			SubDirName = "dirs"
+		;
+			% .a and .so files need to go in the same
+			% directory, so that using .$(EXT_FOR_SHARED_LIB)
+			% will work
+			( Ext = ".a"
+			; Ext = ".so"
+			; Ext = ".$(EXT_FOR_SHARED_LIB)"
+			; Ext = ".split.a"
+			; Ext = ".split.so"
+			; Ext = ".split.$(EXT_FOR_SHARED_LIB)"
+			)
+		->
+			SubDirName = "libs"
+		;
+			% .o and .pic_o files need to go in the
+			% same directory, so that using
+			% .$(EXT_FOR_PIC_OBJECTS) will work.
+			( Ext = ".o"
+			; Ext = ".pic_o"
+			; Ext = "$(EXT_FOR_PIC_OBJECTS)"
+			)
+		->
+			SubDirName = "os"
+		;
+			% _init.c, _init.s, _init.o etc. files
+			% go in the cs, ss, os etc. subdirectories
+			string__append("_init.", ExtName, Ext)
+		->
+			string__append(ExtName, "s", SubDirName)
+		;
+			% .int.tmp, .opt.tmp, etc. files
+			% need to go in the ints, opts, etc. subdirectories
+			string__append(".", ExtName0, Ext),
+			string__remove_suffix(ExtName0, ".tmp", ExtName)
+		->
+			string__append(ExtName, "s", SubDirName)
+		;
+			% the usual case: `*.foo' files go in the `foos'
+			% subdirectory
+			string__append(".", ExtName, Ext)
+		->
+			string__append(ExtName, "s", SubDirName)
+		;
+			string__append_list(["unknown extension `", Ext, "'"],
+				ErrorMsg),
+			error(ErrorMsg)
+		},
+		{ dir__directory_separator(SlashChar) },
+		{ string__char_to_string(SlashChar, Slash) },
+		{ string__append_list(["Mercury", Slash, SubDirName],
+			DirName) },
+		( { MkDir = yes } ->
+			make_directory(DirName)
+		;
+			[]
+		),
+		{ string__append_list([DirName, Slash, BaseName], FileName) }
+	).
 
 module_name_to_split_c_file_name(ModuleName, Num, Ext, FileName) -->
-	module_name_to_file_name(ModuleName, ".dir", DirName),
+	module_name_to_file_name(ModuleName, ".dir", no, DirName),
 	{ unqualify_name(ModuleName, BaseFileName) },
 	{ dir__directory_separator(Slash) },
 	{ string__format("%s%c%s_%03d%s",
 		[s(DirName), c(Slash), s(BaseFileName), i(Num), s(Ext)],
 		FileName) }.
-		
+
 file_name_to_module_name(FileName, ModuleName) :-
 	string_to_sym_name(FileName, ".", ModuleName).
 
 module_name_to_make_var_name(ModuleName, MakeVarName) :-
 	prog_out__sym_name_to_string(ModuleName, ".", MakeVarName).
 
+:- pred make_directory(string, io__state, io__state).
+:- mode make_directory(in, di, uo) is det.
+
+make_directory(DirName) -->
+	( { dir__this_directory(DirName) } ->
+		[]
+	;
+		{ string__format("[ -d %s ] || mkdir -p %s",
+			[s(DirName), s(DirName)], Command) },
+		io__call_system(Command, _Result)
+	).
+
 %-----------------------------------------------------------------------------%
 
 	% Read in the .int3 files that the current module depends on,
@@ -408,8 +546,8 @@
 		%
 		% Check whether we succeeded
 		%
-	module_name_to_file_name(ModuleName, ".int0", FileName),
 	( { Error = yes } ->
+		module_name_to_file_name(ModuleName, ".int0", no, FileName),
 		io__write_strings(["Error reading interface files.\n",
 				"`", FileName, "' not written.\n"])
 	;
@@ -421,6 +559,8 @@
 				Items2, ModuleName, yes, _, _, _, _),
 		io__get_exit_status(Status),
 		( { Status \= 0 } ->
+			module_name_to_file_name(ModuleName, ".int0", no,
+				FileName),
 			io__write_strings(["`", FileName, "' not written.\n"])
 		;
 				%
@@ -449,8 +589,8 @@
 		%
 	{ module_imports_get_items(Module0, InterfaceItems1) },
 	( { Error = yes } ->
-		module_name_to_file_name(ModuleName, ".int", IntFileName),
-		module_name_to_file_name(ModuleName, ".int2", Int2FileName),
+		module_name_to_file_name(ModuleName, ".int", no, IntFileName),
+		module_name_to_file_name(ModuleName, ".int2", no, Int2FileName),
 		io__write_strings(["Error reading short interface files.\n",
 				"`", IntFileName, "' and ",
 				"`", Int2FileName, "' not written.\n"])
@@ -462,7 +602,7 @@
 				InterfaceItems2, ModuleName, yes, _, _, _, _),
 		io__get_exit_status(Status),
 		( { Status \= 0 } ->
-			module_name_to_file_name(ModuleName, ".int",
+			module_name_to_file_name(ModuleName, ".int", no,
 				IntFileName),
 			io__write_strings(["`", IntFileName, "' ",
 				"not written.\n"])
@@ -638,7 +778,7 @@
 	( 	
 		{ ExportWarning = yes }
 	->
-		module_name_to_file_name(ModuleName, ".m", FileName),
+		module_name_to_file_name(ModuleName, ".m", no, FileName),
 		{ sym_name_to_string(ModuleName, ModuleNameString) },
 		{ string__append_list(["interface for module `",
 			ModuleNameString, "' does not export anything."],
@@ -673,8 +813,8 @@
 		% create (e.g.) `foo.int.tmp'
 
 	{ string__append(Suffix, ".tmp", TmpSuffix) },
-	module_name_to_file_name(ModuleName, Suffix, OutputFileName),
-	module_name_to_file_name(ModuleName, TmpSuffix, TmpOutputFileName),
+	module_name_to_file_name(ModuleName, Suffix, yes, OutputFileName),
+	module_name_to_file_name(ModuleName, TmpSuffix, no, TmpOutputFileName),
 
 		% we need to add a `:- interface' declaration at the start
 		% of the item list
@@ -709,7 +849,7 @@
 %-----------------------------------------------------------------------------%
 
 touch_interface_datestamp(ModuleName, Ext) -->
-	module_name_to_file_name(ModuleName, Ext, OutputFileName),
+	module_name_to_file_name(ModuleName, Ext, yes, OutputFileName),
 
 	globals__io_lookup_bool_option(verbose, Verbose),
 	maybe_write_string(Verbose, "% Touching `"),
@@ -921,7 +1061,8 @@
 			; list__member(ModuleName, UsedModules)
 			}
 		->
-			module_name_to_file_name(ModuleName, ".m", FileName),
+			module_name_to_file_name(ModuleName, ".m", no,
+				FileName),
 			{ term__context_init(FileName, 1, Context) },
 			prog_out__write_context(Context),
 			report_warning("Warning: module `"),
@@ -945,7 +1086,7 @@
 :- mode warn_imported_ancestor(in, in, di, uo) is det.
 
 warn_imported_ancestor(ModuleName, AncestorName) -->
-	module_name_to_file_name(ModuleName, ".m", FileName),
+	module_name_to_file_name(ModuleName, ".m", no, FileName),
 	{ term__context_init(FileName, 1, Context) },
 	prog_out__write_context(Context),
 	report_warning("module `"),
@@ -987,7 +1128,8 @@
 		{ set__to_sorted_list(BothSet, BothList) },
 		globals__io_lookup_bool_option(warn_simple_code, WarnSimple),
 		( { WarnSimple = yes } ->
-			module_name_to_file_name(ModuleName, ".m", FileName),
+			module_name_to_file_name(ModuleName, ".m", no,
+				FileName),
 			{ term__context_init(FileName, 1, Context) },
 			prog_out__write_context(Context),
 			io__write_string("Warning:"),
@@ -1028,8 +1170,8 @@
 			IndirectDeps, _InclDeps, FactDeps0, _Items, _Error) },
 	globals__io_lookup_bool_option(verbose, Verbose),
 	{ module_name_to_make_var_name(ModuleName, MakeVarName) },
-	module_name_to_file_name(ModuleName, ".d", DependencyFileName),
-	module_name_to_file_name(ModuleName, ".trans_opt_date",
+	module_name_to_file_name(ModuleName, ".d", yes, DependencyFileName),
+	module_name_to_file_name(ModuleName, ".trans_opt_date", no,
 						TransOptDateFileName),
 	%
 	% To avoid problems with concurrent updates of `.d' files
@@ -1081,18 +1223,9 @@
 			io__nl(DepStream),
 			globals__io_lookup_bool_option(assume_gmake,
 				AssumeGmake),
-			( { AssumeGmake = no } ->
-				io__write_strings(DepStream,
-					[MakeVarName, ".fact_tables.os ="]),
-				write_file_dependencies_list(FactDeps, ".o",
-					DepStream),
-				io__write_strings(DepStream, [
-					"\n\n", 
-					MakeVarName, ".fact_tables.cs ="]),
-				write_file_dependencies_list(FactDeps, ".c",
-					DepStream),
-				io__nl(DepStream)
-			;
+			globals__io_lookup_bool_option(use_subdirs,
+				UseSubdirs),
+			( { AssumeGmake = yes, UseSubdirs = no } ->
 				io__write_strings(DepStream, [
 					"\n\n", MakeVarName,
 					".fact_tables.os = $(", MakeVarName,
@@ -1101,17 +1234,27 @@
 					".fact_tables.cs = $(", MakeVarName,
 					".fact_tables:%=%.c)\n\n"
 				])
+			;
+				io__write_strings(DepStream,
+					[MakeVarName, ".fact_tables.cs ="]),
+				write_fact_table_dependencies_list(ModuleName,
+					FactDeps, ".c", DepStream),
+				io__write_strings(DepStream, ["\n\n", 
+					MakeVarName, ".fact_tables.os ="]),
+				write_fact_table_dependencies_list(ModuleName,
+					FactDeps, ".o", DepStream),
+				io__nl(DepStream)
 			)
 		;
 			[]
 		),
 
-		module_name_to_file_name(ModuleName, ".optdate",
+		module_name_to_file_name(ModuleName, ".optdate", no,
 					OptDateFileName),
-		module_name_to_file_name(ModuleName, ".c", CFileName),
-		module_name_to_file_name(ModuleName, ".err", ErrFileName),
-		module_name_to_file_name(ModuleName, ".o", ObjFileName),
-		module_name_to_file_name(ModuleName, ".m", SourceFileName),
+		module_name_to_file_name(ModuleName, ".c", no, CFileName),
+		module_name_to_file_name(ModuleName, ".err", no, ErrFileName),
+		module_name_to_file_name(ModuleName, ".o", no, ObjFileName),
+		module_name_to_file_name(ModuleName, ".m", no, SourceFileName),
 		io__write_strings(DepStream, ["\n\n",
 			OptDateFileName, " ",
 			TransOptDateFileName, " ",
@@ -1183,8 +1326,10 @@
 			[]
 		),
 
-		module_name_to_file_name(ModuleName, ".date", DateFileName),
-		module_name_to_file_name(ModuleName, ".date0", Date0FileName),
+		module_name_to_file_name(ModuleName, ".date", no,
+						DateFileName),
+		module_name_to_file_name(ModuleName, ".date0", no,
+						Date0FileName),
 		io__write_strings(DepStream, [
 				"\n\n", DateFileName, " ",
 				Date0FileName, " : ",
@@ -1194,7 +1339,7 @@
 		write_dependencies_list(LongDeps, ".int3", DepStream),
 		write_dependencies_list(ShortDeps, ".int3", DepStream),
 
-		module_name_to_file_name(ModuleName, ".dir", DirFileName),
+		module_name_to_file_name(ModuleName, ".dir", no, DirFileName),
 		module_name_to_split_c_file_name(ModuleName, 0, ".o",
 			SplitCObj0FileName),
 		io__write_strings(DepStream, [
@@ -1229,7 +1374,8 @@
 	globals__io_lookup_bool_option(transitive_optimization, TransOpt),
 	( { TransOpt = yes } ->
 		globals__io_lookup_bool_option(verbose, Verbose),
-		module_name_to_file_name(ModuleName, ".d", DependencyFileName),
+		module_name_to_file_name(ModuleName, ".d", no,
+					DependencyFileName),
 		maybe_write_string(Verbose, "% Reading auto-dependency file `"),
 		maybe_write_string(Verbose, DependencyFileName),
 		maybe_write_string(Verbose, "'..."),
@@ -1237,8 +1383,8 @@
 		io__open_input(DependencyFileName, OpenResult),
 		( { OpenResult = ok(Stream) } ->
 			io__set_input_stream(Stream, OldStream),
-			module_name_to_file_name(ModuleName, ".trans_opt_date", 
-				TransOptDateFileName0),
+			module_name_to_file_name(ModuleName, ".trans_opt_date",
+				no, TransOptDateFileName0),
 			{ string__to_char_list(TransOptDateFileName0, 
 				TransOptDateFileName) },
 			{ list__append(TransOptDateFileName, [' ', ':'],
@@ -1325,7 +1471,7 @@
 	io__state::di, io__state::uo) is det.
 get_both_opt_deps([], _, [], []) --> [].
 get_both_opt_deps([Dep | Deps], IntermodDirs, OptDeps, TransOptDeps) -->
-	module_name_to_file_name(Dep, ".m", DepName), 
+	module_name_to_file_name(Dep, ".m", no, DepName), 
 	search_for_file(IntermodDirs, DepName, Result1),
 	get_both_opt_deps(Deps, IntermodDirs, OptDeps0, TransOptDeps0),
 	( { Result1 = yes } ->
@@ -1333,7 +1479,7 @@
 		{ TransOptDeps = [Dep | TransOptDeps0] },
 		io__seen
 	;
-		module_name_to_file_name(Dep, ".opt", OptName), 
+		module_name_to_file_name(Dep, ".opt", no, OptName), 
 		search_for_file(IntermodDirs, OptName, Result2),
 		( { Result2 = yes } ->
 			{ OptDeps = [Dep | OptDeps0] },
@@ -1341,7 +1487,7 @@
 		;
 			{ OptDeps = OptDeps0 }
 		),
-		module_name_to_file_name(Dep, ".trans_opt", TransOptName), 
+		module_name_to_file_name(Dep, ".trans_opt", no, TransOptName), 
 		search_for_file(IntermodDirs, TransOptName, Result3),
 		( { Result3 = yes } ->
 			{ TransOptDeps = [Dep | TransOptDeps0] },
@@ -1357,14 +1503,14 @@
 	list(module_name)::out, io__state::di, io__state::uo) is det.
 get_opt_deps([], _, _, []) --> [].
 get_opt_deps([Dep | Deps], IntermodDirs, Suffix, OptDeps) -->
-	module_name_to_file_name(Dep, ".m", DepName),
+	module_name_to_file_name(Dep, ".m", no, DepName),
 	search_for_file(IntermodDirs, DepName, Result1),
 	get_opt_deps(Deps, IntermodDirs, Suffix, OptDeps0),
 	( { Result1 = yes } ->
 		{ OptDeps = [Dep | OptDeps0] },
 		io__seen
 	;
-		module_name_to_file_name(Dep, Suffix, OptName),
+		module_name_to_file_name(Dep, Suffix, no, OptName),
 		search_for_file(IntermodDirs, OptName, Result2),
 		( { Result2 = yes } ->
 			{ OptDeps = [Dep | OptDeps0] },
@@ -1419,7 +1565,7 @@
 	globals__io_lookup_bool_option(generate_module_order, Order),
 	globals__io_lookup_bool_option(verbose, Verbose),
 	( { Order = yes } ->
-		module_name_to_file_name(Module, ".order", OrdFileName),
+		module_name_to_file_name(Module, ".order", yes, OrdFileName),
 		maybe_write_string(Verbose, "% Creating module order file `"),
 		maybe_write_string(Verbose, OrdFileName),
 		maybe_write_string(Verbose, "'...\n"),
@@ -1599,7 +1745,7 @@
 	io__state::di, io__state::uo) is det.
 generate_dependencies_write_dep_file(ModuleName, DepsMap) -->
 	globals__io_lookup_bool_option(verbose, Verbose),
-	module_name_to_file_name(ModuleName, ".dep", DepFileName),
+	module_name_to_file_name(ModuleName, ".dep", yes, DepFileName),
 	maybe_write_string(Verbose, "% Creating auto-dependency file `"),
 	maybe_write_string(Verbose, DepFileName),
 	maybe_write_string(Verbose, "'...\n"),
@@ -1641,12 +1787,11 @@
 	io__write_string(DepStream, "\n\n"),
 
 	globals__io_lookup_bool_option(assume_gmake, Gmake),
-	(
-		{ Gmake = yes },
+	globals__io_lookup_bool_option(use_subdirs, UseSubdirs),
+	( { Gmake = yes }, { UseSubdirs = no } ->
 		{ string__append(MakeVarName, ".ms", VarName) },
 		{ Basis = yes(VarName - ".m") }
 	;
-		{ Gmake = no },
 		{ Basis = no }
 	),
 
@@ -1769,14 +1914,14 @@
 	write_compact_dependencies_list(Modules, ".prof", Basis, DepStream),
 	io__write_string(DepStream, "\n\n"),
 
-	module_name_to_file_name(ModuleName, ".init", InitFileName),
-	module_name_to_file_name(ModuleName, "_init.c", InitCFileName),
-	module_name_to_file_name(ModuleName, "_init.s", InitAsmFileName),
-	module_name_to_file_name(ModuleName, "_init.o", InitObjFileName),
-	module_name_to_file_name(ModuleName, "_init.pic_o",
+	module_name_to_file_name(ModuleName, ".init", yes, InitFileName),
+	module_name_to_file_name(ModuleName, "_init.c", yes, InitCFileName),
+	module_name_to_file_name(ModuleName, "_init.s", no, InitAsmFileName),
+	module_name_to_file_name(ModuleName, "_init.o", yes, InitObjFileName),
+	module_name_to_file_name(ModuleName, "_init.pic_o", yes,
 							InitPicObjFileName),
 
-	module_name_to_file_name(ModuleName, "", ExeFileName),
+	module_name_to_file_name(ModuleName, "", no, ExeFileName),
 	io__write_strings(DepStream, [
 		ExeFileName, " : $(", MakeVarName, ".os) ",
 		InitObjFileName, " MLOBJS-", MakeVarName, "\n",
@@ -1785,8 +1930,8 @@
 		"\t	$(", MakeVarName, ".os) $(MLOBJS) $(MLLIBS)\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".split", SplitExeFileName),
-	module_name_to_file_name(ModuleName, ".split.a", SplitLibFileName),
+	module_name_to_file_name(ModuleName, ".split", yes, SplitExeFileName),
+	module_name_to_file_name(ModuleName, ".split.a", yes, SplitLibFileName),
 	io__write_strings(DepStream, [
 		SplitExeFileName, " : ", SplitLibFileName, " ",
 				InitObjFileName, "\n",
@@ -1806,12 +1951,12 @@
 		"\t$(RANLIB) $(RANLIBFLAGS) ", SplitLibFileName, "\n\n"
 	]),
 
-	module_name_to_lib_file_name("lib", ModuleName, "", LibTargetName),
-	module_name_to_lib_file_name("lib", ModuleName, ".a", LibFileName),
-	module_name_to_lib_file_name("lib", ModuleName,
-		".so", SharedLibFileName),
+	module_name_to_lib_file_name("lib", ModuleName, "", no, LibTargetName),
+	module_name_to_lib_file_name("lib", ModuleName, ".a", yes, LibFileName),
+	module_name_to_lib_file_name("lib", ModuleName, ".so", yes,
+							SharedLibFileName),
 	module_name_to_lib_file_name("lib", ModuleName,
-		".$(EXT_FOR_SHARED_LIB)", MaybeSharedLibFileName),
+		".$(EXT_FOR_SHARED_LIB)", no, MaybeSharedLibFileName),
 	io__write_strings(DepStream, [
 		".PHONY : ", LibTargetName, "\n",
 		LibTargetName, " : ",
@@ -1840,7 +1985,7 @@
 		"\t$(RANLIB) $(RANLIBFLAGS) ", LibFileName, "\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".dep", DepFileName),
+	module_name_to_file_name(ModuleName, ".dep", no, DepFileName),
 	io__write_strings(DepStream, [
 		InitFileName, " : ", DepFileName, "\n",
 		"\techo > ", InitFileName, "\n"
@@ -1854,8 +1999,9 @@
 			InitCFileName, "\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".nu", NU_ExeFileName),
-	module_name_to_file_name(ModuleName, ".nu.debug", NU_DebugExeFileName),
+	module_name_to_file_name(ModuleName, ".nu", yes, NU_ExeFileName),
+	module_name_to_file_name(ModuleName, ".nu.debug", yes,
+						NU_DebugExeFileName),
 	io__write_strings(DepStream, [
 		NU_ExeFileName, " : $(", MakeVarName, ".nos)\n",
 		"\t$(MNL) $(MNLFLAGS) -o ", NU_ExeFileName, " ",
@@ -1866,8 +2012,9 @@
 			"$(", MakeVarName, ".nos)\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".sicstus", SicstusExeFileName),
-	module_name_to_file_name(ModuleName, ".sicstus.debug",
+	module_name_to_file_name(ModuleName, ".sicstus", yes,
+						SicstusExeFileName),
+	module_name_to_file_name(ModuleName, ".sicstus.debug", yes,
 						SicstusDebugExeFileName),
 	io__write_strings(DepStream, [
 		SicstusExeFileName, " : $(", MakeVarName, ".qls)\n",
@@ -1879,22 +2026,27 @@
 			" $(", MakeVarName, ".qls)\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".check", CheckTargetName),
-	module_name_to_file_name(ModuleName, ".ints", IntsTargetName),
-	module_name_to_file_name(ModuleName, ".int3s", Int3sTargetName),
-	module_name_to_file_name(ModuleName, ".opts", OptsTargetName),
-	module_name_to_file_name(ModuleName, ".trans_opts",
+	module_name_to_file_name(ModuleName, ".check", no, CheckTargetName),
+	module_name_to_file_name(ModuleName, ".ints", no, IntsTargetName),
+	module_name_to_file_name(ModuleName, ".int3s", no, Int3sTargetName),
+	module_name_to_file_name(ModuleName, ".opts", no, OptsTargetName),
+	module_name_to_file_name(ModuleName, ".trans_opts", no,
 						TransOptsTargetName),
 	io__write_strings(DepStream, [
+		".PHONY : ", CheckTargetName, "\n",
 		CheckTargetName, " : $(", MakeVarName, ".errs)\n\n",
+		".PHONY : ", IntsTargetName, "\n",
 		IntsTargetName, " : $(", MakeVarName, ".dates)\n\n",
+		".PHONY : ", Int3sTargetName, "\n",
 		Int3sTargetName, " : $(", MakeVarName, ".date3s)\n\n",
+		".PHONY : ", OptsTargetName, "\n",
 		OptsTargetName, " : $(", MakeVarName, ".optdates)\n\n",
+		".PHONY : ", TransOptsTargetName, "\n",
 		TransOptsTargetName, " : $(", MakeVarName,
 						".trans_opt_dates)\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".clean", CleanTargetName),
+	module_name_to_file_name(ModuleName, ".clean", no, CleanTargetName),
 	io__write_strings(DepStream, [
 		"clean : ", CleanTargetName, "\n"
 	]),
@@ -1917,7 +2069,7 @@
 
 	io__write_string(DepStream, "\n"),
 
-	module_name_to_file_name(ModuleName, ".change_clean",
+	module_name_to_file_name(ModuleName, ".change_clean", no,
 			ChangeCleanTargetName),
 	io__write_strings(DepStream, [
 		".PHONY : ", ChangeCleanTargetName, "\n",
@@ -1939,7 +2091,7 @@
 			DepFileName, "\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".realclean",
+	module_name_to_file_name(ModuleName, ".realclean", no,
 			RealCleanTargetName),
 	io__write_strings(DepStream, [
 		"realclean : ", RealCleanTargetName, "\n"
@@ -1958,8 +2110,9 @@
 		"\t-rm -f $(", MakeVarName, ".ds)\n",
 		"\t-rm -f $(", MakeVarName, ".hs)\n"
 	]),
-	module_name_to_file_name(ModuleName, ".nu.save", NU_SaveExeFileName),
-	module_name_to_file_name(ModuleName, ".nu.debug.save",
+	module_name_to_file_name(ModuleName, ".nu.save", no,
+						NU_SaveExeFileName),
+	module_name_to_file_name(ModuleName, ".nu.debug.save", no,
 						NU_DebugSaveExeFileName),
 	io__write_strings(DepStream, [
 		"\t-rm -f ",
@@ -1978,8 +2131,9 @@
 			DepFileName, "\n\n"
 	]),
 
-	module_name_to_file_name(ModuleName, ".clean_nu", CleanNU_TargetName),
-	module_name_to_file_name(ModuleName, ".clean_sicstus",
+	module_name_to_file_name(ModuleName, ".clean_nu", no,
+						CleanNU_TargetName),
+	module_name_to_file_name(ModuleName, ".clean_sicstus", no,
 						CleanSicstusTargetName),
 	io__write_strings(DepStream, [
 		"clean_nu : ", CleanNU_TargetName, "\n",
@@ -2050,11 +2204,24 @@
 
 write_dependencies_list([], _, _) --> [].
 write_dependencies_list([Module | Modules], Suffix, DepStream) -->
-	module_name_to_file_name(Module, Suffix, FileName),
+	module_name_to_file_name(Module, Suffix, no, FileName),
 	io__write_string(DepStream, " \\\n\t"),
 	io__write_string(DepStream, FileName),
 	write_dependencies_list(Modules, Suffix, DepStream).
 
+:- pred write_fact_table_dependencies_list(module_name, list(file_name),
+			string, io__output_stream, io__state, io__state).
+:- mode write_fact_table_dependencies_list(in, in, in, in, di, uo) is det.
+
+write_fact_table_dependencies_list(_, [], _, _) --> [].
+write_fact_table_dependencies_list(Module, [FactTable | FactTables], Suffix,
+			DepStream) -->
+	fact_table_file_name(Module, FactTable, Suffix, FileName),
+	io__write_string(DepStream, " \\\n\t"),
+	io__write_string(DepStream, FileName),
+	write_fact_table_dependencies_list(Module, FactTables, Suffix,
+			DepStream).
+
 :- pred write_file_dependencies_list(list(string), string, io__output_stream,
 				io__state, io__state).
 :- mode write_file_dependencies_list(in, in, in, di, uo) is det.
@@ -2163,7 +2330,7 @@
 %-----------------------------------------------------------------------------%
 
 read_mod(ModuleName, Extension, Descr, Search, Items, Error) -->
-	module_name_to_file_name(ModuleName, Extension, FileName),
+	module_name_to_file_name(ModuleName, Extension, no, FileName),
 	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
 	maybe_write_string(VeryVerbose, "% "),
 	maybe_write_string(VeryVerbose, Descr),
@@ -2196,7 +2363,7 @@
 */
 
 read_mod_ignore_errors(ModuleName, Extension, Descr, Search, Items, Error) -->
-	module_name_to_file_name(ModuleName, Extension, FileName),
+	module_name_to_file_name(ModuleName, Extension, no, FileName),
 	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
 	maybe_write_string(VeryVerbose, "% "),
 	maybe_write_string(VeryVerbose, Descr),
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.224
diff -u -r1.224 options.m
--- options.m	1998/03/03 17:35:33	1.224
+++ options.m	1998/03/18 05:35:21
@@ -268,6 +268,7 @@
 		;	search_directories
 		;	intermod_directories
 		;	use_search_directories_for_intermod
+		;	use_subdirs
 		;	help.
 
 :- implementation.
@@ -568,6 +569,7 @@
 	intermod_directories	-	accumulating([]),
 	use_search_directories_for_intermod
 				-	bool(yes),
+	use_subdirs		-	bool(no),
 	help 			-	bool(no)
 ]).
 
@@ -883,6 +885,7 @@
 long_option("intermod-directory",	intermod_directories).
 long_option("use-search-directories-for-intermod",
 					use_search_directories_for_intermod).	
+long_option("use-subdirs",		use_subdirs).	
 
 %-----------------------------------------------------------------------------%
 
@@ -1858,8 +1861,10 @@
 	io__write_string("\t--no-use-search-directories-for-intermod\n"),
 	io__write_string("\t\tDon't add arguments to `--search-directory' to the list\n"),
 	io__write_string("\t\tof directories to search for `.opt' files - use only the\n"),
-	io__write_string("\t\tdirectories given by `--intermod-directory'.\n").
-
+	io__write_string("\t\tdirectories given by `--intermod-directory'.\n"),
+	io__write_string("\t--use-subdirs\n"),
+	io__write_string("\t\tGenerate intermediate files in a `Mercury' subdirectory,\n"),
+	io__write_string("\t\trather than generating them in the current directory.\n").
 
 :- end_module options.
 
Index: compiler/termination.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/termination.m,v
retrieving revision 1.10
diff -u -r1.10 termination.m
--- termination.m	1998/03/17 00:28:15	1.10
+++ termination.m	1998/03/17 03:22:05
@@ -668,7 +668,7 @@
 
 termination__make_opt_int(PredIds, Module) -->
 	{ module_info_name(Module, ModuleName) },
-	module_name_to_file_name(ModuleName, ".opt.tmp", OptFileName),
+	module_name_to_file_name(ModuleName, ".opt.tmp", no, OptFileName),
 	io__open_append(OptFileName, OptFileRes),
 	( { OptFileRes = ok(OptFile) } ->
 		io__set_output_stream(OptFile, OldStream),
Index: compiler/trans_opt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trans_opt.m,v
retrieving revision 1.8
diff -u -r1.8 trans_opt.m
--- trans_opt.m	1998/03/17 00:28:17	1.8
+++ trans_opt.m	1998/03/17 03:22:57
@@ -83,7 +83,8 @@
 
 trans_opt__write_optfile(Module) -->
 	{ module_info_name(Module, ModuleName) },
-	module_name_to_file_name(ModuleName, ".trans_opt.tmp", TmpOptName),
+	module_name_to_file_name(ModuleName, ".trans_opt.tmp", yes,
+					TmpOptName),
 	io__open_output(TmpOptName, Result),
 	(
 		{ Result = error(Error) },
@@ -116,7 +117,8 @@
 		io__set_output_stream(OldStream, _),
 		io__close_output(Stream),
 
-		module_name_to_file_name(ModuleName, ".trans_opt", OptName),
+		module_name_to_file_name(ModuleName, ".trans_opt", no,
+				OptName),
 		update_interface(OptName),
 		touch_interface_datestamp(ModuleName, ".trans_opt_date")
 	).
@@ -204,7 +206,7 @@
 	maybe_flush_output(VeryVerbose),
 	maybe_write_string(VeryVerbose, "% done.\n"),
 
-	module_name_to_file_name(Import, ".trans_opt", FileName),
+	module_name_to_file_name(Import, ".trans_opt", no, FileName),
 	prog_io__read_module(FileName, Import, yes,
 			ModuleError, Messages, Items1),
 	update_error_status(ModuleError, Messages, Error0, Error1),
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.47
diff -u -r1.47 unused_args.m
--- unused_args.m	1998/03/17 00:28:19	1.47
+++ unused_args.m	1998/03/17 03:23:12
@@ -98,7 +98,8 @@
 	globals__io_lookup_bool_option(make_optimization_interface, MakeOpt),
 	( { MakeOpt = yes } ->
 		{ module_info_name(ModuleInfo0, ModuleName) },
-		module_name_to_file_name(ModuleName, ".opt.tmp", OptFileName),
+		module_name_to_file_name(ModuleName, ".opt.tmp", no,
+				OptFileName),
 		io__open_append(OptFileName, OptFileRes),
 		( { OptFileRes = ok(OptFile) } ->
 			{ MaybeOptFile = yes(OptFile) }
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.119
diff -u -r1.119 user_guide.texi
--- user_guide.texi	1998/03/03 17:39:01	1.119
+++ user_guide.texi	1998/03/18 05:34:29
@@ -128,6 +128,15 @@
 whose name should be the same as the filename without
 the @samp{.m} extension.
 
+The Mercury implementation uses a variety of intermediate files, which
+are described below.  But all you really need to know is how to name
+source files.  For historical reasons, the default behaviour is for
+intermediate files to be created in the current directory, but if you
+use the @samp{--use-subdirs} option to @samp{mmc} or @samp{mmake}, all
+these intermediate files will be created in a @file{Mercury}
+subdirectory, where you can happily ignore them.
+Thus you may wish to skip the rest of this chapter.
+
 Files ending in @file{.int}, @file{.int0}, @file{.int2} and @file{.int3}
 are interface files; these are generated automatically by the compiler,
 using the @samp{--make-interface} (or @samp{--make-int}),
@@ -193,6 +202,9 @@
 all the steps listed below, using automatic dependency analysis
 to ensure that things are done in the right order, and that
 steps are not repeated unnecessarily.
+If you use Mmake, then you don't need to understand the details
+of how the Mercury implementation goes about building programs.
+Thus you may wish to skip the rest of this chapter.
 
 To compile a module to object code without creating an executable,
 use the command
@@ -2555,6 +2567,10 @@
 @item --use-search-directories-for-intermod
 Append the arguments of all -I options to the list of directories
 to be searched for @samp{.opt} files.
+
+ at item --use-subdirs
+Create intermediate files in a @file{Mercury} subdirectory,
+rather than in the current directory.
 
 @sp 1
 @item -?
Index: library/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mmakefile,v
retrieving revision 1.24
diff -u -r1.24 Mmakefile
--- Mmakefile	1998/03/11 05:57:33	1.24
+++ Mmakefile	1998/03/18 05:53:09
@@ -317,6 +317,12 @@
 			cp $$file $$target; \
 		fi; \
 	done
+	# The following is needed to support the `--use-subdirs' option
+	[ -d $(INSTALL_INT_DIR)/Mercury ] || \
+		mkdir -p $(INSTALL_INT_DIR)/Mercury
+	for dir in ints int2s int3s opts trans_opts; do \
+		ln -s .. $(INSTALL_INT_DIR)/Mercury/$$dir; \
+	done
 
 .PHONY: install_init
 install_init: libmercury.init
Index: scripts/Mmake.rules
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.rules,v
retrieving revision 1.52
diff -u -r1.52 Mmake.rules
--- Mmake.rules	1998/03/09 02:22:21	1.52
+++ Mmake.rules	1998/03/18 04:53:16
@@ -6,6 +6,9 @@
 
 # Mmake.rules - rules for building Mercury programs
 
+# N.B. All the builtin rules must use $@ as the target, so that they work
+# when $(VPATH) is set.
+
 main_target: $(MAIN_TARGET)
 
 #-----------------------------------------------------------------------------#
@@ -19,38 +22,153 @@
 		.i .s .pic_s \
 		.ql .pl
 
-.PRECIOUS: %.date0 %.date %.date3 %.optdate %.trans_opt_date
+ifeq ($(MMAKE_USE_SUBDIRS),yes)
 
-# All the builtin rules must use $@ as the target, so that they work
-# when $(VPATH) is set.
+MCFLAGS += --use-subdirs
 
-.m.no:
+SUBDIR=Mercury/
+# SUBDIR=
+
+.PRECIOUS: $(SUBDIR)date0s/%.date0
+.PRECIOUS: $(SUBDIR)dates/%.date
+.PRECIOUS: $(SUBDIR)date3s/%.date3
+.PRECIOUS: $(SUBDIR)optdates/%.optdate
+.PRECIOUS: $(SUBDIR)trans_opt_dates/%.trans_opt_date
+
+$(SUBDIR)nos/%.no : %.m
 	$(MNC) $(MNCFLAGS) -o $@ $<
 
-.nl.no:
+$(SUBDIR)nos/%.no : %.nl
 	$(MNC) $(MNCFLAGS) -o $@ $<
 
-.m.ql:
+$(SUBDIR)nos/%.ql : %.m
 	$(MSC) $(MSCFLAGS) -o $@ $<
 
-.nl.ql:
+$(SUBDIR)nos/%.ql : %.nl
 	$(MSC) $(MSCFLAGS) -o $@ $<
 
-.m.pl:
-	sicstus_conv $<
+$(SUBDIR)date0s/%.date0 : %.m
+	$(MCPI) $(MCPIFLAGS) $<
 
-.nl.pl:
-	sicstus_conv $<
+$(SUBDIR)dates/%.date : %.m
+	$(MCI) $(MCIFLAGS) $<
 
-# The `touch' is necessary, since otherwise if
-# the old .err file was of size zero and
-# the new .err file is also of size zero,
-# the time-stamp doesn't get updated!
-# (Is that a bug in unix? In bash?)
+$(SUBDIR)date3s/%.date3 : %.m
+	$(MCSI) $(MCSIFLAGS) $<
 
-.m.err:
-	$(MC) $(MCFLAGS) --errorcheck-only $< > $@ 2>&1
-	@touch $@
+$(SUBDIR)optdates/%.optdate : %.m
+	$(MCOI) $(MCOIFLAGS) $<
+
+$(SUBDIR)trans_opt_dates/%.trans_opt_date : %.m
+	$(MCTOI) $(MCTOIFLAGS) $<
+
+# Be very careful about changing the following rules.
+# The `@:' is a silent do-nothing command.
+# It is used to force GNU Make to recheck the timestamp
+# on the target file.  (It is a pity that GNU Make doesn't
+# have a way of handling these sorts of rules in a nicer manner.)
+
+$(SUBDIR)int0s/%.int0 : $(SUBDIR)date0s/%.date0
+	@:
+
+$(SUBDIR)ints/%.int : $(SUBDIR)dates/%.date
+	@:
+
+$(SUBDIR)int2s/%.int2 : $(SUBDIR)dates/%.date
+	@:
+
+$(SUBDIR)int3s/%.int3 : $(SUBDIR)date3s/%.date3
+	@:
+
+$(SUBDIR)opts/%.opt : $(SUBDIR)opt_dates/%.opt_date
+	@:
+
+$(SUBDIR)trans_opts/%.trans_opt : $(SUBDIR)trans_opt_dates/%.trans_opt_date
+	@:
+
+%.dep : $(SUBDIR)deps/%.dep
+
+$(SUBDIR)deps/%.dep: %.m
+	$(MCD) $(MCDFLAGS) $<
+
+# When creating the dependencies, we need to create the int3s
+# in order to get things started.  This should not be necessary,
+# but there seem to be some bugs in GNU Make with regard to
+# the combination of rule chaining and subdirectories.
+# I have sent off a bug report to the GNU Make maintainers (18 March 1998).
+#	-fjh.
+
+%.depend : %.m
+	$(MCD) $(MCDFLAGS) $<
+	-rm -f $(SUBDIR)cs/$*_init.c
+	$(MMAKE) $(MAKEOVERRIDES) $(MMAKEFLAGS) $*.int3s
+
+%.doit : $(SUBDIR)deps/%.dep
+	sed -e ':a' -e '/\\/N' -e 's/\\\n	//' -e 't a' $< |  \
+	tee tmp | \
+	grep 'srcs *=' | \
+	sed	-e 's/.*=/:-[ '\''nu_library.doit'\'', /' \
+		-e 's/\.nl/,/g' \
+		-e 's/$$/ portray ]./' \
+		> $@
+
+$(SUBDIR)cs/%.c : %.m
+	rm -f $(SUBDIR)cs/$*.c
+	$(MCG) $(GRADEFLAGS) $(MCGFLAGS) $< > $*.err 2>&1
+
+$(SUBDIR)os/%.o : $(SUBDIR)cs/%.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) -c $< -o $@
+
+# If we aren't removing the .c files, we generate .pic_o files
+# without invoking mmake.
+ifeq ($(RM_C),:)
+$(SUBDIR)os/%.pic_o : $(SUBDIR)cs/%.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) $(CFLAGS_FOR_PIC) -c $< -o $@
+endif
+
+%.s: $(SUBDIR)cs/%.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) -S $< -o $@
+
+%.pic_s: $(SUBDIR)cs/%.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) $(CFLAGS_FOR_PIC) -S $< -o $@
+
+%.i: $(SUBDIR)cs/%.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) -E $< > $@
+
+# If we aren't removing the .c files, we don't need to invoke mmake
+# for each .c file
+ifneq ($(RM_C),:)
+$(SUBDIR)os/%.o : %.m
+	$(MMAKE_MAKE_CMD) $(MAKEOVERRIDES) $(SUBDIR)cs/$*.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) -c $(SUBDIR)cs/$*.c -o $@
+	$(RM_C) $(SUBDIR)cs/$*.c
+
+$(SUBDIR)os/%.pic_o : %.m
+	$(MMAKE_MAKE_CMD) $(MAKEOVERRIDES) $(SUBDIR)cs/$*.c
+	$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) $(CFLAGS_FOR_PIC) \
+		-c $(SUBDIR)cs/$*.c -o $@
+
+endif
+
+$(SUBDIR)dirs/%.dir/*.o: %.m
+	rm -f $@
+	$(MCS) $(GRADEFLAGS) $(MCSFLAGS) $<
+
+else # USE_SUBDIRS=no
+
+.PRECIOUS: %.date0 %.date %.date3 %.optdate %.trans_opt_date
+
+.m.no:
+	$(MNC) $(MNCFLAGS) -o $@ $<
+
+.nl.no:
+	$(MNC) $(MNCFLAGS) -o $@ $<
+
+.m.ql:
+	$(MSC) $(MSCFLAGS) -o $@ $<
+
+.nl.ql:
+	$(MSC) $(MSCFLAGS) -o $@ $<
 
 .m.date0:
 	$(MCPI) $(MCPIFLAGS) $<
@@ -91,9 +209,6 @@
 .trans_opt_date.trans_opt:
 	@:
 
-.m.ugly:
-	$(MC) --convert-to-mercury $(MCFLAGS) $<
-
 .m.dep:
 	@-[ ! -f $*.dep ] || chmod +w $*.dep
 	$(MCD) $(MCDFLAGS) $<
@@ -151,6 +266,29 @@
 %.dir/*.o: %.m
 	rm -f $@
 	$(MCS) $(GRADEFLAGS) $(MCSFLAGS) $<
+
+endif	# !USE_SUBDIRS
+
+.m.pl:
+	sicstus_conv $<
+
+.nl.pl:
+	sicstus_conv $<
+
+# The `touch' is necessary, since otherwise if
+# the old .err file was of size zero and
+# the new .err file is also of size zero,
+# the time-stamp doesn't get updated!
+# (Is that a bug in unix? In bash?)
+
+.m.err:
+	$(MC) $(MCFLAGS) --errorcheck-only $< > $@ 2>&1
+	@touch $@
+
+.m.ugly:
+	$(MC) --convert-to-mercury $(MCFLAGS) $<
+
+#-----------------------------------------------------------------------------#
 
 MLOBJS-%: $(MLOBJS)
 	@
Index: scripts/mmake.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/mmake.in,v
retrieving revision 1.14
diff -u -r1.14 mmake.in
--- mmake.in	1997/07/27 15:09:36	1.14
+++ mmake.in	1998/03/18 05:58:41
@@ -19,6 +19,9 @@
 Name: mmake -- Mercury Make
 Usage: mmake [<mmake options>] [-- <make options>] <target>...
 Options:
+	--use-subdirs:
+		Build intermediate files in subdirectories,
+		rather than in the current directory.
 	-s, --save-makefile:
 		Save the generated makefile to \`Mmake.makefile'.
 		This is useful for tracking down syntax errors in
@@ -60,6 +63,7 @@
 MMAKE=$0
 verbose=false
 save_makefile=false
+use_subdirs=${MMAKE_USE_SUBDIRS=no}
 
 while [ $# -gt 0 ]; do
 	case $1 in
@@ -67,16 +71,34 @@
 			echo "$Help"
 			exit 0
 			;;
+		--use-subdirs)
+			use_subdirs=yes
+			shift
+			;;
+		--no-use-subdirs)
+			use_subdirs=no
+			shift
+			;;
 		-s|--save-makefile)
 			save_makefile=true
 			MMAKE="$MMAKE $1"
 			shift
 			;;
+		-s-|--no-save-makefile)
+			save_makefile=false
+			MMAKE="$MMAKE $1"
+			shift
+			;;
 		-v|--verbose)
 			verbose=true
 			MMAKE="$MMAKE $1"
 			shift
 			;;
+		-v-|--no-verbose)
+			verbose=false
+			MMAKE="$MMAKE $1"
+			shift
+			;;
 		--)	
 			MMAKE="$MMAKE $1"
 			shift
@@ -97,16 +119,30 @@
 		mmake=""
 	fi
 fi
-if [ "`echo *.dep`" = "*.dep" ]; then
-	deps=""
-else
-	deps="*.dep"
-fi
-if [ "`echo *.d`" = "*.d" ]; then
-	ds=""
-else
-	ds="*.d"
-fi
+case $use_subdirs in
+	no)
+		deps="`echo *.dep`"
+		if [ "$deps" = "*.dep" ]; then
+			deps=""
+		fi
+		ds="`echo *.d`"
+		if [ "$ds" = "*.d" ]; then
+			ds=""
+		fi
+		;;
+	yes)
+		deps="`echo Mercury/deps/*.dep`"
+		if [ "$deps" = "Mercury/deps/*.dep" ]; then
+			deps=""
+		fi
+		ds="`echo Mercury/ds/*.d`"
+		if [ "$ds" = "Mercury/ds/*.d" ]; then
+			ds=""
+		fi
+		;;
+esac
+
+MMAKE_USE_SUBDIRS=$use_subdirs
 
 if $save_makefile; then
 	tmp=Mmake.makefile
@@ -122,6 +158,8 @@
 	echo export MMAKE
 	echo MMAKE_MAKE_CMD=$MMAKE_MAKE_CMD
 	echo export MMAKE_MAKE_CMD
+	echo MMAKE_USE_SUBDIRS=$MMAKE_USE_SUBDIRS
+	echo export MMAKE_USE_SUBDIRS
 	echo MERCURY_INT_DIR=$MERCURY_INT_DIR
 	echo export MERCURY_INT_DIR
 	echo MERCURY_DEFAULT_GRADE=$MERCURY_DEFAULT_GRADE
@@ -131,6 +169,7 @@
 fi
 export MMAKE
 export MMAKE_MAKE_CMD
+export MMAKE_USE_SUBDIRS
 export MERCURY_INT_DIR
 export MERCURY_DEFAULT_GRADE
 cat ${MMAKE_VARS} $deps $ds $mmake ${MMAKE_RULES} > $tmp
-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list