[m-rev.] for review: mmc --make [2]
Simon Taylor
stayl at cs.mu.OZ.AU
Wed Feb 6 02:20:43 AEDT 2002
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.213
diff -u -u -r1.213 modules.m
--- compiler/modules.m 30 Jan 2002 05:08:44 -0000 1.213
+++ compiler/modules.m 5 Feb 2002 09:37:21 -0000
@@ -198,8 +198,8 @@
%-----------------------------------------------------------------------------%
- % make_private_interface(SourceFileName, ModuleName,
- % MaybeTimestamp, Items):
+ % make_private_interface(SourceFileName, SourceFileModuleName,
+ % ModuleName, MaybeTimestamp, Items):
% Given a source file name and module name,
% the timestamp of the source file,
% and the list of items in that module,
@@ -208,20 +208,21 @@
% the module, including those in the `implementation'
% section; it is used when compiling sub-modules.)
%
-:- pred make_private_interface(file_name, module_name,
+:- pred make_private_interface(file_name, module_name, module_name,
maybe(timestamp), item_list, io__state, io__state).
-:- mode make_private_interface(in, in, in, in, di, uo) is det.
+:- mode make_private_interface(in, in, in, in, in, di, uo) is det.
- % make_interface(SourceFileName, ModuleName, MaybeTimestamp, Items):
+ % make_interface(SourceFileName, SourceFileModuleName,
+ % ModuleName, MaybeTimestamp, Items):
% Given a source file name and module name,
% the timestamp of the source file,
% and the list of items in that module,
% output the long (`.int') and short (`.int2') interface files
% for the module.
%
-:- pred make_interface(file_name, module_name, maybe(timestamp),
+:- pred make_interface(file_name, module_name, module_name, maybe(timestamp),
item_list, io__state, io__state).
-:- mode make_interface(in, in, in, in, di, uo) is det.
+:- mode make_interface(in, in, in, in, in, di, uo) is det.
% Output the unqualified short interface file to <module>.int3.
%
@@ -253,6 +254,10 @@
module_imports(
source_file_name :: file_name,
% The source file
+ source_file_module_name :: module_name,
+ % The name of the top-level module in
+ % the source file containing the module
+ % that we are compiling.
module_name :: module_name,
% The module (or sub-module)
% that we are compiling.
@@ -267,10 +272,15 @@
% in the implementation.
indirect_deps :: list(module_name),
% The list of modules it indirectly imports
+ children :: list(module_name),
public_children :: list(module_name),
% The list of its public children,
% i.e. child modules that it includes
% in the interface section.
+ nested_children :: list(module_name),
+ % The modules included in the same source
+ % file. This field is only set for the
+ % top-level module in each file.
fact_table_deps :: list(string),
% The list of filenames for fact tables
% in this module.
@@ -280,16 +290,25 @@
foreign_import_module_info :: foreign_import_module_info,
% The `:- pragma foreign_import_module'
% declarations.
+ contains_foreign_export :: contains_foreign_export,
+ % Does the module contain any
+ % `:- pragma export' declarations.
items :: item_list,
% The contents of the module and its imports
error :: module_error,
% Whether an error has been encountered
% when reading in this module.
- maybe_timestamps :: maybe(module_timestamps)
+ maybe_timestamps :: maybe(module_timestamps),
% If we are doing smart recompilation,
% we need to keep the timestamps of the
% modules read in.
+
+ has_main :: has_main,
+ % Does this module contain main/2.
+
+ module_dir :: dir_name
+ % The directory containing the module source.
).
:- type contains_foreign_code
@@ -297,6 +316,15 @@
; no_foreign_code
; unknown.
+:- type contains_foreign_export
+ ---> contains_foreign_export
+ ; no_foreign_export.
+
+:- type has_main
+ ---> has_main
+ ; no_main
+ .
+
% When doing smart recompilation record for each module
% the suffix of the file that was read and the modification
% time of the file.
@@ -386,6 +414,10 @@
:- pred strip_off_interface_decl(item_list, item_list).
:- mode strip_off_interface_decl(in, out) is det.
+ % Remove all the imported items the list.
+:- pred strip_imported_items(item_list, item_list).
+:- mode strip_imported_items(in, out) is det.
+
%-----------------------------------------------------------------------------%
% Given a module (well, a list of items), split it into
@@ -403,10 +435,15 @@
%-----------------------------------------------------------------------------%
- % grab_imported_modules(SourceFileName, ModuleName, ReadModules,
+ % grab_imported_modules(SourceFileName, SourceFileModuleName,
+ % ModuleName, NestedSubModules, ReadModules,
% ModuleTimestamp, Items, Module, Error)
- % Given a source file name and module name,
- % and the list of items in that module,
+ % Given a source file name and the top-level module
+ % name in that file, the current module name,
+ % the nested sub-modules in the file if this module is
+ % the top-level module,
+ % the timestamp of the file SourceFileName
+ % and the list of items in the current module,
% read in the private interface files for all the parent modules,
% the long interface files for all the imported modules,
% and the short interface files for all the indirectly imported
@@ -415,13 +452,14 @@
% ReadModules contains the interface files read during
% recompilation checking.
%
-:- pred grab_imported_modules(file_name, module_name, read_modules,
- maybe(timestamp), item_list, module_imports,
- module_error, io__state, io__state).
-:- mode grab_imported_modules(in, in, in, in, in, out, out, di, uo) is det.
+:- pred grab_imported_modules(file_name, module_name, module_name,
+ list(module_name), read_modules, maybe(timestamp),
+ item_list, module_imports, module_error, io__state, io__state).
+:- mode grab_imported_modules(in, in, in, in, in, in, in,
+ out, out, di, uo) is det.
- % grab_unqual_imported_modules(SourceFileName, ModuleName,
- % Items, Module, Error):
+ % grab_unqual_imported_modules(SourceFileName, SourceFileModuleName,
+ % ModuleName, Items, Module, Error):
% Similar to grab_imported_modules, but only reads in
% the unqualified short interfaces (.int3s),
% and the .int0 files for parent modules,
@@ -430,9 +468,9 @@
% Does not set the `PublicChildren' or `FactDeps'
% fields of the module_imports structure.
-:- pred grab_unqual_imported_modules(file_name, module_name, item_list,
- module_imports, module_error, io__state, io__state).
-:- mode grab_unqual_imported_modules(in, in, in, out, out, di, uo) is det.
+:- pred grab_unqual_imported_modules(file_name, module_name, module_name,
+ item_list, module_imports, module_error, io__state, io__state).
+:- mode grab_unqual_imported_modules(in, in, in, in, out, out, di, uo) is det.
% process_module_long_interfaces(ReadModules, NeedQualifier, Imports,
% Ext, IndirectImports0, IndirectImports, Module0, Module):
@@ -571,6 +609,13 @@
:- pred get_ancestors(module_name, list(module_name)).
:- mode get_ancestors(in, out) is det.
+ % init_dependencies(FileName, SourceFileModuleName, NestedModuleNames,
+ % Error, Globals, ModuleName - Items, ModuleImports).
+:- pred init_dependencies(file_name, module_name, list(module_name),
+ module_error, globals, pair(module_name, item_list),
+ module_imports).
+:- mode init_dependencies(in, in, in, in, in, in, out) is det.
+
%-----------------------------------------------------------------------------%
% touch_interface_datestamp(ModuleName, Ext).
@@ -590,11 +635,14 @@
:- pred touch_datestamp(file_name, io__state, io__state).
:- mode touch_datestamp(in, di, uo) is det.
- % update_interface(FileName)
+ % update_interface(FileName, Succeeded)
%
% Call the shell script mercury_update_interface to update the
% interface file FileName if it has changed.
+:- pred update_interface(string, bool, io__state, io__state).
+:- mode update_interface(in, out, di, uo) is det.
+
:- pred update_interface(string, io__state, io__state).
:- mode update_interface(in, di, uo) is det.
@@ -620,7 +668,7 @@
:- implementation.
:- import_module llds_out, passes_aux, prog_out, prog_util, mercury_to_mercury.
:- import_module prog_io_util, options, module_qual, foreign.
-:- import_module recompilation_version.
+:- import_module make, recompilation_version.
:- import_module string, map, term, varset, dir, library.
:- import_module assoc_list, relation, char, require.
@@ -922,9 +970,10 @@
% Read in the .int3 files that the current module depends on,
% and use these to qualify all the declarations
% as much as possible. Then write out the .int0 file.
-make_private_interface(SourceFileName, ModuleName, MaybeTimestamp, Items0) -->
- grab_unqual_imported_modules(SourceFileName, ModuleName, Items0,
- Module, Error),
+make_private_interface(SourceFileName, SourceFileModuleName, ModuleName,
+ MaybeTimestamp, Items0) -->
+ grab_unqual_imported_modules(SourceFileName, SourceFileModuleName,
+ ModuleName, Items0, Module, Error),
%
% Check whether we succeeded
%
@@ -970,13 +1019,14 @@
% Read in the .int3 files that the current module depends on,
% and use these to qualify all items in the interface as much as
% possible. Then write out the .int and .int2 files.
-make_interface(SourceFileName, ModuleName, MaybeTimestamp, Items0) -->
+make_interface(SourceFileName, SourceFileModuleName, ModuleName,
+ MaybeTimestamp, Items0) -->
{ get_interface(Items0, InterfaceItems0) },
%
% Get the .int3 files for imported modules
%
- grab_unqual_imported_modules(SourceFileName, ModuleName,
- InterfaceItems0, Module0, Error),
+ grab_unqual_imported_modules(SourceFileName, SourceFileModuleName,
+ ModuleName, InterfaceItems0, Module0, Error),
%
% Check whether we succeeded
@@ -1043,6 +1093,9 @@
%-----------------------------------------------------------------------------%
+strip_imported_items(Items0, Items) :-
+ strip_imported_items(Items0, [], Items).
+
:- pred strip_imported_items(item_list::in, item_list::in,
item_list::out) is det.
@@ -1231,8 +1284,7 @@
(
{ VerboseErrors = yes }
->
- io__stderr_stream(StdErr),
- io__write_strings(StdErr, [ "\t\t",
+ io__write_strings([ "\t\t",
"To be useful, a module should export something.\n\t\t",
"A file should contain at least one declaration other than\n\t\t",
"`:- import_module' in its interface section(s).\n\t\t",
@@ -1319,6 +1371,14 @@
% necessary
update_interface(OutputFileName) -->
+ update_interface(OutputFileName, Succeeded),
+ ( { Succeeded = no } ->
+ report_error("problem updating interface files.")
+ ;
+ []
+ ).
+
+update_interface(OutputFileName, Succeeded) -->
globals__io_lookup_bool_option(verbose, Verbose),
maybe_write_string(Verbose, "% Updating interface:\n"),
( { Verbose = yes } ->
@@ -1327,12 +1387,8 @@
{ Command = "mercury_update_interface " }
),
{ string__append(Command, OutputFileName, ShellCommand) },
- invoke_shell_command(ShellCommand, Succeeded),
- ( { Succeeded = no } ->
- report_error("problem updating interface files.")
- ;
- []
- ).
+ io__output_stream(OutputStream),
+ invoke_shell_command(OutputStream, verbose, ShellCommand, Succeeded).
%-----------------------------------------------------------------------------%
@@ -1363,8 +1419,9 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
-grab_imported_modules(SourceFileName, ModuleName, ReadModules, MaybeTimestamp,
- Items0, Module, Error) -->
+grab_imported_modules(SourceFileName, SourceFileModuleName, ModuleName,
+ NestedChildren, ReadModules, MaybeTimestamp,
+ Items0, Module, Error) -->
%
% Find out which modules this one depends on
%
@@ -1395,8 +1452,9 @@
MaybeTimestamps = no
},
- { init_module_imports(SourceFileName, ModuleName, Items0,
- PublicChildren, FactDeps, MaybeTimestamps, Module0) },
+ { init_module_imports(SourceFileName, SourceFileModuleName, ModuleName,
+ Items0, PublicChildren, NestedChildren, FactDeps,
+ MaybeTimestamps, Module0) },
% If this module has any seperately-compiled sub-modules,
% then we need to make everything in this module
@@ -1473,8 +1531,8 @@
% like grab_imported_modules, but gets the `.int3' files
% instead of the `.int' and `.int2' files.
-grab_unqual_imported_modules(SourceFileName, ModuleName, Items0,
- Module, Error) -->
+grab_unqual_imported_modules(SourceFileName, SourceFileModuleName, ModuleName,
+ Items0, Module, Error) -->
%
% Find out which modules this one depends on
%
@@ -1486,8 +1544,8 @@
% Construct the initial module import structure,
% and append a `:- imported' decl to the items.
%
- { init_module_imports(SourceFileName, ModuleName, Items0, [], [],
- no, Module0) },
+ { init_module_imports(SourceFileName, SourceFileModuleName, ModuleName,
+ Items0, [], [], [], no, Module0) },
{ append_pseudo_decl(Module0, imported(interface), Module1) },
% Add `builtin' and `private_builtin' to the imported modules.
@@ -1556,16 +1614,19 @@
MaybeTimestamp = no
).
-:- pred init_module_imports(file_name, module_name, item_list,
- list(module_name), list(string),
+:- pred init_module_imports(file_name, module_name, module_name, item_list,
+ list(module_name), list(module_name), list(string),
maybe(module_timestamps), module_imports).
-:- mode init_module_imports(in, in, in, in, in, in, out) is det.
+:- mode init_module_imports(in, in, in, in, in, in, in, in, out) is det.
-init_module_imports(SourceFileName, ModuleName, Items, PublicChildren,
- FactDeps, MaybeTimestamps, Module) :-
- Module = module_imports(SourceFileName, ModuleName, [], [], [], [],
- PublicChildren, FactDeps, unknown, [], Items, no_module_errors,
- MaybeTimestamps).
+init_module_imports(SourceFileName, SourceFileModuleName, ModuleName,
+ Items, PublicChildren, NestedChildren, FactDeps,
+ MaybeTimestamps, Module) :-
+ Module = module_imports(SourceFileName, SourceFileModuleName,
+ ModuleName, [], [], [], [], [], PublicChildren,
+ NestedChildren, FactDeps, unknown, [], no_foreign_export,
+ Items, no_module_errors,
+ MaybeTimestamps, no_main, dir__this_directory).
module_imports_get_source_file_name(Module, Module ^ source_file_name).
module_imports_get_module_name(Module, Module ^ module_name).
@@ -1792,10 +1853,12 @@
%-----------------------------------------------------------------------------%
write_dependency_file(Module, AllDepsSet, MaybeTransOptDeps) -->
- { Module = module_imports(SourceFileName, ModuleName, ParentDeps,
- IntDeps, ImplDeps, IndirectDeps, _InclDeps, FactDeps0,
- ContainsForeignCode, ForeignImports0,
- Items, _Error, _Timestamps) },
+ { Module = module_imports(SourceFileName, _SourceFileModuleName,
+ ModuleName, ParentDeps, IntDeps, ImplDeps,
+ IndirectDeps, _Children, _InclDeps, _NestDeps,
+ FactDeps0, ContainsForeignCode, ForeignImports0,
+ _ContainsForeignExport, Items, _Error,
+ _Timestamps, _HasMain, _Dir) },
globals__io_lookup_bool_option(verbose, Verbose),
{ module_name_to_make_var_name(ModuleName, MakeVarName) },
module_name_to_file_name(ModuleName, ".d", yes, DependencyFileName),
@@ -2046,6 +2109,26 @@
"endif"
]),
+ %
+ % The `.module_dep' file is made as a side effect of
+ % creating the `.c', `.s' or `.il'.
+ %
+ module_name_to_file_name(ModuleName, ".il", no, ILFileName),
+ module_name_to_file_name(ModuleName, module_dep_file_extension,
+ no, ModuleDepFileName),
+ io__write_strings(DepStream, [
+ "\n\n",
+ "ifeq ($(TARGET_ASM),yes)\n",
+ ModuleDepFileName, " : ", AsmFileName, "\n",
+ "else\n",
+ "ifeq ($(findstring il,$(GRADE)),il)\n",
+ ModuleDepFileName, " : ", ILFileName, "\n",
+ "else\n",
+ ModuleDepFileName, " : ", CFileName, "\n",
+ "endif\n",
+ "endif"
+ ]),
+
% The .date and .date0 files depend on the .int0 files
% for the parent modules, and the .int3 files for the
% directly and indirectly imported modules.
@@ -2112,7 +2195,7 @@
ForeignImports = ForeignImports0
; ContainsForeignCode = unknown,
get_item_list_foreign_code(Globals, Items,
- LangSet, ForeignImports)
+ LangSet, ForeignImports, _)
; ContainsForeignCode = no_foreign_code,
set__init(LangSet),
ForeignImports = ForeignImports0
@@ -2520,7 +2603,7 @@
( { BuildOptFiles = yes } ->
module_name_to_file_name(Dep, ".m", no, DepName),
search_for_file(IntermodDirs, DepName, Result1),
- ( { Result1 = yes } ->
+ ( { Result1 = yes(_) } ->
{ OptDeps1 = [Dep | OptDeps0] },
{ TransOptDeps1 = [Dep | TransOptDeps0] },
io__seen,
@@ -2539,7 +2622,7 @@
( { Found = no } ->
module_name_to_file_name(Dep, ".opt", no, OptName),
search_for_file(IntermodDirs, OptName, Result2),
- ( { Result2 = yes } ->
+ ( { Result2 = yes(_) } ->
{ OptDeps = [Dep | OptDeps1] },
io__seen
;
@@ -2547,7 +2630,7 @@
),
module_name_to_file_name(Dep, ".trans_opt", no, TransOptName),
search_for_file(IntermodDirs, TransOptName, Result3),
- ( { Result3 = yes } ->
+ ( { Result3 = yes(_) } ->
{ TransOptDeps = [Dep | TransOptDeps1] },
io__seen
;
@@ -2571,7 +2654,7 @@
( { BuildOptFiles = yes } ->
module_name_to_file_name(Dep, ".m", no, DepName),
search_for_file(IntermodDirs, DepName, Result1),
- ( { Result1 = yes } ->
+ ( { Result1 = yes(_) } ->
{ OptDeps1 = [Dep | OptDeps0] },
{ Found = yes },
io__seen
@@ -2587,7 +2670,7 @@
( { Found = no } ->
module_name_to_file_name(Dep, Suffix, no, OptName),
search_for_file(IntermodDirs, OptName, Result2),
- ( { Result2 = yes } ->
+ ( { Result2 = yes(_) } ->
{ OptDeps = [Dep | OptDeps1] },
io__seen
;
@@ -2613,7 +2696,10 @@
{ string__append(FileName, ".m", SourceFileName) },
split_into_submodules(ModuleName, Items, SubModuleList),
globals__io_get_globals(Globals),
- { list__map(init_dependencies(SourceFileName, Error, Globals),
+ { assoc_list__keys(SubModuleList, SubModuleNames) },
+ { list__map(
+ init_dependencies(SourceFileName, ModuleName, SubModuleNames,
+ Error, Globals),
SubModuleList, ModuleImportsList) },
{ map__init(DepsMap0) },
{ list__foldl(insert_into_deps_map, ModuleImportsList,
@@ -3319,6 +3405,12 @@
io__write_string(DepStream, "\n"),
io__write_string(DepStream, MakeVarName),
+ io__write_string(DepStream, ".num_splits = "),
+ write_compact_dependencies_list(Modules, "$(num_splits_subdir)",
+ ".num_splits", Basis, DepStream),
+ io__write_string(DepStream, "\n"),
+
+ io__write_string(DepStream, MakeVarName),
io__write_string(DepStream, ".dir_os = "),
write_compact_dependencies_list(Modules, "$(dirs_subdir)", ".dir/*.$O",
Basis, DepStream),
@@ -3373,6 +3465,12 @@
io__write_string(DepStream, "\n"),
io__write_string(DepStream, MakeVarName),
+ io__write_string(DepStream, ".module_deps = "),
+ write_compact_dependencies_list(Modules, "$(module_deps_subdir)",
+ module_dep_file_extension, Basis, DepStream),
+ io__write_string(DepStream, "\n"),
+
+ io__write_string(DepStream, MakeVarName),
io__write_string(DepStream, ".hs = "),
globals__io_lookup_bool_option(highlevel_code, HighLevelCode),
( { HighLevelCode = yes } ->
@@ -3395,8 +3493,17 @@
[]
)
;
- % For the LLDS back-end, we don't use `.h' files at all
- []
+ % For the LLDS back-end, we only generate `.h' files
+ % for modules containing `:- pragma export' declarations.
+ { LLDSHeaderModules =
+ list__filter(
+ (pred(Module::in) is semidet :-
+ map__lookup(DepsMap, Module,
+ deps(_, ModuleImports)),
+ contains_foreign_export =
+ ModuleImports ^ contains_foreign_export
+ ), Modules) },
+ write_dependencies_list(LLDSHeaderModules, ".h", DepStream)
),
io__write_string(DepStream, "\n"),
@@ -3613,6 +3720,15 @@
;
MaybeTransOptsVar = ""
},
+ globals__io_lookup_bool_option(generate_mmc_make_module_dependencies,
+ MmcMakeDeps),
+ { MmcMakeDeps = yes ->
+ string__append_list(["$(", MakeVarName, ".module_deps) "],
+ MaybeModuleDepsVar)
+ ;
+ MaybeModuleDepsVar = ""
+ },
+
module_name_to_lib_file_name("lib", ModuleName, "", no, LibTargetName),
module_name_to_lib_file_name("lib", ModuleName, ".$A",
yes, LibFileName),
@@ -3692,7 +3808,10 @@
module_name_to_lib_file_name("lib", ModuleName, ".install_ints", no,
LibInstallIntsTargetName),
- { InstallIntsRuleBody =
+ { Intermod = yes -> OptStr = " opt" ; OptStr = "" },
+ { TransOpt = yes -> TransOptStr = " trans_opt" ; TransOptStr = "" },
+ { MmcMakeDeps = yes -> DepStr = " module_dep" ; DepStr = "" },
+ { InstallIntsRuleBody = string__append_list([
" for file in $$files; do \\
target=""$(INSTALL_INT_DIR)/`basename $$file`""; \\
if cmp -s ""$$file"" ""$$target""; then \\
@@ -3705,7 +3824,7 @@
# The following is needed to support the `--use-subdirs' option
# We try using `ln -s', but if that fails, then we just use
# `$(INSTALL)'.
- for ext in int int2 int3 opt trans_opt; do \\
+ for ext in int int2 int3", OptStr, TransOptStr, DepStr, "; do \\
dir=""$(INSTALL_INT_DIR)/Mercury/$${ext}s""; \\
rm -f ""$$dir""; \\
ln -s .. ""$$dir"" || { \\
@@ -3714,16 +3833,17 @@
$(INSTALL) ""$(INSTALL_INT_DIR)""/*.$$ext \\
""$$dir""; \\
} || exit 1; \\
- done\n\n" },
+ done\n\n"]) },
io__write_strings(DepStream, [
".PHONY : ", LibInstallIntsTargetName, "\n",
LibInstallIntsTargetName, " : $(", MakeVarName, ".ints) $(",
MakeVarName, ".int3s) ", MaybeOptsVar,
- MaybeTransOptsVar, "install_lib_dirs\n",
+ MaybeTransOptsVar, MaybeModuleDepsVar,
+ "install_lib_dirs\n",
"\tfiles=""$(", MakeVarName, ".ints) $(", MakeVarName,
".int3s) ", MaybeOptsVar, MaybeTransOptsVar,
- """; \\\n",
+ MaybeModuleDepsVar, """; \\\n",
InstallIntsRuleBody
]),
@@ -3820,6 +3940,7 @@
".PHONY : ", CleanTargetName, "\n",
CleanTargetName, " :\n",
"\t-rm -rf $(", MakeVarName, ".dirs)\n",
+ "\t-rm -f $(", MakeVarName, ".num_splits)\n",
"\t-rm -f $(", MakeVarName, ".cs) ", InitCFileName, "\n",
"\t-rm -f $(", MakeVarName, ".all_ss) ", InitAsmFileName, "\n",
"\t-rm -f $(", MakeVarName, ".all_pic_ss) ",
@@ -3860,6 +3981,7 @@
"\t-rm -f $(", MakeVarName, ".opts)\n",
"\t-rm -f $(", MakeVarName, ".trans_opts)\n",
"\t-rm -f $(", MakeVarName, ".ds)\n",
+ "\t-rm -f $(", MakeVarName, ".module_deps)\n",
"\t-rm -f $(", MakeVarName, ".all_hs)\n",
"\t-rm -f $(", MakeVarName, ".dlls)\n",
"\t-rm -f $(", MakeVarName, ".foreign_dlls)\n",
@@ -3961,7 +4083,6 @@
ModuleImports ^ foreign_code = contains_foreign_code(Langs),
LangList = set__to_sorted_list(Langs).
-
% get_extra_link_objects(Modules, DepsMap, Target, ExtraLinkObjs) },
% Find any extra .$O files that should be linked into the executable.
% These include fact table object files and object files for foreign
@@ -3973,10 +4094,10 @@
get_extra_link_objects(Modules, DepsMap, Target, ExtraLinkObjs) :-
get_extra_link_objects_2(Modules, DepsMap, Target, [], ExtraLinkObjs0),
list__reverse(ExtraLinkObjs0, ExtraLinkObjs).
-
+
:- pred get_extra_link_objects_2(list(module_name), deps_map,
- compilation_target, assoc_list(file_name, module_name),
- assoc_list(file_name, module_name)).
+ compilation_target, assoc_list(file_name, module_name),
+ assoc_list(file_name, module_name)).
:- mode get_extra_link_objects_2(in, in, in, in, out) is det.
get_extra_link_objects_2([], _DepsMap, _Target, ExtraLinkObjs, ExtraLinkObjs).
@@ -3995,16 +4116,11 @@
% Handle object files for foreign code.
% XXX currently we only support `C' foreign code.
%
- % Note that we implement fact tables by generating
- % some inline C, so code which uses fact tables must
- % be treated as if it also contained foreign code.
- %
(
Target = asm,
- ( ModuleImports ^ foreign_code = contains_foreign_code(Langs),
- set__member(c, Langs)
- ; FactTableObjs \= []
- )
+ ModuleImports ^ foreign_code
+ = contains_foreign_code(Langs),
+ set__member(c, Langs)
->
prog_out__sym_name_to_string(Module, ".", FileName),
NewLinkObjs = [(FileName ++ "__c_code") - Module |
@@ -4013,107 +4129,122 @@
NewLinkObjs = FactTableObjs
),
list__append(NewLinkObjs, ExtraLinkObjs0, ExtraLinkObjs1),
- get_extra_link_objects_2(Modules, DepsMap, Target, ExtraLinkObjs1,
- ExtraLinkObjs).
+ get_extra_link_objects_2(Modules, DepsMap, Target,
+ ExtraLinkObjs1, ExtraLinkObjs).
+
+:- type module_foreign_info
+ ---> module_foreign_info(
+ used_foreign_languages :: set(foreign_language),
+ foreign_proc_languages :: map(sym_name, foreign_language),
+ all_foreign_import_module_info :: foreign_import_module_info,
+ module_contains_foreign_export :: contains_foreign_export
+ ).
:- pred get_item_list_foreign_code(globals::in, item_list::in,
- set(foreign_language)::out, foreign_import_module_info::out) is det.
+ set(foreign_language)::out, foreign_import_module_info::out,
+ contains_foreign_export::out) is det.
-get_item_list_foreign_code(Globals, Items, LangSet, ForeignImports) :-
+get_item_list_foreign_code(Globals, Items, LangSet, ForeignImports,
+ ContainsPragmaExport) :-
+ Info0 = module_foreign_info(set__init,
+ map__init, [], no_foreign_export),
+ list__foldl(get_item_foreign_code(Globals), Items, Info0, Info),
+ Info = module_foreign_info(LangSet0, LangMap,
+ ForeignImports, ContainsPragmaExport),
+ ForeignProcLangs = map__values(LangMap),
+ LangSet = set__insert_list(LangSet0, ForeignProcLangs).
+
+:- pred get_item_foreign_code(globals::in, item_and_context::in,
+ module_foreign_info::in, module_foreign_info::out) is det.
+
+get_item_foreign_code(Globals, Item, Info0, Info) :-
+ ( Item = pragma(Pragma) - Context ->
globals__get_backend_foreign_languages(Globals, BackendLangs),
globals__get_target(Globals, Target),
- list__foldl3((pred(Item::in, Set0::in, Set::out, Seen0::in, Seen::out,
- Imports0::in, Imports::out) is det :-
- (
- Item = pragma(Pragma) - Context
- ->
- % The code here should match the way that mlds_to_gcc.m
- % decides whether or not to call mlds_to_c.m. XXX Note
- % that we do NOT count foreign_decls here. We only
- % link in a foreign object file if mlds_to_gcc called
- % mlds_to_c.m to generate it, which it will only do if
- % there is some foreign_code, not just foreign_decls.
- % Counting foreign_decls here causes problems with
- % intermodule optimization.
- (
- Pragma = foreign_code(Lang, _),
- list__member(Lang, BackendLangs)
- ->
- set__insert(Set0, Lang, Set),
- Seen = Seen0,
- Imports = Imports0
- ;
- Pragma = foreign_proc(Attrs, Name, _, _, _, _)
- ->
- foreign_language(Attrs, NewLang),
- ( OldLang = map__search(Seen0, Name) ->
- % is it better than an existing
- % one?
- (
- yes = prefer_foreign_language(
- Globals, Target, OldLang,
- NewLang)
- ->
- map__set(Seen0, Name,
- NewLang, Seen)
- ;
- Seen = Seen0
- )
- ;
- % is it one of the languages
- % we support?
- (
- list__member(NewLang,
- BackendLangs)
- ->
- map__det_insert(Seen0, Name,
- NewLang, Seen)
- ;
- Seen = Seen0
- )
- ),
- Set = Set0,
- Imports = Imports0
- ;
- % XXX `pragma export' should not be treated as
- % foreign, but currently mlds_to_gcc.m doesn't
- % handle that declaration, and instead just
- % punts it on to mlds_to_c.m, thus generating C
- % code for it, rather than assembler code. So
- % we need to treat `pragma export' like the
- % other pragmas for foreign code.
- Pragma = export(_, _, _, _),
- list__member(c, BackendLangs)
- ->
- % XXX we assume lang = c for exports
- Lang = c,
- set__insert(Set0, Lang, Set),
- Seen = Seen0,
- Imports = Imports0
- ;
- % XXX handle lang \= c for
- % `:- pragma foreign_import_module'.
- Pragma = foreign_import_module(Lang, Import),
- Lang = c,
- list__member(c, BackendLangs)
+
+ % The code here should match the way that mlds_to_gcc.m
+ % decides whether or not to call mlds_to_c.m. XXX Note
+ % that we do NOT count foreign_decls here. We only
+ % link in a foreign object file if mlds_to_gcc called
+ % mlds_to_c.m to generate it, which it will only do if
+ % there is some foreign_code, not just foreign_decls.
+ % Counting foreign_decls here causes problems with
+ % intermodule optimization.
+ (
+ Pragma = foreign_code(Lang, _),
+ list__member(Lang, BackendLangs)
+ ->
+ Info = Info0 ^ used_foreign_languages :=
+ set__insert(Info0 ^ used_foreign_languages, Lang)
+ ;
+ Pragma = foreign_proc(Attrs, Name, _, _, _, _)
+ ->
+ foreign_language(Attrs, NewLang),
+ ( OldLang = Info0 ^ foreign_proc_languages ^ elem(Name) ->
+ % is it better than an existing one?
+ (
+ yes = prefer_foreign_language(Globals,
+ Target, OldLang, NewLang)
->
- Set = Set0,
- Seen = Seen0,
- Imports = [foreign_import_module(Lang,
- Import, Context) | Imports0]
+ Info = Info0 ^ foreign_proc_languages
+ ^ elem(Name) := NewLang
;
- Set = Set0,
- Seen = Seen0,
- Imports = Imports0
+ Info = Info0
)
;
- Set = Set0,
- Seen = Seen0,
- Imports = Imports0
- )), Items, set__init, LangSet0, map__init, LangMap,
- [], ForeignImports),
- Values = map__values(LangMap),
- LangSet = set__insert_list(LangSet0, Values).
+ % is it one of the languages we support?
+ ( list__member(NewLang, BackendLangs) ->
+ Info = Info0 ^ foreign_proc_languages
+ ^ elem(Name) := NewLang
+ ;
+ Info = Info0
+ )
+ )
+ ;
+ % XXX `pragma export' should not be treated as
+ % foreign, but currently mlds_to_gcc.m doesn't
+ % handle that declaration, and instead just
+ % punts it on to mlds_to_c.m, thus generating C
+ % code for it, rather than assembler code. So
+ % we need to treat `pragma export' like the
+ % other pragmas for foreign code.
+ Pragma = export(_, _, _, _),
+ list__member(c, BackendLangs)
+ ->
+ % XXX we assume lang = c for exports
+ Lang = c,
+ Info1 = Info0 ^ used_foreign_languages :=
+ set__insert(Info0 ^ used_foreign_languages, Lang),
+ Info = Info1 ^ module_contains_foreign_export :=
+ contains_foreign_export
+ ;
+ % XXX handle lang \= c for
+ % `:- pragma foreign_import_module'.
+ Pragma = foreign_import_module(Lang, Import),
+ Lang = c,
+ list__member(c, BackendLangs)
+ ->
+ Info = Info0 ^ all_foreign_import_module_info :=
+ [foreign_import_module(Lang, Import, Context) |
+ Info0 ^ all_foreign_import_module_info]
+ ;
+ % We generate some C code for fact tables,
+ % so we need to treat modules containing
+ % fact tables as if they contain foreign
+ % code.
+ ( Target = asm
+ ; Target = c
+ ),
+ Pragma = fact_table(_, _, _)
+ ->
+ Info = Info0 ^ used_foreign_languages :=
+ set__insert(Info0 ^ used_foreign_languages, c)
+ ;
+ Info = Info0
+ )
+ ;
+ Info = Info0
+ ).
%-----------------------------------------------------------------------------%
@@ -4369,15 +4500,12 @@
split_into_submodules(ModuleName, Items, SubModuleList)
),
globals__io_get_globals(Globals),
- { list__map(init_dependencies(FileName, Error, Globals), SubModuleList,
- ModuleImportsList) }.
-
-:- pred init_dependencies(file_name, module_error, globals,
- pair(module_name, item_list), module_imports).
-:- mode init_dependencies(in, in, in, in, out) is det.
+ { assoc_list__keys(SubModuleList, SubModuleNames) },
+ { list__map(init_dependencies(FileName, ModuleName, SubModuleNames,
+ Error, Globals), SubModuleList, ModuleImportsList) }.
-init_dependencies(FileName, Error, Globals, ModuleName - Items,
- ModuleImports) :-
+init_dependencies(FileName, SourceFileModuleName, NestedModuleNames,
+ Error, Globals, ModuleName - Items, ModuleImports) :-
get_ancestors(ModuleName, ParentDeps),
get_dependencies(Items, ImplImportDeps0, ImplUseDeps0),
@@ -4397,12 +4525,20 @@
% we don't fill in the indirect dependencies yet
IndirectDeps = [],
- get_children(InterfaceItems, IncludeDeps),
+ get_children(Items, IncludeDeps),
+ get_children(InterfaceItems, InterfaceIncludeDeps),
+
+ ( ModuleName = SourceFileModuleName ->
+ list__delete_all(NestedModuleNames, ModuleName, NestedDeps)
+ ;
+ NestedDeps = []
+ ),
get_fact_table_dependencies(Items, FactTableDeps),
% Figure out whether the items contain foreign code.
- get_item_list_foreign_code(Globals, Items, LangSet, ForeignImports),
+ get_item_list_foreign_code(Globals, Items, LangSet, ForeignImports,
+ ContainsPragmaExport),
ContainsForeignCode =
(if
not set__empty(LangSet)
@@ -4412,10 +4548,26 @@
no_foreign_code
),
- ModuleImports = module_imports(FileName, ModuleName, ParentDeps,
- InterfaceDeps, ImplementationDeps, IndirectDeps, IncludeDeps,
- FactTableDeps, ContainsForeignCode, ForeignImports,
- [], Error, no).
+ %
+ % Work out whether the items contain main/2.
+ %
+ (
+ list__member(Item, Items),
+ Item = pred_or_func(_, _, _, predicate,
+ Name, [_, _], _, _, _, _) - _,
+ unqualify_name(Name, "main")
+ ->
+ HasMain = has_main
+ ;
+ HasMain = no_main
+ ),
+
+ ModuleImports = module_imports(FileName, SourceFileModuleName,
+ ModuleName, ParentDeps, InterfaceDeps,
+ ImplementationDeps, IndirectDeps, IncludeDeps,
+ InterfaceIncludeDeps, NestedDeps, FactTableDeps,
+ ContainsForeignCode, ForeignImports, ContainsPragmaExport,
+ [], Error, no, HasMain, dir__this_directory).
%-----------------------------------------------------------------------------%
@@ -5388,24 +5540,24 @@
Items0, Items) :-
( Item = module_defn(_, interface) ->
Items1 = Items0,
- InInterface1 = yes
+ InInterface1 = yes,
+ Continue = yes
;
Item = module_defn(_, Defn),
( Defn = imported(_)
; Defn = used(_)
)
->
- % This should never happen;
- % `:- imported' and `:- used' declarations should only
- % get inserted *after* get_interface is called.
- error("get_interface: `:- imported' or `:- used' declaration")
- % Items1 = Items0,
- % InInterface1 = InInterface0
+ % Items after here are not part of this module.
+ Items1 = Items0,
+ InInterface1 = no,
+ Continue = no
;
Item = module_defn(_, implementation)
->
Items1 = Items0,
- InInterface1 = no
+ InInterface1 = no,
+ Continue = yes
;
( InInterface0 = yes ->
( make_abstract_instance(Item, Item1) ->
@@ -5417,9 +5569,14 @@
;
Items1 = Items0
),
- InInterface1 = InInterface0
+ InInterface1 = InInterface0,
+ Continue = yes
),
- get_interface_2(Rest, InInterface1, Items1, Items).
+ ( Continue = yes ->
+ get_interface_2(Rest, InInterface1, Items1, Items)
+ ;
+ Items = Items1
+ ).
% Given a module interface (well, a list of items), extract the
% short interface part of that module, i.e. the exported
Index: compiler/optimize.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/optimize.m,v
retrieving revision 1.28
diff -u -u -r1.28 optimize.m
--- compiler/optimize.m 31 May 2001 05:59:50 -0000 1.28
+++ compiler/optimize.m 24 Jan 2002 13:41:53 -0000
@@ -94,12 +94,14 @@
{ OptDebugInfo = opt_debug_info(BaseName, 0) },
{ string__append_list([BaseName, ".opt0"], FileName) },
- io__tell(FileName, Res),
- ( { Res = ok } ->
+ io__open_output(FileName, Res),
+ ( { Res = ok(FileStream) } ->
+ io__set_output_stream(FileStream, OutputStream),
{ counter__allocate(NextLabel, Counter, _) },
opt_debug__msg(yes, NextLabel, "before optimization"),
opt_debug__dump_instrs(yes, Instrs0),
- io__told
+ io__set_output_stream(OutputStream, _),
+ io__close_output(FileStream)
;
{ string__append("cannot open ", FileName, ErrorMsg) },
{ error(ErrorMsg) }
@@ -126,12 +128,14 @@
OptFileName) },
{ string__append_list([BaseName, ".diff", OptNumStr],
DiffFileName) },
- io__tell(OptFileName, Res),
- ( { Res = ok } ->
+ io__open_output(OptFileName, Res),
+ ( { Res = ok(FileStream) } ->
+ io__set_output_stream(FileStream, OutputStream),
{ counter__allocate(NextLabel, Counter, _) },
opt_debug__msg(yes, NextLabel, Msg),
opt_debug__dump_instrs(yes, Instrs),
- io__told
+ io__set_output_stream(OutputStream, _),
+ io__close_output(FileStream)
;
{ string__append("cannot open ", OptFileName,
ErrorMsg) },
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.350
diff -u -u -r1.350 options.m
--- compiler/options.m 16 Dec 2001 08:11:09 -0000 1.350
+++ compiler/options.m 3 Feb 2002 07:22:18 -0000
@@ -1,5 +1,5 @@
%-----------------------------------------------------------------------------%
-% Copyright (C) 1994-2001 The University of Melbourne.
+% Copyright (C) 1994-2002 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.
%-----------------------------------------------------------------------------%
@@ -70,12 +70,15 @@
; warn_missing_module_name
; warn_wrong_module_name
; warn_smart_recompilation
+ ; warn_undefined_options_variables
% Verbosity options
; verbose
; very_verbose
; verbose_errors
; verbose_recompilation
; verbose_make
+ ; verbose_commands
+ ; output_compile_error_lines
; statistics
; debug_types
; debug_modes
@@ -110,6 +113,8 @@
% It is implied by --smart-recompilation,
% and cannot be set explicitly by the user.
; generate_item_version_numbers
+ ; generate_mmc_make_module_dependencies
+ ; generate_mmake_module_dependencies
; assume_gmake
; trace
; trace_optimized
@@ -467,6 +472,17 @@
; java_classpath
; java_object_file_extension
+ % IL
+ ; il_assembler
+ ; ilasm_flags
+
+ % Managed C++
+ ; mcpp_compiler
+ ; mcpp_flags
+
+ % C#
+ ; csharp_compiler
+ ; csharp_flags
% Link options
; output_file_name
@@ -491,15 +507,22 @@
; create_archive_command_flags
; ranlib_command
- % Miscellaneous Options
+ % Build system options
; make
; keep_going
; rebuild
+ ; install_prefix
+ ; install_command
+ ; libgrades
+ ; options_files
+ ; options_search_directories
+ ; use_subdirs
+
+ % Miscellaneous Options
; search_directories
; intermod_directories
; use_search_directories_for_intermod
; filenames_from_stdin
- ; use_subdirs
; aditi % XXX this should be in the
% "Auxiliary output options"
% section
@@ -527,6 +550,7 @@
; optimization_option
; target_code_compilation_option
; link_option
+ ; build_system_option
; miscellaneous_option.
option_defaults(Option, Default) :-
@@ -563,7 +587,8 @@
warn_duplicate_calls - bool(no),
warn_missing_module_name - bool(yes),
warn_wrong_module_name - bool(yes),
- warn_smart_recompilation - bool(yes)
+ warn_smart_recompilation - bool(yes),
+ warn_undefined_options_variables - bool(yes)
]).
option_defaults_2(verbosity_option, [
% Verbosity Options
@@ -572,6 +597,8 @@
verbose_errors - bool(no),
verbose_recompilation - bool(no),
verbose_make - bool(yes),
+ verbose_commands - bool(no),
+ output_compile_error_lines - int(15),
statistics - bool(no),
debug_types - bool(no),
debug_modes - bool(no),
@@ -605,6 +632,8 @@
% Auxiliary Output Options
smart_recompilation - bool(no),
generate_item_version_numbers - bool(no),
+ generate_mmc_make_module_dependencies - bool(no),
+ generate_mmake_module_dependencies - bool(yes),
assume_gmake - bool(yes),
trace - string("default"),
trace_optimized - bool(no),
@@ -923,7 +952,19 @@
java_compiler - string("javac"),
java_flags - accumulating([]),
java_classpath - accumulating([]),
- java_object_file_extension - string(".class")
+ java_object_file_extension - string(".class"),
+
+% IL
+ il_assembler - string("ilasm"),
+ ilasm_flags - accumulating([]),
+
+% Managed C++
+ mcpp_compiler - string("cl"),
+ mcpp_flags - accumulating([]),
+
+% C#
+ csharp_compiler - string("csc"),
+ csharp_flags - accumulating([])
]).
option_defaults_2(link_option, [
% Link Options
@@ -959,17 +1000,25 @@
ranlib_command - string("")
]).
-option_defaults_2(miscellaneous_option, [
- % Miscellaneous Options
- filenames_from_stdin - bool(no),
+option_defaults_2(build_system_option, [
+ % Build System Options
make - bool(no),
keep_going - bool(no),
rebuild - bool(no),
+ install_prefix - string("/usr/local/"),
+ install_command - string("cp"),
+ libgrades - accumulating([]),
+ options_files - accumulating([]),
+ options_search_directories - accumulating(["."]),
+ use_subdirs - bool(no),
search_directories - accumulating(["."]),
intermod_directories - accumulating([]),
use_search_directories_for_intermod
- - bool(yes),
- use_subdirs - bool(no),
+ - bool(yes)
+]).
+option_defaults_2(miscellaneous_option, [
+ % Miscellaneous Options
+ filenames_from_stdin - bool(no),
aditi - bool(no),
aditi_user - string(""),
help - bool(no),
@@ -1028,6 +1077,8 @@
long_option("warn-missing-module-name", warn_missing_module_name).
long_option("warn-wrong-module-name", warn_wrong_module_name).
long_option("warn-smart-recompilation", warn_smart_recompilation).
+long_option("warn-undefined-options-variables",
+ warn_undefined_options_variables).
% verbosity options
long_option("verbose", verbose).
@@ -1035,6 +1086,8 @@
long_option("verbose-error-messages", verbose_errors).
long_option("verbose-recompilation", verbose_recompilation).
long_option("verbose-make", verbose_make).
+long_option("verbose-commands", verbose_commands).
+long_option("output-compile-error-lines", output_compile_error_lines).
long_option("statistics", statistics).
long_option("debug-types", debug_types).
long_option("debug-modes", debug_modes).
@@ -1084,6 +1137,12 @@
% aux output options
long_option("smart-recompilation", smart_recompilation).
long_option("assume-gmake", assume_gmake).
+long_option("generate-mmc-make-module-dependencies",
+ generate_mmc_make_module_dependencies).
+long_option("generate-mmc-deps",
+ generate_mmc_make_module_dependencies).
+long_option("generate-mmake-module-dependencies",
+ generate_mmake_module_dependencies).
long_option("trace", trace).
long_option("trace-optimised", trace_optimized).
long_option("trace-optimized", trace_optimized).
@@ -1433,7 +1492,7 @@
long_option("java-compiler", java_compiler).
long_option("javac", java_compiler).
-long_option("java-flags", cflags).
+long_option("java-flags", java_flags).
% XXX we should consider the relationship between java_debug and
% target_debug more carefully. Perhaps target_debug could imply
% Java debug if the target is Java. However for the moment they are
@@ -1442,6 +1501,15 @@
long_option("java-classpath", java_classpath).
long_option("java-object-file-extension", java_object_file_extension).
+long_option("il-assembler", il_assembler).
+long_option("ilasm-flags", ilasm_flags).
+
+long_option("mcpp-compiler", mcpp_compiler).
+long_option("mcpp-flags", mcpp_flags).
+
+long_option("csharp-compiler", csharp_compiler).
+long_option("csharp-flags", csharp_flags).
+
% link options
long_option("output-file", output_file_name).
long_option("link-flags", link_flags).
@@ -1465,17 +1533,25 @@
long_option("create-archive-command-flags", create_archive_command_flags).
long_option("ranlib-command", ranlib_command).
-% misc options
-long_option("help", help).
+% build system options
long_option("make", make).
long_option("keep-going", keep_going).
long_option("rebuild", rebuild).
+long_option("install-prefix", install_prefix).
+long_option("install-command", install_command).
+long_option("library-grade", libgrades).
+long_option("libgrade", libgrades).
+long_option("options-file", options_files).
+long_option("options-search-directory", options_search_directories).
+long_option("use-subdirs", use_subdirs).
long_option("search-directory", search_directories).
long_option("intermod-directory", intermod_directories).
long_option("use-search-directories-for-intermod",
use_search_directories_for_intermod).
+
+% misc options
+long_option("help", help).
long_option("filenames-from-stdin", filenames_from_stdin).
-long_option("use-subdirs", use_subdirs).
long_option("aditi", aditi).
long_option("aditi-user", aditi_user).
long_option("fullarch", fullarch).
@@ -1569,7 +1645,8 @@
warn_simple_code - bool(Enable),
warn_missing_module_name - bool(Enable),
warn_wrong_module_name - bool(Enable),
- warn_smart_recompilation - bool(Enable)
+ warn_smart_recompilation - bool(Enable),
+ warn_undefined_options_variables - bool(Enable)
], OptionTable0, OptionTable).
special_handler(infer_all, bool(Infer), OptionTable0, ok(OptionTable)) :-
override_options([
@@ -1822,6 +1899,7 @@
options_help_output_optimization,
options_help_target_code_compilation,
options_help_link,
+ options_help_build_system,
options_help_misc.
:- pred options_help_warning(io__state::di, io__state::uo) is det.
@@ -1885,7 +1963,10 @@
"\tDisable warnings for modules whose `:- module'",
"\tdeclaration does not match the module's file name.",
"--no-warn-smart-recompilation",
- "\tDisable warnings from the smart recompilation system."
+ "\tDisable warnings from the smart recompilation system.",
+ "--no-warn-undefined-options-variables",
+ "\tWarn about references to undefined variables in",
+ "\toptions files with `--make'."
]).
:- pred options_help_verbosity(io__state::di, io__state::uo) is det.
@@ -1900,10 +1981,16 @@
"-E, --verbose-error-messages",
"\tExplain error messages. Asks the compiler to give you a more",
"\tdetailed explanation of any errors it finds in your program.",
-% `--make' is not yet implemented.
-% "--verbose-make",
-% "\tOutput progress messages about the progress of the",
-% "\t`--make' option.",
+ "--no-verbose-make",
+ "\tDisable messages about the progress of builds using",
+ "\tthe `--make' option.",
+ "--output-compile-error-lines <n>",
+ "\tWith `--make', output the first <n> lines of the `.err'",
+ "\tfile after compiling a module (default: 15).",
+ "--verbose-commands",
+ "\tOutput each external command before it is run.",
+ "\tNote that some commands will only be printed",
+ "\tprinted with `--verbose'.",
"--verbose-recompilation",
"\tWhen using `--smart-recompilation', output messages\n",
"\texplaining why a module needs to be recompiled.",
@@ -1928,10 +2015,9 @@
"\tOutput detailed debugging traces of Aditi-RL optimization.",
"--debug-liveness <pred_id>",
"\tOutput detailed debugging traces of the liveness analysis",
- "\tof the predicate with the given predicate id."
-% `--make' is not yet implemented.
-% "--debug-make",
-% "\tOutput detailed debugging traces of the `--make' option."
+ "\tof the predicate with the given predicate id.",
+ "--debug-make",
+ "\tOutput detailed debugging traces of the `--make' option."
]).
:- pred options_help_output(io__state::di, io__state::uo) is det.
@@ -2010,6 +2096,18 @@
"\tWhen generating `.dep' files, generate Makefile",
"\tfragments that use only the features of standard make;",
"\tdo not assume the availability of GNU Make extensions.",
+ "\tWhen generating `.dep' files, generate dependencies",
+ "\tfor use by `mmc --make' in addition to the dependencies",
+ "\tused by mmake.",
+ "--generate-mmc-deps",
+ "--generate-mmc-make-module-dependencies",
+ "\tGenerate dependencies for use by `mmc --make' even",
+ "\twhen using Mmake. This is recommended when building a",
+ "\tlibrary for installation.",
+
+ % --generate-mmake-module-dependencies is for internal
+ % use by the compiler.
+
% declarative debugging is not documented yet, since it is still experimental
% "--trace {minimum, shallow, deep, decl, rep, default}",
"--trace {minimum, shallow, deep, default}",
@@ -2994,15 +3092,30 @@
"--java-compiler",
"\tSpecify which Java compiler to use. The default is javac.",
- "--java-flags",
+ "--java-flags <options>",
"\tSpecify options to be passed to the Java compiler.",
- "--java-classpath",
+ "--java-classpath <path>",
"\tSet the classpath for the Java compiler.",
- "--java-object-file-extension",
+ "--java-object-file-extension <ext>",
"\tSpecify an extension for Java object (bytecode) files",
- "\tBy default this is `.class'."
+ "\tBy default this is `.class'.",
+
+ "--il-assembler <ilasm>",
+ "\tThe Microsoft IL Assembler.",
+ "--ilasm-flags <options>",
+ "\tSpecify options to be passed to the IL assembler.",
+
+ "--mcpp-compiler <cl>",
+ "\tSpecify the name of the Microsoft Managed C++ Compiler.",
+ "--mcpp-flags <options>",
+ "\tSpecify options to be passed to the Managed C++ Compiler.",
+
+ "--csharp-compiler <csc>",
+ "\tSpecify the name of the Microsoft C# Compiler.",
+ "--csharp-flags <options>",
+ "\tSpecify options to be passed to the C# Compiler."
]).
:- pred options_help_link(io__state::di, io__state::uo) is det.
@@ -3052,21 +3165,38 @@
% they are deliberately not documented.
]).
-:- pred options_help_misc(io__state::di, io__state::uo) is det.
+:- pred options_help_build_system(io__state::di, io__state::uo) is det.
-options_help_misc -->
- io__write_string("\nMiscellaneous Options:\n"),
+options_help_build_system -->
+ io__write_string("\nBuild System Options:\n"),
write_tabbed_lines([
-% `--make' is not yet implemented.
-% "-m, --make",
-% "\tTreat the non-option arguments to `mmc' as files to",
-% "\tmake, rather than source files.",
-% "-r, --rebuild",
-% "\tSame as `--make', but always rebuild the target files",
-% "\teven if they are up to date."j
-% "-k, --keep-going",
-% "\tWith `--make' or `--rebuild', keep going as far as",
-% "\tpossible even if an error is detected.",
+ "-m, --make",
+ "\tTreat the non-option arguments to `mmc' as files to",
+ "\tmake, rather than source files.",
+ "-r, --rebuild",
+ "\tSame as `--make', but always rebuild the target files",
+ "\teven if they are up to date.",
+ "-k, --keep-going",
+ "\tWith `--make', keep going as far as",
+ "\tpossible even if an error is detected.",
+ "--install-prefix <dir>",
+ "\tThe directory under which to install Mercury libraries.",
+ "--install-command <command>",
+ "\tSpecify the command to use to install the files in",
+ "\tMercury libraries. The given command will be invoked as",
+ "\t`<command> <source> <target>' to install each file",
+ "\tin a Mercury library. The default command is `cp'.",
+ "--libgrade <grade>",
+ "\tAdd <grade> to the list of compilation grades in",
+ "\twhich a library to be installed should be built.",
+ "--options-file <file>",
+ "\tAdd <file> to the list of options files to be processed.",
+ "\tIf no `--options-file' options are given, the file",
+ "\t`Mercury.options' in the current directory will be read",
+ "\tif it exists.",
+ "--options-search-directory <dir>",
+ "\tAdd <dir> to the list of directories to be searched for",
+ "\toptions files.",
"-I <dir>, --search-directory <dir>",
"\tAppend <dir> to the list of directories to be searched for",
"\timported modules.",
@@ -3079,7 +3209,14 @@
"\tdirectories given by `--intermod-directory'.",
"--use-subdirs",
"\tGenerate intermediate files in a `Mercury' subdirectory,",
- "\trather than generating them in the current directory.",
+ "\trather than generating them in the current directory."
+ ]).
+
+:- pred options_help_misc(io__state::di, io__state::uo) is det.
+
+options_help_misc -->
+ io__write_string("\nMiscellaneous Options:\n"),
+ write_tabbed_lines([
"--filenames-from-stdin",
"\tRead then compile a newline terminated module name or",
"\tfile name from the standard input. Repeat this until EOF",
Index: compiler/passes_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/passes_aux.m,v
retrieving revision 1.40
diff -u -u -r1.40 passes_aux.m
--- compiler/passes_aux.m 2 May 2001 11:36:40 -0000 1.40
+++ compiler/passes_aux.m 5 Feb 2002 09:38:07 -0000
@@ -145,6 +145,8 @@
:- pred maybe_flush_output(bool::in, io__state::di, io__state::uo) is det.
:- pred report_error(string::in, io__state::di, io__state::uo) is det.
+:- pred report_error(io__output_stream::in, string::in,
+ io__state::di, io__state::uo) is det.
:- pred maybe_report_sizes(module_info::in, io__state::di, io__state::uo)
is det.
@@ -176,18 +178,40 @@
---> forward % '
; double. % "
+:- type command_verbosity
+ ---> verbose % Output the command line
+ % only with `--verbose'.
+
+ ; verbose_commands % Output the command line
+ % with `--verbose-commands'.
+ % This should be used for
+ % commands that may be of
+ % interest to the user.
+ .
+
% Invoke a shell script.
-:- pred invoke_shell_command(string::in, bool::out,
+ % Both standard and error output will go to the
+ % specified output stream.
+:- pred invoke_shell_command(io__output_stream::in,
+ command_verbosity::in, string::in, bool::out,
io__state::di, io__state::uo) is det.
% Invoke an executable.
-:- pred invoke_system_command(string::in, bool::out,
+ % Both standard and error output will go to the
+ % specified output stream.
+:- pred invoke_system_command(io__output_stream::in,
+ command_verbosity::in, string::in, bool::out,
io__state::di, io__state::uo) is det.
% Make a command string, which needs to be invoked in a shell
% environment.
:- pred make_command_string(string::in, quote_char::in, string::out) is det.
+ % raise_signal(Signal).
+ % Send `Signal' to the current process.
+ % XXX This belongs somewhere else.
+:- pred raise_signal(int::in, io__state::di, io__state::uo) is det.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -401,6 +425,11 @@
io__write_string("\n"),
io__set_exit_status(1).
+report_error(Stream, ErrorMessage) -->
+ io__set_output_stream(Stream, OldStream),
+ report_error(ErrorMessage),
+ io__set_output_stream(OldStream, _).
+
:- pred passes_aux__handle_errors(int, int, module_info, module_info,
io__state, io__state).
:- mode passes_aux__handle_errors(in, in, in, out, di, uo) is det.
@@ -424,13 +453,20 @@
State9 = State2
).
-invoke_shell_command(Command0, Succeeded) -->
+invoke_shell_command(ErrorStream, Verbosity, Command0, Succeeded) -->
{ make_command_string(Command0, forward, Command) },
- invoke_system_command(Command, Succeeded).
+ invoke_system_command(ErrorStream, Verbosity, Command, Succeeded).
-invoke_system_command(Command, Succeeded) -->
+invoke_system_command(ErrorStream, Verbosity, Command, Succeeded) -->
globals__io_lookup_bool_option(verbose, Verbose),
- ( { Verbose = yes } ->
+ (
+ { Verbosity = verbose },
+ { PrintCommand = Verbose }
+ ;
+ { Verbosity = verbose_commands },
+ globals__io_lookup_bool_option(verbose_commands, PrintCommand)
+ ),
+ ( { PrintCommand = yes } ->
io__write_string("% Invoking system command `"),
io__write_string(Command),
io__write_string("'...\n"),
@@ -438,17 +474,75 @@
;
[]
),
- io__call_system(Command, Result),
- ( { Result = ok(0) } ->
- maybe_write_string(Verbose, "% done.\n"),
- { Succeeded = yes }
- ; { Result = ok(_) } ->
- report_error("system command returned non-zero exit status."),
+
+ %
+ % The output from the command is written to a temporary file,
+ % which is then written to the output stream. Without this,
+ % the output from the command would go to the current C output
+ % and error streams.
+ %
+ io__make_temp(TmpFile),
+ io__call_system_return_signal(
+ string__append_list([Command, " > ", TmpFile, " 2>&1"]),
+ Result),
+ (
+ { Result = ok(exited(Status)) },
+ maybe_write_string(PrintCommand, "% done.\n"),
+ ( { Status = 0 } ->
+ { Succeeded = yes }
+ ;
+ io__set_exit_status(1),
+ % The command should have produced output
+ % describing the error.
+ { Succeeded = no }
+ )
+ ;
+ { Result = ok(signalled(Signal)) },
+ % Make sure the current process gets the signal. Some
+ % systems (e.g. Linux) ignore SIGINT during a call to
+ % system().
+ raise_signal(Signal),
+ report_error(ErrorStream, "system command received signal "
+ ++ int_to_string(Signal) ++ "."),
{ Succeeded = no }
- ;
- report_error("unable to invoke system command."),
+ ;
+ { Result = error(Error) },
+ report_error(ErrorStream, io__error_message(Error)),
{ Succeeded = no }
- ).
+ ),
+
+ %
+ % Write the output to the error stream.
+ %
+ io__open_input(TmpFile, TmpFileRes),
+ (
+ { TmpFileRes = ok(TmpFileStream) },
+ io__input_stream_foldl_io(TmpFileStream,
+ io__write_char(ErrorStream), Res),
+ (
+ { Res = ok }
+ ;
+ { Res = error(TmpFileReadError) },
+ report_error(ErrorStream,
+ "error reading command output: "
+ ++ io__error_message(TmpFileReadError))
+ )
+ ;
+ { TmpFileRes = error(TmpFileError) },
+ report_error(ErrorStream, "error opening command output: "
+ ++ io__error_message(TmpFileError))
+ ),
+ io__remove_file(TmpFile, _).
+
+:- pragma foreign_decl("C", "#include <signal.h>").
+
+:- pragma foreign_proc("C",
+ raise_signal(Signal::in, IO0::di, IO::uo),
+ [will_not_call_mercury, promise_pure],
+"
+ IO = IO0;
+ raise(Signal);
+").
make_command_string(String0, QuoteType, String) :-
( use_win32 ->
@@ -579,10 +673,12 @@
maybe_write_string(Verbose, FileName),
maybe_write_string(Verbose, "'...\n"),
maybe_flush_output(Verbose),
- io__tell(FileName, Res),
- ( { Res = ok } ->
+ io__open_output(FileName, Res),
+ ( { Res = ok(FileStream) } ->
+ io__set_output_stream(FileStream, OutputStream),
Action(ActionResult),
- io__told,
+ io__set_output_stream(OutputStream, _),
+ io__close_output(OutputStream),
maybe_write_string(Verbose, "% done.\n"),
maybe_report_stats(Stats),
{ Result = yes(ActionResult) }
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.197
diff -u -u -r1.197 prog_io.m
--- compiler/prog_io.m 16 Jul 2001 08:21:04 -0000 1.197
+++ compiler/prog_io.m 2 Jan 2002 14:52:36 -0000
@@ -114,10 +114,13 @@
io__state, io__state).
:- mode check_module_has_expected_name(in, in, in, di, uo) is det.
- % search_for_file(Dirs, FileName, Found, IO0, IO)
+ % search_for_file(Dirs, FileName, FoundDirName, IO0, IO)
%
- % Search Dirs for FileName, opening the file if it is found.
-:- pred search_for_file(list(dir_name), file_name, bool, io__state, io__state).
+ % Search Dirs for FileName, opening the file if it is found,
+ % and returning the name of the directory in which the file
+ % was found.
+:- pred search_for_file(list(dir_name), file_name, maybe(dir_name),
+ io__state, io__state).
:- mode search_for_file(in, in, out, di, uo) is det.
% parse_item(ModuleName, VarSet, Term, MaybeItem)
@@ -228,8 +231,7 @@
( { ActualName \= ExpectedName } ->
{ prog_out__sym_name_to_string(ActualName, ActualString) },
{ prog_out__sym_name_to_string(ExpectedName, ExpectedString) },
- io__stderr_stream(ErrStream),
- io__write_strings(ErrStream, [
+ io__write_strings([
"Error: file `", FileName,
"' contains the wrong module.\n",
"Expected module `", ExpectedString,
@@ -269,7 +271,7 @@
),
io__input_stream(OldInputStream),
search_for_file(Dirs, FileName, R),
- ( { R = yes } ->
+ ( { R = yes(_) } ->
( { ReturnTimestamp = yes } ->
io__input_stream_name(InputStreamName),
io__file_modification_time(InputStreamName,
@@ -326,13 +328,11 @@
{ dir__this_directory(Dir) ->
ThisFileName = FileName
;
- dir__directory_separator(Separator),
- string__first_char(Tmp1, Separator, FileName),
- string__append(Dir, Tmp1, ThisFileName)
+ ThisFileName = dir__make_path_name(Dir, FileName)
},
io__see(ThisFileName, R0),
( { R0 = ok } ->
- { R = yes }
+ { R = yes(Dir) }
;
search_for_file(Dirs, FileName, R)
).
Index: compiler/prog_io_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io_util.m,v
retrieving revision 1.21
diff -u -u -r1.21 prog_io_util.m
--- compiler/prog_io_util.m 25 Sep 2001 09:36:55 -0000 1.21
+++ compiler/prog_io_util.m 2 Jan 2002 14:52:36 -0000
@@ -537,14 +537,13 @@
%-----------------------------------------------------------------------------%
report_warning(Message) -->
- io__stderr_stream(StdErr),
globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn),
( { HaltAtWarn = yes } ->
io__set_exit_status(1)
;
[]
),
- io__write_string(StdErr, Message).
+ io__write_string(Message).
report_warning(Stream, Message) -->
globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn),
@@ -558,8 +557,7 @@
report_warning(FileName, LineNum, Message) -->
{ string__format("%s:%3d: Warning: %s\n",
[s(FileName), i(LineNum), s(Message)], FullMessage) },
- io__stderr_stream(StdErr),
- io__write_string(StdErr, FullMessage),
+ io__write_string(FullMessage),
globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn),
( { HaltAtWarn = yes } ->
io__set_exit_status(1)
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.41
diff -u -u -r1.41 purity.m
--- compiler/purity.m 30 Jan 2002 01:40:30 -0000 1.41
+++ compiler/purity.m 30 Jan 2002 16:34:28 -0000
@@ -222,14 +222,10 @@
puritycheck(FoundTypeError, HLDS0, PostTypecheckError, HLDS) -->
globals__io_lookup_bool_option(statistics, Statistics),
globals__io_lookup_bool_option(verbose, Verbose),
- io__stderr_stream(StdErr),
- io__set_output_stream(StdErr, OldStream),
maybe_write_string(Verbose, "% Purity-checking clauses...\n"),
check_preds_purity(FoundTypeError, HLDS0, PostTypecheckError, HLDS),
- maybe_report_stats(Statistics),
-
- io__set_output_stream(OldStream, _).
+ maybe_report_stats(Statistics).
% worst_purity/3 could be written more compactly, but this definition
Index: compiler/timestamp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/timestamp.m,v
retrieving revision 1.3
diff -u -u -r1.3 timestamp.m
--- compiler/timestamp.m 20 Jan 2002 07:32:16 -0000 1.3
+++ compiler/timestamp.m 21 Jan 2002 04:08:41 -0000
@@ -22,22 +22,30 @@
% is equivalent to comparison of the times represented.
:- type timestamp.
- % time__time_t_to_timestamp(Time) = Timestamp:
+ % time_t_to_timestamp(Time) = Timestamp:
% Converts the calendar time value `Time' into a timestamp.
% Equivalent to `gm_time_to_timestamp(gmtime(Time))'.
:-func time_t_to_timestamp(time_t) = timestamp.
- % time__timestamp_to_string(Timestamp) = String:
+ % timestamp_to_string(Timestamp) = String:
% Converts `Timestamp' into a string with format
% "yyyy-mm-dd hh:mm:ss", expressed as UTC.
:- func timestamp_to_string(timestamp) = string.
- % time__string_to_timestamp(String) = Timestamp:
+ % string_to_timestamp(String) = Timestamp:
% Converts a string formatted as "yyyy-mm-dd hh:mm:ss",
% into a timestamp. Fails if the string does not have the
% correct format.
:- func string_to_timestamp(string) = timestamp is semidet.
+ % oldest_timestamp = Timestamp:
+ % Return a timestamp which is older than any other timestamp.
+:- func oldest_timestamp = timestamp.
+
+ % newest_timestamp = Timestamp:
+ % Return a timestamp which is newer than any other timestamp.
+:- func newest_timestamp = timestamp.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -48,7 +56,8 @@
% representing a time expressed as UTC (Universal Coordinated Time).
:- type timestamp == string.
-:- pragma c_header_code("#include <time.h>").
+oldest_timestamp = "0000-00-00 00:00:00".
+newest_timestamp = "9999-99-99 99:99:99".
time_t_to_timestamp(Time) = gmtime_to_timestamp(time__gmtime(Time)).
@@ -145,4 +154,3 @@
string__to_int(string__unsafe_substring(Timestamp, 17, 2), Second),
Second >= 0,
Second =< 61. % Seconds 60 and 61 are for leap seconds.
-
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.308
diff -u -u -r1.308 typecheck.m
--- compiler/typecheck.m 25 Sep 2001 09:36:55 -0000 1.308
+++ compiler/typecheck.m 2 Jan 2002 14:52:36 -0000
@@ -165,14 +165,10 @@
typecheck(Module0, Module, FoundError, ExceededIterationLimit) -->
globals__io_lookup_bool_option(statistics, Statistics),
globals__io_lookup_bool_option(verbose, Verbose),
- io__stderr_stream(StdErr),
- io__set_output_stream(StdErr, OldStream),
maybe_write_string(Verbose, "% Type-checking clauses...\n"),
check_pred_types(Module0, Module, FoundError, ExceededIterationLimit),
- maybe_report_stats(Statistics),
-
- io__set_output_stream(OldStream, _).
+ maybe_report_stats(Statistics).
%-----------------------------------------------------------------------------%
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.68
diff -u -u -r1.68 compiler_design.html
--- compiler/notes/compiler_design.html 31 Dec 2001 06:07:25 -0000 1.68
+++ compiler/notes/compiler_design.html 27 Jan 2002 16:43:28 -0000
@@ -111,7 +111,8 @@
<!---------------------------------------------------------------------------->
<p>
-The action is co-ordinated from mercury_compile.m.
+The action is co-ordinated from mercury_compile.m or make.m (if `--make'
+was specified on the command line).
<p>
@@ -124,6 +125,48 @@
defined in options.m as arguments, to parse them. It then invokes
handle_options.m to postprocess the option set. The results are
stored in the io__state, using the type globals defined in globals.m.
+After the options are processed, the options files specified
+by the `--option-defaults-file' option is read by options_file.m.
+The options are then reprocessed with the options set in the options
+file.
+
+<p>
+
+<h3> Build system </h3>
+
+<p>
+
+<dl>
+
+<dt> make.m
+ <dd>
+ Categorizes targets passed on the command line and passes
+ them to the appropriate module to be built.
+
+<dt> make.program_target.m
+ <dd>
+ Handles whole program `mmc --make' targets, including
+ executables, libraries and cleanup.
+
+<dt> make.module_target.m
+ <dd>
+ Handles targets built by a compilation action associated
+ with a single module, for example making interface files,
+
+<dt> make.dependencies.m
+ <dd>
+ Compute dependencies between targets and between modules.
+
+<dt> make.module_dep_file.m
+ <dd>
+ Record the dependency information for each module between
+ compilations.
+
+<dt> make.util.m
+ <dd>
+ Utility predicates.
+
+</dl>
<p>
<hr>
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.287
diff -u -u -r1.287 user_guide.texi
--- doc/user_guide.texi 30 Jan 2002 14:51:04 -0000 1.287
+++ doc/user_guide.texi 30 Jan 2002 16:34:40 -0000
@@ -771,6 +771,29 @@
In particular, GNU Make has support for running jobs in parallel, which
is very useful if you have a machine with more than one CPU.
+As an alternative to Mmake, the Mercury compiler now contains a
+significant part of the functionality of Mmake, using the
+ at samp{--make} option.
+ at findex --make
+To use the compiler's internal make with Mmake, set the
+ at samp{MMAKE_USE_MMC_MAKE} environment variable to @samp{yes},
+or create a file @file{Mercury.options} in the directory
+containing the source files. When this is done, Mmake will
+process source files written in other programming languages,
+but all Mercury compilation will be done by @samp{mmc --make}.
+
+The advantages of the @samp{mmc --make} over Mmake are that there
+is no @samp{mmake depend} step and the dependencies are more accurate.
+Library installation (@pxref{Libraries}) and parallel makes are
+not yet supported.
+
+The Mmake variables above can be used by @samp{mmc --make} if they
+are set in a file called @file{Mercury.options}. The @file{Mercury.options}
+file has the same syntax as an Mmakefile, but only variable assignments and
+ at samp{include} directives are allowed. All variables in the Mercury.options
+are treated as if they are assigned using @samp{:=}. As with Mmake,
+variables may also be set in the environment.
+
@c ----------------------------------------------------------------------------
@node Libraries
@@ -3372,6 +3395,7 @@
* Optimization options::
* Target code compilation options::
* Link options::
+* Build system options::
* Miscellaneous options::
@end menu
@@ -3525,6 +3549,13 @@
@findex --no-warn-smart-recompilation
Disable warnings from the smart recompilation system.
+ at sp 1
+ at item --no-warn-undefined-options-variables
+ at findex --no-warn-undefined-options-variables
+ at findex --make
+Warn about references to undefined variables in
+options files with @samp{--make}.
+
@end table
@node Verbosity options
@@ -3553,6 +3584,27 @@
detailed explanation of any errors it finds in your program.
@sp 1
+ at item --no-verbose-make
+ at findex --no-verbose-make
+ at findex --make
+Disable messages about the progress of builds using
+the @samp{--make} option.
+
+ at sp 1
+ at item --output-compile-error-lines @var{n}
+ at findex --output-compile-error-lines
+ at findex --make
+With @samp{--make}, output the first @var{n} lines of the @samp{.err}
+file after compiling a module (default: 15).
+
+ at sp 1
+ at item --verbose-commands
+ at findex --verbose-commands
+Output each external command before it is run.
+Note that some commands will only be printed
+with @samp{--verbose}.
+
+ at sp 1
@item --verbose-recompilation
@findex --verbose-recompilation
When using @samp{--smart-recompilation}, output messages
@@ -3622,6 +3674,12 @@
Output detailed debugging traces of the liveness analysis
of the predicate with the given predicate id.
+ at sp 1
+ at item --debug-make
+ at findex --debug-make
+ at findex --make
+Output detailed debugging traces of the `--make' option.
+
@end table
@node Output options
@@ -3648,6 +3706,15 @@
dependency graph in top-down order to @file{@var{module}.order}.
Implies @samp{--generate-dependencies}.
+ at item --generate-mmc-deps
+ at itemx --generate-mmc-make-module-dependencies
+ at findex --generate-mmc-deps
+ at findex --generate-mmc-make-module-dependencies
+ at findex --make
+Generate dependencies for use by @samp{mmc --make} even
+when using Mmake. This is recommended when building a
+library for installation.
+
@sp 1
@item -i
@itemx --make-int
@@ -5368,9 +5435,58 @@
@end ifset
@c aditi
- at node Miscellaneous options
- at section Miscellaneous options
+ at node Build system options
+ at section Build system options
@table @code
+ at item -m
+ at itemx --make
+ at findex -m
+ at findex --make
+Treat the non-option arguments to @samp{mmc} as files to
+make, rather than source files.
+
+ at item -r
+ at itemx --rebuild
+ at findex -r
+ at findex --rebuild
+Same as @samp{--make}, but always rebuild the target files
+even if they are up to date.
+
+ at item -k
+ at itemx --keep-going
+ at findex -k
+ at findex --keep-going
+With @samp{--make} keep going as far as
+possible even if an error is detected.
+
+ at item --install-prefix @var{dir}
+ at findex --install-prefix
+Specify the directory under which to install Mercury libraries.
+
+ at item --install-command @var{command}
+ at findex --install-command
+Specify the command to use to install the files in Mercury
+libraries. The given command will be invoked as
+ at code{@var{command} @var{source} @var{target}}
+to install each file in a Mercury library.
+The default command is @samp{cp}.
+
+ at item --libgrade @var{grade}
+ at findex --libgrade
+Add @var{grade} to the list of compilation grades in
+which a library to be installed should be built.
+
+ at item --options-file @var{file}
+ at findex --options-file
+Add @var{file} to the list of options files to be processed.
+If no @samp{--options-file} options are given, the file
+ at file{Mercury.options} in the current directory will be
+read if it exists.
+
+ at item --options-search-directory @var{dir}
+Add @var{dir} to the list of directories to be searched for
+options files.
+
@item -I @var{dir}
@itemx --search-directory @var{dir}
@findex -I
@@ -5402,6 +5518,12 @@
@cindex @file{Mercury} subdirectory
Create intermediate files in a @file{Mercury} subdirectory,
rather than in the current directory.
+
+ at end table
+
+ at node Miscellaneous options
+ at section Miscellaneous options
+ at table @code
@sp 1
@item -?
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.241
diff -u -u -r1.241 io.m
--- library/io.m 4 Feb 2002 05:22:48 -0000 1.241
+++ library/io.m 4 Feb 2002 17:59:47 -0000
@@ -1131,6 +1131,23 @@
% signal kills the system call, then Result will be an error
% indicating which signal occured.
+:- type io__system_result
+ ---> exited(int)
+ ; signalled(int)
+ .
+
+:- pred io__call_system_return_signal(string, io__res(io__system_result),
+ io__state, io__state).
+:- mode io__call_system_return_signal(in, out, di, uo) is det.
+% io__call_system_return_signal(Command, Result, IO0, IO1).
+% Invokes the operating system shell with the specified
+% Command. Result is either `ok(ExitStatus)' if it was
+% possible to invoke the command and the it ran to completion,
+% `signal(SignalNum)' if the command was killed by a signal, or
+% `error(ErrorCode)' if the command could not be executed.
+% The `ExitStatus' will be 0 if the command completed
+% successfully or the return value of the command otherwise.
+
:- func io__error_message(io__error) = string.
:- pred io__error_message(io__error, string).
:- mode io__error_message(in, out) is det.
@@ -1185,17 +1202,24 @@
:- pred io__write_univ(univ, io__state, io__state).
:- mode io__write_univ(in, di, uo) is det.
-% This is the same as io__read_from_string, except that an integer
-% is allowed where a character is expected. This is needed by
-% extras/aditi/aditi.m because Aditi does not have a builtin
-% character type. This also allows an integer where a float
-% is expected.
+% For use by extras/aditi/aditi.m
+ % This is the same as io__read_from_string, except that an integer
+ % is allowed where a character is expected. This is needed because
+ % Aditi does not have a builtin character type. This also allows an
+ % integer where a float is expected.
:- pred io__read_from_string_with_int_instead_of_char(string, string, int,
io__read_result(T), posn, posn).
:- mode io__read_from_string_with_int_instead_of_char(in, in, in,
out, in, out) is det.
+% For use by compiler/make.util.m:
+
+ % Interpret the child process exit status returned by
+ % system() or wait().
+:- func io__handle_system_command_exit_status(int) =
+ io__res(io__system_result).
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -1272,13 +1296,13 @@
% Reads a character code from specified stream.
% Returns -1 if at EOF, -2 if an error occurs.
-:- pred io__call_system_code(string, int, io__state, io__state).
-:- mode io__call_system_code(in, out, di, uo) is det.
-% io__call_system_code(Command, Status, IO0, IO1).
+:- pred io__call_system_code(string, int, string, io__state, io__state).
+:- mode io__call_system_code(in, out, out, di, uo) is det.
+% io__call_system_code(Command, Status, Message, IO0, IO1).
% Invokes the operating system shell with the specified
-% Command. Returns Status = 127 on failure. Otherwise
-% returns the exit status as a positive integer, or the
-% signal which killed the command as a negative integer.
+% Command. Returns Status = 127 and Message on failure.
+% Otherwise returns the raw exit status from the system()
+% call.
:- pred io__do_open(string, string, int, io__input_stream,
io__state, io__state).
@@ -3155,18 +3179,27 @@
io__insert_stream_name(Stderr, "<standard error>").
io__call_system(Command, Result) -->
- io__call_system_code(Command, Status),
- { Status = 127 ->
- % XXX improve error message
- Result = error(io_error("can't invoke system command"))
- ; Status < 0 ->
- Signal is - Status,
+ io__call_system_return_signal(Command, Result0),
+ {
+ Result0 = ok(exited(Code)),
+ Result = ok(Code)
+ ;
+ Result0 = ok(signalled(Signal)),
string__int_to_string(Signal, SignalStr),
string__append("system command killed by signal number ",
SignalStr, ErrMsg),
Result = error(io_error(ErrMsg))
;
- Result = ok(Status)
+ Result0 = error(Error),
+ Result = error(Error)
+ }.
+
+io__call_system_return_signal(Command, Result) -->
+ io__call_system_code(Command, Code, Msg),
+ { Code = 127 ->
+ Result = error(io_error(Msg))
+ ;
+ Result = io__handle_system_command_exit_status(Code)
}.
:- type io__error
@@ -4780,18 +4813,46 @@
").
:- pragma foreign_proc("C",
- io__call_system_code(Command::in, Status::out, IO0::di, IO::uo),
+ io__call_system_code(Command::in, Status::out, Msg::out,
+ IO0::di, IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io],
"
Status = system(Command);
- if ( Status == -1 || Status == 127 ) {
+ if ( Status == -1 ) {
/*
** Return values of 127 or -1 from system() indicate that
** the system call failed. Dont return -1, as -1 indicates
** that the system call was killed by signal number 1.
*/
Status = 127;
+ ML_maybe_make_err_msg(TRUE,
+ ""error invoking system command: "",
+ MR_PROC_LABEL, Msg);
} else {
+ Msg = MR_make_string_const("""");
+ }
+ update_io(IO0, IO);
+").
+
+
+io__handle_system_command_exit_status(Code0) = Status :-
+ Code = io__handle_system_command_exit_code(Code0),
+ ( Code = 127 ->
+ Status = error(
+ io_error("unknown result code from system command"))
+ ; Code < 0 ->
+ Status = ok(signalled(-Code))
+ ;
+ Status = ok(exited(Code))
+ ).
+
+:- func io__handle_system_command_exit_code(int) = int.
+
+:- pragma foreign_proc("C",
+ io__handle_system_command_exit_code(Status0::in) = (Status::out),
+ [will_not_call_mercury, thread_safe, promise_pure],
+"
+ Status = Status0;
#if defined (WIFEXITED) && defined (WEXITSTATUS) && \
defined (WIFSIGNALED) && defined (WTERMSIG)
if (WIFEXITED(Status))
@@ -4810,8 +4871,6 @@
Status = (Status & 0xff00) >> 8;
#endif
- }
- update_io(IO0, IO);
").
:- pragma foreign_proc("MC++",
@@ -4853,7 +4912,8 @@
").
:- pragma foreign_proc("MC++",
- io__call_system_code(Command::in, Status::out, IO0::di, IO::uo),
+ io__call_system_code(Command::in, Status::out, _Msg::out,
+ IO0::di, IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io],
"
// XXX This could be better... need to handle embedded spaces.
@@ -4867,6 +4927,13 @@
update_io(IO0, IO);
").
+:- pragma foreign_proc("MC++",
+ io__handle_system_command_exit_code(Status0::in)
+ = (Status::out),
+ [will_not_call_mercury, thread_safe, promise_pure],
+"
+ mercury::runtime::Errors::SORRY(""foreign code for this function"");
+").
/*---------------------------------------------------------------------------*/
Index: library/list.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.103
diff -u -u -r1.103 list.m
--- library/list.m 29 Dec 2001 04:41:01 -0000 1.103
+++ library/list.m 5 Feb 2002 06:49:34 -0000
@@ -557,6 +557,8 @@
in, in, out, in, out, in, out) is semidet.
:- mode list__foldl3(pred(in, in, out, in, out, in, out) is nondet,
in, in, out, in, out, in, out) is nondet.
+:- mode list__foldl3(pred(in, in, out, in, out, di, uo) is det,
+ in, in, out, in, out, di, uo) is det.
% list__map_foldl(Pred, InList, OutList, Start, End) calls Pred
% with an accumulator (with the initial value of Start) on
@@ -573,6 +575,17 @@
:- mode list__map_foldl(pred(in, out, in, out) is nondet, in, out, in, out)
is nondet.
+ % Same as list__map_foldl, but with two accumulators.
+:- pred list__map_foldl2(pred(X, Y, A, A, B, B), list(X), list(Y), A, A, B, B).
+:- mode list__map_foldl2(pred(in, out, in, out, di, uo) is det,
+ in, out, in, out, di, uo) is det.
+:- mode list__map_foldl2(pred(in, out, in, out, in, out) is det,
+ in, out, in, out, in, out) is det.
+:- mode list__map_foldl2(pred(in, out, in, out, in, out) is semidet,
+ in, out, in, out, in, out) is semidet.
+:- mode list__map_foldl2(pred(in, out, in, out, in, out) is nondet,
+ in, out, in, out, in, out) is nondet.
+
% list__filter(Pred, List, TrueList) takes a closure with one
% input argument and for each member of List `X', calls the closure.
% Iff call(Pred, X) is true, then X is included in TrueList.
@@ -1335,6 +1348,11 @@
list__map_foldl(P, [H0|T0], [H|T]) -->
call(P, H0, H),
list__map_foldl(P, T0, T).
+
+list__map_foldl2(_, [], [], A, A) --> [].
+list__map_foldl2(P, [H0|T0], [H|T], A0, A) -->
+ call(P, H0, H, A0, A1),
+ list__map_foldl2(P, T0, T, A1, A).
list__foldr(_, [], Acc, Acc).
list__foldr(P, [H|T], Acc0, Acc) :-
Index: runtime/RESERVED_MACRO_NAMES
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/RESERVED_MACRO_NAMES,v
retrieving revision 1.8
diff -u -u -r1.8 RESERVED_MACRO_NAMES
--- runtime/RESERVED_MACRO_NAMES 2 Feb 2002 16:52:30 -0000 1.8
+++ runtime/RESERVED_MACRO_NAMES 3 Feb 2002 08:42:08 -0000
@@ -110,6 +110,7 @@
HAVE_SIGCONTEXT_STRUCT_3ARG
HAVE_SIGINFO
HAVE_SIGINFO_T
+HAVE_SIGINTERRUPT
HAVE_SNPRINTF
HAVE_STAT
HAVE_STRERROR
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.41
diff -u -u -r1.41 mercury_conf.h.in
--- runtime/mercury_conf.h.in 30 Jan 2002 14:51:07 -0000 1.41
+++ runtime/mercury_conf.h.in 5 Feb 2002 07:40:50 -0000
@@ -187,6 +187,7 @@
** HAVE__VSNPRINTF we have the _vsnprintf() function.
** HAVE_SYSCONF we have the sysconf() system call.
** HAVE_SIGACTION we have the sigaction() system call.
+** HAVE_SIGINTERRUPT we have the siginterrupt() function.
** HAVE_GETPAGESIZE we have the getpagesize() system call.
** HAVE_MPROTECT we have the mprotect() system call.
** HAVE_MEMALIGN we have the memalign() function.
@@ -228,6 +229,7 @@
#undef HAVE__VSNPRINTF
#undef HAVE_SYSCONF
#undef HAVE_SIGACTION
+#undef HAVE_SIGINTERRUPT
#undef HAVE_GETPAGESIZE
#undef HAVE_MEMALIGN
#undef HAVE_MPROTECT
Index: runtime/mercury_signal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_signal.c,v
retrieving revision 1.11
diff -u -u -r1.11 mercury_signal.c
--- runtime/mercury_signal.c 31 Jan 2002 17:10:17 -0000 1.11
+++ runtime/mercury_signal.c 2 Feb 2002 05:45:18 -0000
@@ -11,6 +11,7 @@
/*---------------------------------------------------------------------------*/
#include "mercury_imp.h"
+#include "mercury_signal.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -20,8 +21,6 @@
#include <string.h>
#include <errno.h>
-#include "mercury_signal.h"
-
#ifdef HAVE_SYS_SIGINFO
#include <sys/siginfo.h>
#endif
@@ -142,4 +141,30 @@
exit(1);
}
#endif /* not HAVE_SIGACTION */
+}
+
+void
+MR_signal_should_restart(int sig, bool restart)
+{
+#if defined(HAVE_SIGACTION)
+ struct sigaction act;
+ if (sigaction(sig, NULL, &act) != 0) {
+ MR_perror("error setting signal system call behaviour");
+ exit(1);
+ }
+ if (restart) {
+ act.sa_flags |= SA_RESTART;
+ } else {
+ act.sa_flags &= ~SA_RESTART;
+ }
+ if (sigaction(sig, &act, NULL) != 0) {
+ MR_perror("error setting signal system call behaviour");
+ exit(1);
+ }
+#elif defined(HAVE_SIGINTERRUPT)
+ if (siginterrupt(sig, !restart) != 0) {
+ MR_perror("error setting signal system call behaviour");
+ exit(1);
+ }
+#endif
}
Index: runtime/mercury_signal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_signal.h,v
retrieving revision 1.8
diff -u -u -r1.8 mercury_signal.h
--- runtime/mercury_signal.h 1 Feb 2002 08:43:20 -0000 1.8
+++ runtime/mercury_signal.h 1 Feb 2002 08:55:12 -0000
@@ -16,8 +16,6 @@
#ifndef MERCURY_SIGNAL_H
#define MERCURY_SIGNAL_H
-#include "mercury_types.h"
-#include "mercury_std.h"
#include "mercury_conf.h"
#ifdef HAVE_SIGCONTEXT_STRUCT
@@ -49,6 +47,9 @@
#include <signal.h>
#endif
+#include "mercury_types.h"
+#include "mercury_std.h"
+
#ifdef HAVE_SIGACTION
typedef struct sigaction MR_signal_action;
#else
@@ -92,5 +93,14 @@
*/
extern void MR_set_signal_action(int sig, MR_signal_action *action,
const char *error_message);
+
+ /*
+ ** Change the behaviour of system calls when the
+ ** the specified signal is received.
+ ** If restart is TRUE they will be restarted, if it
+ ** is false, they won't. This function may have no
+ ** effect on some systems.
+ */
+extern void MR_signal_should_restart(int sig, bool restart);
#endif /* not MERCURY_SIGNAL_H */
Index: scripts/Mmake.vars.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.vars.in,v
retrieving revision 1.61
diff -u -u -r1.61 Mmake.vars.in
--- scripts/Mmake.vars.in 11 Jan 2002 11:33:15 -0000 1.61
+++ scripts/Mmake.vars.in 24 Jan 2002 17:13:05 -0000
@@ -442,6 +442,7 @@
qls_subdir=$(SUBDIR)qls/
deps_subdir=$(SUBDIR)deps/
ds_subdir=$(SUBDIR)ds/
+module_deps_subdir=$(SUBDIR)module_deps/
int0s_subdir=$(SUBDIR)int0s/
ints_subdir=$(SUBDIR)ints/
int2s_subdir=$(SUBDIR)int2s/
@@ -464,10 +465,12 @@
rlos_subdir=
ils_subdir=$(SUBDIR)ils/
dirs_subdir=$(SUBDIR)dirs/
+num_splits_subdir=$(SUBDIR)num_splits/
c_dates_subdir=$(SUBDIR)c_dates/
s_dates_subdir=$(SUBDIR)s_dates/
pic_s_dates_subdir=$(SUBDIR)pic_s_dates/
il_dates_subdir=$(SUBDIR)il_dates/
+err_dates_subdir=$(SUBDIR)err_dates/
else
@@ -477,6 +480,7 @@
qls_subdir=
deps_subdir=
ds_subdir=
+module_deps_subdir=
int0s_subdir=
ints_subdir=
int2s_subdir=
@@ -497,10 +501,12 @@
rlos_subdir=
ils_subdir=
dirs_subdir=
+num_splits_subdir=
c_dates_subdir=
s_dates_subdir=
pic_s_dates_subdir=
il_dates_subdir=
+err_dates_subdir=
endif
Index: scripts/mmc.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/mmc.in,v
retrieving revision 1.18
diff -u -u -r1.18 mmc.in
--- scripts/mmc.in 19 Nov 2001 07:25:08 -0000 1.18
+++ scripts/mmc.in 3 Feb 2002 06:32:18 -0000
@@ -39,6 +39,10 @@
# The default optimization level should be after
# all the options that describe the machine configuration.
+# XXX Once the `mmc --make' change is installed everywhere, the default
+# option settings below should be set in the DEFAULT_MCFLAGS environment
+# variable to avoid having them override the value of MCFLAGS in the
+# Mercury.options file.
case $# in
0) exec $MC \
$MERC_ALL_MC_C_INCL_DIRS \
--------------------------------------------------------------------------
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