[m-rev.] for review: add --order-make-by-timestamp option

Peter Wang novalazy at gmail.com
Thu Jan 28 12:51:15 AEDT 2010


Branches: main

Add an option for `mmc --make' to compile more recently edited source files
first, instead of in alphabetical order.  The intention is to catch errors
in modified files more quickly.

Note this does not affect "build_all" targets (e.g. foo.cs).

compiler/options.m:
doc/user_guide.texi:
NEWS:
        Add the option `--order-make-by-timestamp'.

compiler/make.program_target.m:
        Sort modules by timestamp when making a linked target, if the option is
        set.

diff --git a/NEWS b/NEWS
index 1cc20eb..05e99c9 100644
--- a/NEWS
+++ b/NEWS
@@ -299,6 +299,9 @@ Changes to the Mercury compiler:
 * We have added support for `mmc --make' to recompile modules if options have
   changed.
 
+* We have added an option for `mmc --make' to compile more recently edited
+  source files first.
+
 * We have added support for stack segments, which allows programs to grow
   stacks on demand.
 
@@ -527,6 +530,9 @@ Changes to the Mercury compiler:
   recompile modules whose options have changed, even if the files haven't
   been touched.
 
+* `mmc --make' can compile more recently edited files first, if the option
+  `--order-make-by-timestamp' is enabled.
+
 * The option `--stack-segments', or grade component `.stseg', causes
   programs to execute using stack segments, where segments can be allocated
   at runtime, instead of using fixed sized stacks.  The program won't run out
diff --git a/compiler/make.program_target.m b/compiler/make.program_target.m
index e4ccaf8..0497efd 100644
--- a/compiler/make.program_target.m
+++ b/compiler/make.program_target.m
@@ -185,7 +185,8 @@ make_linked_target_2(LinkedTargetFile, Globals, _, Succeeded, !Info, !IO) :-
 
         AllModulesList = set.to_sorted_list(AllModules),
         get_target_modules(Globals, IntermediateTargetType, AllModulesList,
-            ObjModules, !Info, !IO),
+            ObjModulesAlpha, !Info, !IO),
+        order_target_modules(Globals, ObjModulesAlpha, ObjModules, !Info, !IO),
         IntermediateTargets = make_dependency_list(ObjModules,
             IntermediateTargetType),
         ObjTargets = make_dependency_list(ObjModules, ObjectTargetType),
@@ -309,6 +310,56 @@ get_target_modules_2(Globals, ModuleName, !TargetModules, !Info, !IO) :-
         true
     ).
 
+:- pred order_target_modules(globals::in,
+    list(module_name)::in, list(module_name)::out,
+    make_info::in, make_info::out, io::di, io::uo) is det.
+
+order_target_modules(Globals, Modules, OrderedModules, !Info, !IO) :-
+    globals.lookup_bool_option(Globals, order_make_by_timestamp,
+        OrderByTimestamp),
+    (
+        OrderByTimestamp = yes,
+        list.map_foldl2(pair_module_with_timestamp(Globals),
+            Modules, PairedModules, !Info, !IO),
+        list.sort(compare_paired_modules, PairedModules, OrderedPairs),
+        list.map(pair.snd, OrderedPairs, OrderedModules)
+    ;
+        OrderByTimestamp = no,
+        OrderedModules = Modules
+    ).
+
+:- pred pair_module_with_timestamp(globals::in,
+    module_name::in, pair(timestamp, module_name)::out,
+    make_info::in, make_info::out, io::di, io::uo) is det.
+
+pair_module_with_timestamp(Globals, Module, Timestamp - Module, !Info, !IO) :-
+    Search = do_not_search,
+    Target = target_file(Module, module_target_source),
+    get_target_timestamp(Globals, Search, Target, MaybeTimestamp, !Info, !IO),
+    (
+        MaybeTimestamp = ok(Timestamp)
+    ;
+        MaybeTimestamp = error(_),
+        Timestamp = oldest_timestamp
+    ).
+
+:- pred compare_paired_modules(pair(timestamp, module_name)::in,
+    pair(timestamp, module_name)::in, comparison_result::out) is det.
+
+compare_paired_modules(TimeA - ModuleA, TimeB - ModuleB, Res) :-
+    compare(TimeRes, TimeA, TimeB),
+    % More recently touched files should appear earlier in the list.
+    (
+        TimeRes = (<),
+        Res = (>)
+    ;
+        TimeRes = (>),
+        Res = (<)
+    ;
+        TimeRes = (=),
+        compare(Res, ModuleA, ModuleB)
+    ).
+
 :- pred get_foreign_object_targets(globals::in, pic::in, module_name::in,
     list(dependency_file)::out, make_info::in, make_info::out,
     io::di, io::uo) is det.
diff --git a/compiler/options.m b/compiler/options.m
index c09dd02..28e56e0 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -938,6 +938,7 @@
     ;       intermod_directories
     ;       use_search_directories_for_intermod
     ;       libgrade_install_check
+    ;       order_make_by_timestamp
     ;       show_make_times
     ;       extra_library_header
     ;       restricted_command_line
@@ -1794,6 +1795,7 @@ option_defaults_2(build_system_option, [
     intermod_directories                -   accumulating([]),
     use_search_directories_for_intermod -   bool(yes),
     libgrade_install_check              -   bool(yes),
+    order_make_by_timestamp             -   bool(no),
     show_make_times                     -   bool(no),
     extra_library_header                -   accumulating([]),
     restricted_command_line             -   bool(no)
@@ -2696,6 +2698,7 @@ long_option("intermod-directory",   intermod_directories).
 long_option("use-search-directories-for-intermod",
                     use_search_directories_for_intermod).
 long_option("libgrade-install-check", libgrade_install_check).
+long_option("order-make-by-timestamp", order_make_by_timestamp).
 long_option("show-make-times",      show_make_times).
 long_option("extra-lib-header",     extra_library_header).
 long_option("extra-library-header", extra_library_header).
@@ -5501,6 +5504,8 @@ options_help_build_system -->
         "\tDo not check that libraries have been installed before",
         "\tattempting to use them.  (This option is only meaningful with",
         "\t`mmc --make'.)",
+        "--order-make-by-timestamp",
+        "\tMake `mmc --make' compile more recently edited source files first.",
         "--show-make-times",
         "\tReport run times for commands executed by `mmc --make'.",
         "--extra-library-header <file>, --extra-lib-header <file>",
diff --git a/doc/user_guide.texi b/doc/user_guide.texi
index 8645164..29dca30 100644
--- a/doc/user_guide.texi
+++ b/doc/user_guide.texi
@@ -9151,6 +9151,11 @@ current directory.
 work with @samp{mmc --make}).
 
 @sp 1
+ at item --order-make-by-timestamp
+ at findex --order-make-by-timestamp
+Make @samp{mmc --make} compile more recently edited source files first.
+
+ at sp 1
 @item --show-make-times
 @findex --show-make-times
 Report run times for commands executed by @samp{mmc --make}.

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list