[m-rev.] for review: mmc --make jar archives

Peter Wang novalazy at gmail.com
Tue May 5 16:26:17 AEST 2009


Branches: main

Support generating Java archives (.jar) with `mmc --make'.

compiler/make.program_target.m:
compiler/compile_target_code.m:
        Make `build_linked_target_2' call `compile_target_code.link' instead of
        `create_java_shell_script' so that jar targets don't produce shell
        scripts.

        Make `compile_target_code.link' call `create_java_shell_script' so
        that Java executable targets don't try to produce native executables.

compiler/module_cmds.m:
        Rename `list_class_files_for_jar' to `list_class_files_for_jar_mmake'.

        Add a version of `list_class_files_for_jar' where we are given the
        actual list of .class files.  The old version was given only a mmake
        variable reference so generated a shell expression that relied on `sed'
        to strip `Mercury/classs' prefixes off paths.

compiler/write_deps_file.m:
        Conform to renaming.

library/string.m:
NEWS:
        Add string.remove_prefix_if_present/2.

diff --git a/NEWS b/NEWS
index 27ccc75..691f124 100644
--- a/NEWS
+++ b/NEWS
@@ -126,6 +126,7 @@ Changes to the Mercury standard library:
 	string.split_at_char/2
 	string.split_at_string/2
 	string.remove_suffix_if_present/2
+	string.remove_prefix_if_present/2
 	string.is_all_digits/1
 	string.all_match/2
 	string.remove_prefix/3
diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index f298c87..16dce04 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -1610,9 +1610,11 @@ link(ErrorStream, LinkTargetType, ModuleName,
ObjectsList, Succeeded, !IO) :-
             Target = target_erlang,
             create_erlang_shell_script(ModuleName, LinkSucceeded, !IO)
         ;
+            Target = target_java,
+            create_java_shell_script(ModuleName, LinkSucceeded, !IO)
+        ;
             ( Target = target_c
             ; Target = target_il
-            ; Target = target_java
             ; Target = target_asm
             ; Target = target_x86_64
             ),
@@ -2333,8 +2335,7 @@ create_java_archive(ErrorStream, ModuleName,
JarFileName, ObjectList,
     Jar = "jar",
     JarCreateFlags = "cf",

-    join_quoted_string_list(ObjectList, "", "", " ", Objects),
-    list_class_files_for_jar(ModuleName, Objects, ListClassFiles, !IO),
+    list_class_files_for_jar(ModuleName, ObjectList, ListClassFiles, !IO),
     Cmd = string.append_list([
         Jar, " ", JarCreateFlags, " ", JarFileName, " ", ListClassFiles ]),

diff --git a/compiler/make.program_target.m b/compiler/make.program_target.m
index 7bf69cf..61bca8c 100644
--- a/compiler/make.program_target.m
+++ b/compiler/make.program_target.m
@@ -564,6 +564,7 @@ build_linked_target_2(MainModuleName, FileType,
OutputFileName, MaybeTimestamp,
             ( CompilationTarget = target_c
             ; CompilationTarget = target_asm
             ; CompilationTarget = target_erlang
+            ; CompilationTarget = target_java
             ),
             % Run the link in a separate process so it can be killed
             % if an interrupt is received.
@@ -577,9 +578,6 @@ build_linked_target_2(MainModuleName, FileType,
OutputFileName, MaybeTimestamp,
         ;
             CompilationTarget = target_il,
             Succeeded = yes
-        ;
-            CompilationTarget = target_java,
-            create_java_shell_script(MainModuleName, Succeeded, !IO)
         ),
         !:Info = !.Info ^ command_line_targets :=
             set.delete(!.Info ^ command_line_targets,
diff --git a/compiler/module_cmds.m b/compiler/module_cmds.m
index 60d0c0e..be586c0 100644
--- a/compiler/module_cmds.m
+++ b/compiler/module_cmds.m
@@ -20,6 +20,7 @@
 :- import_module libs.file_util.

 :- import_module bool.
+:- import_module list.
 :- import_module io.
 :- import_module maybe.

@@ -138,10 +139,18 @@
 :- pred create_java_shell_script(module_name::in, bool::out,
     io::di, io::uo) is det.

-    % Strip away the path prefix for a list of .class files.
+    % Given a list .class files, return the string that should be passed
+    % to `jar' to reference those class files.
     %
-:- pred list_class_files_for_jar(module_name::in, string::in, string::out,
-    io::di, io::uo) is det.
+:- pred list_class_files_for_jar(module_name::in, list(string)::in,
+    string::out, io::di, io::uo) is det.
+
+    % Given a `mmake' variable reference to a list of .class files, return an
+    % expression that generates the list of arguments for `jar' to reference
+    % those class files.
+    %
+:- pred list_class_files_for_jar_mmake(module_name::in, string::in,
+    string::out, io::di, io::uo) is det.

     % Get the value of the Java class path from the environment. (Normally
     % it will be obtained from the CLASSPATH environment variable, but if
@@ -177,7 +186,6 @@
 :- import_module parse_tree.file_names.

 :- import_module dir.
-:- import_module list.
 :- import_module getopt_io.
 :- import_module string.

@@ -715,6 +723,30 @@ list_class_files_for_jar(ModuleName, ClassFiles,
ListClassFiles, !IO) :-
             ClassFile, !IO),
         ClassSubdir = dir.dirname(ClassFile),
         % Here we use the `-C' option of jar to change directory during
+        % execution and strip away the Mercury/classs/
+        % prefixes on class file names.
+        % Otherwise, the class files would be stored as
+        %   Mercury/classs/*.class
+        % within the jar file, which is not what we want.
+        UnprefixedClassFiles = list.map(
+            string.remove_prefix_if_present(ClassSubdir ++ "/"), ClassFiles),
+        Arguments = ["-C", ClassSubdir | UnprefixedClassFiles]
+    ;
+        AnySubdirs = no,
+        Arguments = ClassFiles
+    ),
+    ListClassFiles = string.join_list(" ", Arguments).
+
+list_class_files_for_jar_mmake(ModuleName, ClassFiles, ListClassFiles, !IO) :-
+    globals.io_lookup_bool_option(use_subdirs, UseSubdirs, !IO),
+    globals.io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs, !IO),
+    AnySubdirs = UseSubdirs `or` UseGradeSubdirs,
+    (
+        AnySubdirs = yes,
+        module_name_to_file_name(ModuleName, ".class", do_not_create_dirs,
+            ClassFile, !IO),
+        ClassSubdir = dir.dirname(ClassFile),
+        % Here we use the `-C' option of jar to change directory during
         % execution, then use sed to strip away the Mercury/classs/
         % prefix to the class files.
         % Otherwise, the class files would be stored as
diff --git a/compiler/write_deps_file.m b/compiler/write_deps_file.m
index 904a9f0..061fbd8 100644
--- a/compiler/write_deps_file.m
+++ b/compiler/write_deps_file.m
@@ -1917,7 +1917,8 @@ generate_dep_file(SourceFileName, ModuleName,
DepsMap, DepStream, !IO) :-
     ], !IO),

     ClassFiles = "$(" ++ MakeVarName ++ ".classes)",
-    list_class_files_for_jar(ModuleName, ClassFiles, ListClassFiles, !IO),
+    list_class_files_for_jar_mmake(ModuleName, ClassFiles, ListClassFiles,
+        !IO),
     io.write_strings(DepStream, [
         JarFileName, " : ", "$(", MakeVarName, ".classes)\n",
         "\t$(JAR) $(JAR_CREATE_FLAGS) ", JarFileName, " ",
diff --git a/library/string.m b/library/string.m
index 93d455a..0a96a1b 100644
--- a/library/string.m
+++ b/library/string.m
@@ -116,6 +116,11 @@
     %
 :- pred string.remove_prefix(string::in, string::in, string::out) is semidet.

+    % string.remove_prefix_if_present(Prefix, String) = Suffix returns `String'
+    % minus `Prefix' if `String' begins with `Prefix', `String' otherwise.
+    %
+:- func string.remove_prefix_if_present(string, string) = string.
+
     % string.prefix(String, Prefix) is true iff Prefix is a prefix of String.
     % Same as string.append(Prefix, _, String).
     %
@@ -1094,10 +1099,17 @@ string.remove_suffix_if_present(Suffix, String) = Out :-
     ;
         Out = String
     ).
-
+
 string.remove_prefix(Prefix, String, Suffix) :-
     string.append(Prefix, Suffix, String).

+string.remove_prefix_if_present(Prefix, String) = Out :-
+    ( string.remove_prefix(Prefix, String, Suffix) ->
+        Out = Suffix
+    ;
+        Out = String
+    ).
+
 :- pragma promise_equivalent_clauses(string.prefix/2).

 string.prefix(String::in, Prefix::in) :-
--------------------------------------------------------------------------
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