[m-rev.] for review: auto detection of library grades
Peter Wang
novalazy at gmail.com
Tue Sep 3 16:27:02 AEST 2013
On Wed, 28 Aug 2013 17:47:00 +1000 (EST), Julien Fischer <jfischer at opturion.com> wrote:
>
> For review by anyone.
>
> This change has also revealed a bug in the existing library grade check in
> mmc --make; I will fix that separately since that fix also needs to go on
> to the 13.05 branch.
>
> --------------------
>
>
> Auto detection of standard library grades.
>
> Currently, the set of installed standard library grades is hardcoded in
> Mercury's configuration file (and some other spots, but they are not relevant
> here). This change modifies the compiler so it can scan the standard library
> directory at runtime in order to determine what library grades are installed.
> This removes the need for the set of library grades to be specified in the
> configuration file at all. Adding or removing grades from an existing
> installation should now not require changes to any configuration files
> (provided you don't use mmake -- see below).
>
> In the case where the library grades are specified in the Mercury.config file
> and auto detection is also enabled, the auto detected grades will override any
> --libgrade settings from the Mercury.config file.
>
> Automatic detection of library grades is not supported with mmake and I don't
> have any plans to support it. mmake will just use the set of grades with
> which the installation was configured.
>
> compiler/options.m:
> Add a new option `--auto-detect-libgrades' that can be used to control
> the new feature. For now, this is a developer-only option and is
> disabled by default -- I will document it properly when it is enabled
> by default.
I assume it's intended to be enabled for mmc --make in future.
Minor thing, but I think the "auto"- and "Auto"- prefixes don't add
anything.
>
> compiler/mercury_compile.m:
> Scan the standard library directory to see what grades are installed
> and set the options necessary to make the set of library grades those
> that were detected.
>
> compiler/options_file.m:
> Add a predicate for looking up the value of the MERCURY_STDLIB_DIR
> variable.
>
> Julien.
>
> diff --git a/compiler/mercury_compile.m b/compiler/mercury_compile.m
> index 9e690bb..8623595 100644
> --- a/compiler/mercury_compile.m
> +++ b/compiler/mercury_compile.m
> @@ -89,6 +89,7 @@
> :- import_module assoc_list.
> :- import_module bool.
> :- import_module cord.
> +:- import_module dir.
> :- import_module gc.
> :- import_module getopt_io.
> :- import_module list.
> @@ -235,6 +236,7 @@ real_main_after_expansion(CmdLineArgs, !IO) :-
> OptionArgs = [],
> NonOptionArgs = []
> ),
> + AutoDetectedGradeFlags = [],
> Variables = options_variables_init,
> MaybeMCFlags = yes([])
> ;
> @@ -258,6 +260,7 @@ real_main_after_expansion(CmdLineArgs, !IO) :-
> (
> FlagsErrors = [_ | _],
> usage_errors(FlagsErrors, !IO),
> + AutoDetectedGradeFlags = [],
> Variables = options_variables_init,
> MaybeMCFlags = no
> ;
> @@ -271,14 +274,20 @@ real_main_after_expansion(CmdLineArgs, !IO) :-
> (
> MaybeVariables = yes(Variables),
> lookup_mmc_options(FlagsArgsGlobals, Variables,
> - MaybeMCFlags, !IO)
> + MaybeMCFlags, !IO),
> + lookup_mercury_stdlib_dir(FlagsArgsGlobals, Variables,
> + MaybeMerStdLibDir, !IO),
> + auto_detect_libgrades(FlagsArgsGlobals, MaybeMerStdLibDir,
> + AutoDetectedGradeFlags, !IO)
> ;
> MaybeVariables = no,
> MaybeMCFlags = no,
> + AutoDetectedGradeFlags = [],
> Variables = options_variables_init
> )
> ;
> MaybeConfigFile = no,
> + AutoDetectedGradeFlags = [],
> Variables = options_variables_init,
> lookup_mmc_options(FlagsArgsGlobals, Variables,
> MaybeMCFlags, !IO)
> @@ -287,18 +296,20 @@ real_main_after_expansion(CmdLineArgs, !IO) :-
> ;
> MaybeMCFlags0 = no,
> Variables = options_variables_init,
> + AutoDetectedGradeFlags = [],
> MaybeMCFlags = no
> )
> ;
> MaybeVariables0 = no,
> Variables = options_variables_init,
> + AutoDetectedGradeFlags = [],
> MaybeMCFlags = no
> )
> ),
> (
> MaybeMCFlags = yes(MCFlags),
> - handle_given_options(MCFlags ++ OptionArgs, _, _, _,
> - Errors, ActualGlobals, !IO),
> + AllFlags = MCFlags ++ AutoDetectedGradeFlags ++ OptionArgs,
> + handle_given_options(AllFlags, _, _, _, Errors, ActualGlobals, !IO),
>
> % When computing the option arguments to pass to `--make', only include
> % the command-line arguments, not the contents of DEFAULT_MCFLAGS.
> @@ -2025,6 +2036,107 @@ maybe_output_prof_call_graph(Verbose, Stats, !HLDS, !IO) :-
> ).
>
> %-----------------------------------------------------------------------------%
> +%
> +% Library grade detection.
> +%
> +
> +:- pred auto_detect_libgrades(globals::in, maybe(list(string))::in,
> + list(string)::out, io::di, io::uo) is det.
> +
> +auto_detect_libgrades(Globals, MaybeConfigMerStdLibDir, GradeOpts, !IO) :-
> + globals.lookup_bool_option(Globals, auto_detect_libgrades, AutoDetect),
> + (
> + AutoDetect = yes,
> + ( if
> + % Was the standard library directory set on the command line?
> + %
> + globals.lookup_maybe_string_option(Globals,
> + mercury_standard_library_directory, MaybeStdLibDir),
> + MaybeStdLibDir = yes(MerStdLibDir)
> + then
> + do_auto_detect_libgrades(MerStdLibDir, GradeOpts, !IO)
> + else if
> + % Was the standard library directory set using the
> + % MERCURY_STDLIB_DIR variable?
> + MaybeConfigMerStdLibDir = yes([MerStdLibDir])
> + then
> + do_auto_detect_libgrades(MerStdLibDir, GradeOpts, !IO)
> + else
> + GradeOpts = []
> + )
Maybe lookup_maybe_string_option followed by switch on MaybeStdLibDir.
> + ;
> + AutoDetect = no,
> + GradeOpts = []
> + ).
> +
> +:- pred do_auto_detect_libgrades(string::in, list(string)::out,
> + io::di, io::uo) is det.
> +
> +do_auto_detect_libgrades(StdLibDir, GradeOpts, !IO) :-
> + ModulesDir = StdLibDir / "modules",
> + dir.foldl2(do_auto_detect_libgrade, ModulesDir, [], MaybeGradeOpts, !IO),
> + (
> + MaybeGradeOpts = ok(GradeOpts0),
> + (
> + GradeOpts0 = [],
> + GradeOpts = GradeOpts0
> + ;
> + GradeOpts0 = [_ | _],
> + % Override any --libgrades settings from Mercury.config.
> + GradeOpts = ["--no-libgrade" | GradeOpts0]
> + )
> + ;
> + MaybeGradeOpts = error(_, _),
> + GradeOpts = []
> + ).
> +
> +:- pred do_auto_detect_libgrade(string::in, string::in, io.file_type::in,
> + bool::out, list(string)::in, list(string)::out, io::di, io::uo) is det.
> +
> +do_auto_detect_libgrade(DirName, FileName, FileType, Continue, !GradeOpts, !IO) :-
> + (
> + FileType = directory,
> + (
> + % We do not generate .init files for the non-C grades so just check
> + % for directories in StdLibDir / "modules" containing the name of
> + % their base grade.
> + %
> + ( string.prefix(FileName, "csharp")
> + ; string.prefix(FileName, "erlang")
> + ; string.prefix(FileName, "java")
> + )
> + ->
> + !:GradeOpts = ["--libgrade", FileName | !.GradeOpts]
> + ;
> + % For C grades, we check for the presence of the .init file for
> + % mer_std to test whether the grade is present or not.
> + %
> + InitFile = DirName / FileName / "mer_std.init",
> + io.check_file_accessibility(InitFile, [read], Result, !IO),
> + (
> + Result = ok,
> + !:GradeOpts = ["--libgrade", FileName | !.GradeOpts]
> + ;
> + Result = error(_)
> + )
> + ),
> + Continue = yes
Is the test for the .init file really necessary?
The list of non-C grade prefixes is another thing to maintain.
Peter
More information about the reviews
mailing list