[m-rev.] for review: library grade check for `mmc --make'

Julien Fischer juliensf at csse.unimelb.edu.au
Thu May 15 17:39:11 AEST 2008


For review by anyone.  (This is still pending a bootcheck.)

Estimated hours taken: 4
Branches: main

Add a check to `mmc --make' that causes it to check that any libraries
(including the standard library) required for building an executable or
library target are installed and accessible in the compilation grade.  Emit an
error message where they are not.  (The compiler's current behaviour varies
from reporting .mih files are missing through to linker errors.)

The check is implemented by searching for a library's .init file, which works
since every library has a .init file and the .init file is grade dependent.

compiler/options.m:
 	Add a new option `--libgrade-install-check' to control the new check.

compiler/handle_options.m:
 	Only enable --libgrade-intall-check if --make is enabled.

compiler/make.program_target.m:
 	Implement the new check.

 	When building a linked target, i.e. an executable or library,
 	first check that all required libraries are available in the
 	compilation grade.

doc/user_guide.texi:
 	Document the new option.

Julien.

Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.318
diff -u -r1.318 handle_options.m
--- compiler/handle_options.m	27 Mar 2008 12:41:22 -0000	1.318
+++ compiler/handle_options.m	15 May 2008 07:27:03 -0000
@@ -778,6 +778,9 @@
          % and they don't need to be recreated when compiling to C.
          option_implies(invoked_by_mmc_make,
              generate_mmc_make_module_dependencies, bool(no), !Globals),
+ 
+        % --libgrade-install-check only works with --make
+        option_neg_implies(make, libgrade_install_check, bool(no), !Globals),

          % `--transitive-intermodule-optimization' and `--make' are
          % not compatible with each other.
Index: compiler/make.program_target.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make.program_target.m,v
retrieving revision 1.82
diff -u -r1.82 make.program_target.m
--- compiler/make.program_target.m	27 Mar 2008 02:29:42 -0000	1.82
+++ compiler/make.program_target.m	15 May 2008 07:27:03 -0000
@@ -45,6 +45,7 @@
  :- import_module libs.handle_options.
  :- import_module libs.process_util.
  :- import_module parse_tree.prog_foreign.
+:- import_module parse_tree.prog_io.
  :- import_module parse_tree.prog_out.
  :- import_module transform_hlds.
  :- import_module transform_hlds.mmc_analysis.
@@ -55,7 +56,7 @@

  %-----------------------------------------------------------------------------%

-make_linked_target(LinkedTargetFile, Succeeded, !Info, !IO) :-
+make_linked_target(LinkedTargetFile, LinkedTargetSucceeded, !Info, !IO) :-
      LinkedTargetFile = linked_target_file(MainModuleName, FileType),
      (
          FileType = shared_library,
@@ -78,31 +79,49 @@
              not list.member("shared", LibLinkages)
          )
      ->
-        Succeeded = yes
+        LinkedTargetSucceeded = yes
      ;
-        % When using `--intermodule-analysis', perform an analysis pass first.
-        % The analysis of one module may invalidate the results of a module we
-        % analysed earlier, so this step must be carried out until all the
-        % `.analysis' files are in a valid state before we can continue.
-        globals.io_lookup_bool_option(intermodule_analysis,
-            IntermoduleAnalysis, !IO),
-        (
-            IntermoduleAnalysis = yes,
-            make_misc_target_builder(
-                MainModuleName - misc_target_build_analyses,
-                ExtraOptions, Succeeded0, !Info, !IO)
+        globals.io_lookup_bool_option(libgrade_install_check,
+            LibgradeCheck, !IO),
+        (
+            LibgradeCheck = yes,
+            check_libraries_are_installed(LibgradeCheckSucceeded, !IO)
          ;
-            IntermoduleAnalysis = no,
-            Succeeded0 = yes
+            LibgradeCheck = no,
+            LibgradeCheckSucceeded = yes
+        ),
+
+        ( 
+            LibgradeCheckSucceeded = yes,
+            % When using `--intermodule-analysis', perform an analysis pass
+            % first.  The analysis of one module may invalidate the results of
+            % a module we analysed earlier, so this step must be carried out
+            % until all the `.analysis' files are in a valid state before we
+            % can continue.
+            globals.io_lookup_bool_option(intermodule_analysis,
+                IntermodAnalysis, !IO),
+            (
+                IntermodAnalysis = yes,
+                make_misc_target_builder(
+                    MainModuleName - misc_target_build_analyses,
+                    ExtraOptions, IntermodAnalysisSucceeded, !Info, !IO)
+            ;
+                IntermodAnalysis = no,
+                IntermodAnalysisSucceeded = yes
+            )
+        ;
+            LibgradeCheckSucceeded = no,
+            IntermodAnalysisSucceeded = no
          ),
+
          (
-            Succeeded0 = yes,
+            IntermodAnalysisSucceeded = yes,
              build_with_module_options(MainModuleName, ExtraOptions,
                  make_linked_target_2(LinkedTargetFile),
-                Succeeded, !Info, !IO)
+                LinkedTargetSucceeded, !Info, !IO)
          ;
-            Succeeded0 = no,
-            Succeeded = no
+            IntermodAnalysisSucceeded = no,
+            LinkedTargetSucceeded = no
          )
      ).

@@ -1705,6 +1724,95 @@
      make_remove_file(very_verbose, ModuleName, ".request", !Info, !IO).

  %-----------------------------------------------------------------------------%
+%
+% Check that the Mercury libraries required to build a linked target
+% are installed in the selected grade.
+% 
+
+    % Check that all Mercury libraries required by the linked target are
+    % installed in the selected grade.
+    %
+:- pred check_libraries_are_installed(bool::out, io::di, io::uo) is det.
+
+check_libraries_are_installed(Succeeded, !IO) :-
+    io_get_globals(Globals, !IO),
+    % NOTE: we don't look up the value of the option init_files here because
+    % that may include .init files other than those associated with any
+    % libraries.
+    globals.lookup_accumulating_option(Globals, mercury_libraries, Libs),
+    globals.lookup_accumulating_option(Globals, init_file_directories,
+        InitFileDirs),
+    grade_directory_component(Globals, Grade),
+    check_stdlib_is_installed(Grade, Succeeded0, !IO),
+    list.foldl2(check_library_is_installed(InitFileDirs, Grade),
+        Libs, Succeeded0, Succeeded, !IO).
+
+:- pred check_stdlib_is_installed(string::in, bool::out, io::di, io::uo)
+    is det.
+
+check_stdlib_is_installed(Grade, Succeeded, !IO) :-
+    verbose_msg(debug_make,
+        (pred(!.IO::di, !:IO::uo) is det :-
+            io.format("Checking that the Mercury standard library is " ++
+                "installed in grade `%s'.\n", [s(Grade)], !IO)
+        ), !IO),
+    globals.io_lookup_maybe_string_option(
+        mercury_standard_library_directory, MaybeStdLibDir, !IO),
+    (
+        MaybeStdLibDir = yes(StdLibDir),
+        % We check for the presence mer_std.init in the required grade.
+        % Unless the installation is broken this implies the presence
+        % of the the other standard .init files in that grade.
+        StdLibInitFile = StdLibDir / "modules" / Grade / "mer_std.init",
+        io.see(StdLibInitFile, Result, !IO),
+        (
+            Result = ok,
+            io.seen(!IO),
+            Succeeded = yes
+        ;
+            Result = error(_),
+            io.stderr_stream(Stderr, !IO),
+            io.progname_base("mercury_compile", ProgName, !IO),
+            io.format(Stderr,
+                "%s: error: the Mercury standard library "  ++
+                " cannot be found in grade %s.\n",
+                [s(ProgName), s(Grade)], !IO),
+            Succeeded = no
+        )
+    ;
+        MaybeStdLibDir = no,
+        Succeeded = yes
+    ).
+ 
+:- pred check_library_is_installed(list(string)::in, string::in,
+    string::in, bool::in, bool::out, io::di, io::uo) is det.
+
+check_library_is_installed(Dirs, Grade, LibName, !Succeeded, !IO) :-
+    verbose_msg(debug_make,
+        (pred(!.IO::di, !:IO::uo) is det :-
+            io.format("Checking that %s is installed in grade `%s'.\n",
+                [s(LibName), s(Grade)], !IO)
+        ), !IO),
+    % We check for the presence of a library in a particular grade by
+    % seeing whether its .init file.  This will work because all
+    % libraries have a grade dependent .init file.
+    InitFileName = LibName ++ ".init",
+    search_for_file(Dirs, InitFileName, SearchResult, !IO),
+    (
+        SearchResult = ok(_),
+        % search_for_file/5 has opened the file, so close it.
+        io.seen(!IO)
+    ;
+        SearchResult = error(_),
+        io.stderr_stream(Stderr, !IO),
+        io.progname_base("mercury_compile", ProgName, !IO),
+        io.format(Stderr,
+            "%s: error: the library `%s' cannot be found in grade `%s'.\n",
+            [s(ProgName), s(LibName), s(Grade)], !IO),
+        !:Succeeded = no
+    ). 
+
+%-----------------------------------------------------------------------------%

  :- func this_file = string.

Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.615
diff -u -r1.615 options.m
--- compiler/options.m	3 May 2008 14:53:59 -0000	1.615
+++ compiler/options.m	15 May 2008 07:27:04 -0000
@@ -851,6 +851,7 @@
      ;       search_directories
      ;       intermod_directories
      ;       use_search_directories_for_intermod
+    ;       libgrade_install_check

      % Miscellaneous Options
      ;       filenames_from_stdin
@@ -1661,7 +1662,8 @@
      use_grade_subdirs                   -   bool(no),
      search_directories                  -   accumulating(["."]),
      intermod_directories                -   accumulating([]),
-    use_search_directories_for_intermod -   bool(yes)
+    use_search_directories_for_intermod -   bool(yes),
+    libgrade_install_check              -   bool(yes)
  ]).
  option_defaults_2(miscellaneous_option, [
      % Miscellaneous Options
@@ -2507,6 +2509,8 @@
  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).
+

  % misc options
  long_option("typecheck-ambiguity-warn-limit",
@@ -5132,7 +5136,11 @@
          "\tExecutables and libraries will be symlinked or copied into",
          "\tthe current directory.",
          "\t`--use-grade-subdirs' does not work with Mmake (it does",
-        "\twork with `mmc --make')."
+        "\twork with `mmc --make').",
+        "--no-libgrade-install-check",
+        "\tDo not check that libraries have been installed before",
+        "\tattempting to use them.  (This option is only meaningful with",
+        "\t`mmc --make'.)"
      ]).

  :- pred options_help_misc(io::di, io::uo) is det.
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.562
diff -u -r1.562 user_guide.texi
--- doc/user_guide.texi	3 May 2008 14:54:00 -0000	1.562
+++ doc/user_guide.texi	15 May 2008 07:27:05 -0000
@@ -8852,6 +8852,12 @@
  to be searched for @samp{.opt} files.

  @sp 1
+ at item --no-libgrade-install-check
+ at findex --no-libgrade-install-check
+Do not check that libraries have been installed before attempting
+to use them.  (This option is only meaningful with `mmc --make'.)
+
+ at sp 1
  @item --use-subdirs
  @findex --use-subdirs
  @cindex File names

--------------------------------------------------------------------------
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