[m-rev.] for review: improvements to the Java launcher scripts
Julien Fischer
jfischer at opturion.com
Sat Jul 23 02:10:10 AEST 2022
On Mon, 18 Jul 2022, Peter Wang wrote:
>>> I see that the java launcher from JDK 9+ supports the JDK_JAVA_OPTIONS
>>> variable so perhaps we can use that?
>>
>> We still support Java 8 (and that's not going anywhere soon). I would
>> like to avoid the same names as the variables supported by the Java
>> tools themselves. How about we change all of the variables in the
>> Mercury launchers that can be overridden to have a MERCURY_ prefix,
>> e.g.
>>
>> MERCURY_JAVA
>> MERCURY_JAVA_OPTIONS
>>
>> (There's some precedent for doing this since the shell scripts we use
>> in the C grades have MERCURY_C_COMPILER etc.)
>>
>> That should reduce the risk of clashes with (a) Java itself and (b)
>> other stuff written in Java.
The following diff does the above and addresses the other review
comments.
diff --git a/NEWS b/NEWS
index 3732d41..dc27c9f 100644
--- a/NEWS
+++ b/NEWS
@@ -408,6 +408,14 @@ Changes to the Mercury compiler
* The deprecated option `--trail-segments` has been deleted and the grade
component `trseg` is no longer accepted as a synonym for `tr`.
+* `--javac-flags` is now accepted as a synonym for `--java-flags`. Similarly
+ `--javac-flag` is now accepted as synonym for `--java-flags`.
+
+* The new options `--java-runtime-flags` and `--java-runtime-flags` can be
+ used to set flags for the Java interpreter in the launcher shell scripts or
+ batch files generated by the compiler when creating executables in the `java`
+ grade.
+
Changes to the extras distribution
----------------------------------
diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index c20b994..e8ff771 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2002-2012 The University of Melbourne.
+% Copyright (C) 2013-2022 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
@@ -871,7 +872,8 @@ compile_java_files(Globals, ProgressStream, ErrorStream,
),
globals.lookup_string_option(Globals, java_compiler, JavaCompiler),
- globals.lookup_accumulating_option(Globals, java_flags, JavaFlagsList),
+ globals.lookup_accumulating_option(Globals, java_compiler_flags,
+ JavaFlagsList),
globals.lookup_bool_option(Globals, restricted_command_line,
RestrictedCommandLine),
(
diff --git a/compiler/module_cmds.m b/compiler/module_cmds.m
index 6d11495..29856e2 100644
--- a/compiler/module_cmds.m
+++ b/compiler/module_cmds.m
@@ -910,6 +910,11 @@ write_java_shell_script(Globals, MainModuleName, JarFileName, Stream, !IO) :-
MercuryStdLibs ++ ["$CLASSPATH" | UserClasspath],
ClassPath = string.join_list("${SEP}", Java_Incl_Dirs),
+ globals.lookup_accumulating_option(Globals, java_runtime_flags,
+ RuntimeFlags),
+ RuntimeOpts0 = string.join_list(" ", RuntimeFlags),
+ RuntimeOpts = escape_single_quotes_for_shell_script(RuntimeOpts0),
+
globals.lookup_string_option(Globals, java_interpreter, Java),
mangle_sym_name_for_java(MainModuleName, module_qual, ".", ClassName),
@@ -923,8 +928,10 @@ write_java_shell_script(Globals, MainModuleName, JarFileName, Stream, !IO) :-
"esac\n",
"CLASSPATH=", ClassPath, "\n",
"export CLASSPATH\n",
- "JAVA=${JAVA:-", Java, "}\n",
- "exec \"$JAVA\" jmercury.", ClassName, " \"$@\"\n"
+ "MERCURY_JAVA=${MERCURY_JAVA:-'", Java, "'}\n",
+ "MERCURY_JAVA_OPTIONS=${MERCURY_JAVA_OPTIONS:-'", RuntimeOpts, "'}\n",
+ "exec \"$MERCURY_JAVA\" $MERCURY_JAVA_OPTIONS jmercury.", ClassName,
+ " \"$@\"\n"
], !IO).
% For the MSYS version of the Java launcher script, there are a few
@@ -959,6 +966,11 @@ write_java_msys_shell_script(Globals, MainModuleName, JarFileName, Stream,
Java_Incl_Dirs0),
ClassPath = string.join_list("\\;", Java_Incl_Dirs),
+ globals.lookup_accumulating_option(Globals, java_runtime_flags,
+ RuntimeFlags),
+ RuntimeOpts0 = string.join_list(" ", RuntimeFlags),
+ RuntimeOpts = escape_single_quotes_for_shell_script(RuntimeOpts0),
+
globals.lookup_string_option(Globals, java_interpreter, Java),
mangle_sym_name_for_java(MainModuleName, module_qual, ".", ClassName),
@@ -968,10 +980,21 @@ write_java_msys_shell_script(Globals, MainModuleName, JarFileName, Stream,
"DIR=$( cd \"${DIR}\" && pwd -W )\n",
"CLASSPATH=", ClassPath, "\n",
"export CLASSPATH\n",
- "JAVA=${JAVA:-", Java, "}\n",
- "exec \"$JAVA\" jmercury.", ClassName, " \"$@\"\n"
+ "MERCURY_JAVA=${MERCURY_JAVA:-'", Java, "'}\n",
+ "MERCURY_JAVA_OPTIONS=${MERCURY_JAVA_OPTIONS:-'", RuntimeOpts, "'}\n",
+ "exec \"$MERCURY_JAVA\" $MERCURY_JAVA_OPTIONS jmercury.", ClassName,
+ " \"$@\"\n"
], !IO).
+:- func escape_single_quotes_for_shell_script(string) = string.
+
+escape_single_quotes_for_shell_script(S) =
+ ( if string.contains_char(S, '\'') then
+ string.replace_all(S, "'", "'\\''")
+ else
+ S
+ ).
+
:- pred write_java_batch_file(globals::in, module_name::in, file_name::in,
io.text_output_stream::in, io::di, io::uo) is det.
@@ -984,16 +1007,22 @@ write_java_batch_file(Globals, MainModuleName, JarFileName, Stream, !IO) :-
["%CLASSPATH%" | UserClasspath],
ClassPath = string.join_list(";", Java_Incl_Dirs),
+ globals.lookup_accumulating_option(Globals, java_runtime_flags,
+ RuntimeFlags),
+ RuntimeOpts = string.join_list(" ", RuntimeFlags),
+
globals.lookup_string_option(Globals, java_interpreter, Java),
mangle_sym_name_for_java(MainModuleName, module_qual, ".", ClassName),
io.write_strings(Stream, [
"@echo off\n",
"rem Automatically generated by the Mercury compiler.\n",
- "setlocal\n",
+ "setlocal enableextensions\n",
"set DIR=%~dp0\n",
"set CLASSPATH=", ClassPath, "\n",
- Java, " jmercury.", ClassName, " %*\n"
+ "if not defined MERCURY_JAVA_OPTIONS set MERCURY_JAVA_OPTIONS=",
+ RuntimeOpts, "\n",
+ Java, " %MERCURY_JAVA_OPTIONS% jmercury.", ClassName, " %*\n"
], !IO).
get_mercury_std_libs_for_java(Globals, !:StdLibs) :-
diff --git a/compiler/options.m b/compiler/options.m
index c036a12..8d24e5275 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1994-2012 The University of Melbourne.
-% Copyright (C) 2013-2021 The Mercury team.
+% Copyright (C) 2013-2022 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -962,10 +962,12 @@
% Java
; java_compiler
; java_interpreter
- ; java_flags
- ; quoted_java_flag
+ ; java_compiler_flags
+ ; quoted_java_compiler_flag
; java_classpath
; java_object_file_extension
+ ; java_runtime_flags
+ ; quoted_java_runtime_flag
% C#
; csharp_compiler
@@ -1898,10 +1900,12 @@ optdef(oc_target_comp, csharp_compiler_type, string("mono")).
% Java
optdef(oc_target_comp, java_compiler, string("javac")).
optdef(oc_target_comp, java_interpreter, string("java")).
-optdef(oc_target_comp, java_flags, accumulating([])).
-optdef(oc_target_comp, quoted_java_flag, string_special).
+optdef(oc_target_comp, java_compiler_flags, accumulating([])).
+optdef(oc_target_comp, quoted_java_compiler_flag, string_special).
optdef(oc_target_comp, java_classpath, accumulating([])).
optdef(oc_target_comp, java_object_file_extension, string(".class")).
+optdef(oc_target_comp, java_runtime_flags, accumulating([])).
+optdef(oc_target_comp, quoted_java_runtime_flag, string_special).
% C#
optdef(oc_target_comp, csharp_compiler, string("csc")).
@@ -2950,14 +2954,18 @@ long_option("csharp-compiler-type", csharp_compiler_type).
long_option("java-compiler", java_compiler).
long_option("javac", java_compiler).
long_option("java-interpreter", java_interpreter).
-long_option("java-flags", java_flags).
-long_option("java-flag", quoted_java_flag).
+long_option("javac-flags", java_compiler_flags).
+long_option("javac-flag", quoted_java_compiler_flag).
+long_option("java-flags", java_compiler_flags).
+long_option("java-flag", quoted_java_compiler_flag).
% 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 just synonyms.
long_option("java-debug", target_debug).
long_option("java-classpath", java_classpath).
long_option("java-object-file-extension", java_object_file_extension).
+long_option("java-runtime-flags", java_runtime_flags).
+long_option("java-runtime-flag", quoted_java_runtime_flag).
long_option("csharp-compiler", csharp_compiler).
long_option("csharp-flags", csharp_flags).
@@ -3430,9 +3438,13 @@ special_handler(Option, SpecialData, !.OptionTable, Result, !OptOptions) :-
SpecialData = string(Flag),
handle_quoted_flag(msvc_flags, Flag, !OptionTable)
;
- Option = quoted_java_flag,
+ Option = quoted_java_compiler_flag,
SpecialData = string(Flag),
- handle_quoted_flag(java_flags, Flag, !OptionTable)
+ handle_quoted_flag(java_compiler_flags, Flag, !OptionTable)
+ ;
+ Option = quoted_java_runtime_flag,
+ SpecialData = string(Flag),
+ handle_quoted_flag(java_runtime_flags, Flag, !OptionTable)
;
Option = quoted_csharp_flag,
SpecialData = string(Flag),
@@ -6382,18 +6394,24 @@ options_help_target_code_compilation(Stream, !IO) :-
"\tSpecify which Java interpreter to use.",
"\tThe default is `java'",
+ "--javac-flags <options>, --javac-flag <option>",
"--java-flags <options>, --java-flag <option>",
"\tSpecify options to be passed to the Java compiler.",
- "\t`--java-flag' should be used for single words which need",
- "\tto be quoted when passed to the shell.",
+ "\t`--java-flag' or `--javac-flag' should be used for single words",
+ "\twhich need to be quoted when passed to the shell.",
"--java-classpath <path>",
- "\tSet the classpath for the Java compiler.",
+ "\tSet the classpath for the Java compiler and interpreter.",
"--java-object-file-extension <ext>",
"\tSpecify an extension for Java object (bytecode) files",
"\tBy default this is `.class'.",
+ "--java-runtime-flags <options>, java-runtime-flag <option>",
+ "\tSpecify options to be passed to the Java interpreter.",
+ "\t`--java-runtime-flag' should be used for single words which need",
+ "\tto be quoted when passed to the shell.",
+
"--csharp-compiler <csc>",
"\tSpecify the name of the C# Compiler. The default is `csc'.",
"--csharp-flags <options>, --csharp-flag <option>",
diff --git a/doc/user_guide.texi b/doc/user_guide.texi
index 833b648..b8e6d47 100644
--- a/doc/user_guide.texi
+++ b/doc/user_guide.texi
@@ -345,11 +345,19 @@ for further details.)
When targeting Java,
@samp{mmc} will package up all of the class files for the executable
into a Java archive (JAR) named @file{@var{filename}.jar}.
-If you are using the Windows command line interpreter @samp{cmd.exe},
- at samp{mmc} will generate a batch file called @file{@var{filename}.bat}
-that invokes the program using the Java interpreter.
-Otherwise, it will generate a shell script called @file{@var{filename}}
-that also invokes the program using the Java interpreter.
+It will also generate a launcher that invokes the program using the Java
+interpreter.
+If you are using the Windows command line interpreter @samp{cmd.exe}, this
+launcher will be a batch file called @file{@var{filename}.bat}.
+Otherwise, the launcher will be a shell script called @file{@var{filename}}.
+Java runtime flags can be set using @samp{mmc}'s @samp{--java-runtime-flags} or
+ at samp{--java-runtime-flag} options.
+Such Java runtime flags will be included in the generated launcher shell script
+or batch file.
+You may override any runtime flags set at (Mercury) compile time by setting the
+variable @var{MERCURY_JAVA_OPTIONS} in the environment.
+Classpath settings made using @samp{mmc}'s @samp{--java-classpath} option will
+also be included in the generated launcher shell script or batch file.
If you use Mmake or @samp{mmc --make},
then you do not need to understand the details
@@ -9950,8 +9958,12 @@ Specify which Java interpreter to use. The default is @samp{java}.
@sp 1
@item --java-flags @var{options}
@itemx --java-flag @var{option}
+ at itemx --javac-flags @var{options}
+ at itemx --javac-flag @var{option}
@findex --java-flags
@findex --java-flag
+ at findex --javac-flags
+ at findex --javac-flags
@cindex Java compiler options
Specify options to be passed to the Java compiler.
@samp{--java-flag} should be used for single words which need
@@ -9962,7 +9974,7 @@ to be quoted when passed to the shell.
@findex --java-classpath
@cindex classpath
@cindex Directories
-Set the classpath for the Java compiler.
+Set the classpath for the Java compiler and interpreter.
@sp 1
@item --java-object-file-extension @var{extension}
@@ -9972,6 +9984,16 @@ Specify an extension for Java object (bytecode) files. By default this
is @samp{.class}.
@sp 1
+ at item --java-runtime-flags @var{options}
+ at itemx --java-runtime-flag @var{option}
+ at findex --java-runtime-flags
+ at findex --java-runtime
+ at cindex Java runtime options
+Specify options to be passed to the Java interpreter.
+ at samp{--java-runtime-flag} should be used for single words which need
+to be quoted when passed to the shell.
+
+ at sp 1
@item --csharp-compiler @var{compiler-name}
@findex --csharp-compiler
@cindex C# compiler
Julien.
More information about the reviews
mailing list