[m-rev.] for post-commit review: generate batch file launchers for the java grade on Windows

Julien Fischer juliensf at csse.unimelb.edu.au
Tue Jan 4 13:06:40 AEDT 2011


For post-commit review.

The erlang grade runs into path related problems on MinGW (probably 
because of mixing of Unix- and Windows-style paths).  I will add support
for batch files with the erlang grade once I get it to work by hand.

Note that the Mercury compiler does not (currently) do any runtime 
translation of paths based on the setting of --{host,target}-env-type,
so setting --target-env-type=windows also assumes that the directory paths
in Mercury.config etc have been set appropriately.  For the 11.01 release,
this should be ok, anyone packaging Mercury for Windows with the java 
grade should set --target-env-type=windows in Mercury.config.

------

Branches: main, 11.01

Generate a batch file as a launcher for programs built in the java grade rather
than a shell script if --target-env-type=windows is set.

Put the infrastructure in place for doing the same for the erlang grade.

compiler/module_cmds.m:
 	As above.

Julien.

Index: compiler/module_cmds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/module_cmds.m,v
retrieving revision 1.15
diff -u -r1.15 module_cmds.m
--- compiler/module_cmds.m	2 Jan 2011 14:37:56 -0000	1.15
+++ compiler/module_cmds.m	4 Jan 2011 01:56:13 -0000
@@ -106,7 +106,8 @@
              % Output the command line with `--verbose-commands'. This should be
              % used for commands that may be of interest to the user.

-    % invoke_system_command(Globals, ErrorStream, Verbosity, Command, Succeeded)
+    % invoke_system_command(Globals, ErrorStream, Verbosity, Command,
+    %       Succeeded):
      %
      % Invoke an executable. Both standard and error output will go to the
      % specified output stream.
@@ -187,6 +188,10 @@
      pred(io.output_stream, io, io)::in(pred(in, di, uo) is det),
      bool::out, io::di, io::uo) is det.

+:- pred create_launcher_batch_file(globals::in, module_name::in,
+    pred(io.output_stream, io, io)::in(pred(in, di, uo) is det),
+    bool::out, io::di, io::uo) is det.
+
  %-----------------------------------------------------------------------------%
  %-----------------------------------------------------------------------------%

@@ -676,13 +681,24 @@
  %

  create_java_shell_script(Globals, MainModuleName, Succeeded, !IO) :-
-    % XXX We should also create a ".bat" on Windows.
-    create_launcher_shell_script(Globals, MainModuleName,
-        write_java_shell_script(Globals, MainModuleName),
-        Succeeded, !IO).
+    get_target_env_type(Globals, TargetEnvType),
+    (
+        ( TargetEnvType = env_type_posix
+        ; TargetEnvType = env_type_cygwin
+        ; TargetEnvType = env_type_msys
+        ),
+        create_launcher_shell_script(Globals, MainModuleName,
+            write_java_shell_script(Globals, MainModuleName),
+            Succeeded, !IO)
+    ;
+        TargetEnvType = env_type_win_cmd,
+        create_launcher_batch_file(Globals, MainModuleName,
+            write_java_batch_file(Globals, MainModuleName),
+            Succeeded, !IO)
+    ).

  :- pred write_java_shell_script(globals::in, module_name::in,
-    io.output_stream::in, io::di, io::uo) is det.
+    io.text_output_stream::in, io::di, io::uo) is det.

  write_java_shell_script(Globals, MainModuleName, Stream, !IO) :-
      % In shell scripts always use / separators, even on Windows.
@@ -713,7 +729,34 @@
          "exec $JAVA jmercury.", ClassName, " \"$@\"\n"
      ], !IO).

+:- pred write_java_batch_file(globals::in, module_name::in,
+    io.text_output_stream::in, io::di, io::uo) is det.
+
+write_java_batch_file(Globals, MainModuleName, Stream, !IO) :-
+    get_class_dir_name(Globals, ClassDirName),
+
+    get_mercury_std_libs_for_java(Globals, MercuryStdLibs),
+    globals.lookup_accumulating_option(Globals, java_classpath,
+        UserClasspath),
+    % We prepend the .class files' directory and the current CLASSPATH.
+    Java_Incl_Dirs = ["%DIR%\\" ++ ClassDirName] ++ MercuryStdLibs ++
+        ["%CLASSPATH%" | UserClasspath],
+    ClassPath = string.join_list(";", Java_Incl_Dirs),
+
+    globals.lookup_string_option(Globals, java_interpreter, Java),
+    mangle_sym_name_for_java(MainModuleName, module_qual, ".", ClassName),
+
+    list.foldl(io.write_string(Stream), [
+        "@echo off\n",
+        "rem Automatically generated by the Mercury compiler.\n",
+        "setlocal\n",
+        "set DIR=$~dp0\n",
+        "set CLASSPATH=", ClassPath, "\n",
+        Java, " jmercury.", ClassName, " %*\n"
+    ], !IO).
+
      % NOTE: changes here may require changes to get_mercury_std_libs.
+    %
  get_mercury_std_libs_for_java(Globals, !:StdLibs) :-
      !:StdLibs = [],
      globals.lookup_maybe_string_option(Globals,
@@ -845,12 +888,24 @@
  %

  create_erlang_shell_script(Globals, MainModuleName, Succeeded, !IO) :-
-    create_launcher_shell_script(Globals, MainModuleName,
-        write_erlang_shell_script(Globals, MainModuleName),
-        Succeeded, !IO).
+    get_target_env_type(Globals, TargetEnvType),
+    (
+        ( TargetEnvType = env_type_posix
+        ; TargetEnvType = env_type_cygwin
+        ; TargetEnvType = env_type_msys
+        ),
+        create_launcher_shell_script(Globals, MainModuleName,
+            write_erlang_shell_script(Globals, MainModuleName),
+            Succeeded, !IO)
+    ;
+        TargetEnvType = env_type_win_cmd,
+        create_launcher_batch_file(Globals, MainModuleName,
+            write_erlang_batch_file(Globals, MainModuleName),
+            Succeeded, !IO)
+    ).

  :- pred write_erlang_shell_script(globals::in, module_name::in,
-    io.output_stream::in, io::di, io::uo) is det.
+    io.text_output_stream::in, io::di, io::uo) is det.

  write_erlang_shell_script(Globals, MainModuleName, Stream, !IO) :-
      globals.lookup_string_option(Globals, erlang_object_file_extension,
@@ -909,6 +964,12 @@
          " -s init stop -extra ""$@""\n"
      ], !IO).

+:- pred write_erlang_batch_file(globals::in, module_name::in,
+    io.text_output_stream::in, io::di, io::uo) is det.
+
+write_erlang_batch_file(_Globals, _MainModuleName, _Stream, _, _) :-
+    sorry($pred, "Batch file lanuchers NYI for Erlang graade.").
+
  :- pred find_erlang_library_path(globals::in, list(dir_name)::in, string::in,
      string::out, io::di, io::uo) is det.

@@ -982,6 +1043,33 @@

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

+create_launcher_batch_file(Globals, MainModuleName, Pred, Succeeded, !IO) :-
+    Extension = "",
+    module_name_to_file_name(Globals, MainModuleName, Extension,
+        do_not_create_dirs, BaseFileName, !IO),
+
+    FileName = BaseFileName ++ ".bat",
+
+    globals.lookup_bool_option(Globals, verbose, Verbose),
+    maybe_write_string(Verbose, "% Generating batch file `" ++
+        FileName ++ "'...\n", !IO),
+
+    % Remove symlink in the way, if any.
+    io.remove_file(FileName, _, !IO),
+    io.open_output(FileName, OpenResult, !IO),
+    (
+        OpenResult = ok(Stream),
+        Pred(Stream, !IO),
+        io.close_output(Stream, !IO),
+        Succeeded = yes
+    ;
+        OpenResult = error(Message),
+        unexpected(this_file, io.error_message(Message)),
+        Succeeded = no
+    ).
+
+%-----------------------------------------------------------------------------%
+
  :- func this_file = string.

  this_file = "module_cmds.m".

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