[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