blob: 63a0ef91d0a61884abd3971ef77fbd9d5d3abc6b [file] [log] [blame]
Michael Thvedt828a4be2015-08-12 17:45:36 +00001#!/usr/bin/python2.7
2
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00003# Copyright 2015 The Bazel Authors. All rights reserved.
Michael Thvedt828a4be2015-08-12 17:45:36 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http:#www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""A wrapper script for J2ObjC transpiler.
18
19This script wraps around J2ObjC transpiler to also output a dependency mapping
20file by scanning the import and include directives of the J2ObjC-translated
21files.
22"""
23
24import argparse
Rumou Duana1a13ae2016-07-26 17:23:26 +000025import errno
Michael Thvedt828a4be2015-08-12 17:45:36 +000026import multiprocessing
27import os
28import Queue
29import re
Rumou Duana1a13ae2016-07-26 17:23:26 +000030import shutil
Michael Thvedt828a4be2015-08-12 17:45:36 +000031import subprocess
Rumou Duan18742ad2015-09-02 23:45:03 +000032import tempfile
Michael Thvedt828a4be2015-08-12 17:45:36 +000033import threading
Rumou Duana1a13ae2016-07-26 17:23:26 +000034import zipfile
Michael Thvedt828a4be2015-08-12 17:45:36 +000035
Rumou Duana1a13ae2016-07-26 17:23:26 +000036_INCLUDE_RE = re.compile('#(include|import) "([^"]+)"')
37_CONST_DATE_TIME = [1980, 1, 1, 0, 0, 0]
cushon7a080c72021-06-10 18:31:36 -070038_ADD_EXPORTS = [
39 '--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',
40 '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
41 '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED',
42 '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
43 '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',
44]
Michael Thvedt828a4be2015-08-12 17:45:36 +000045
46
Rumou Duana1a13ae2016-07-26 17:23:26 +000047def RunJ2ObjC(java, jvm_flags, j2objc, main_class, output_file_path,
48 j2objc_args, source_paths, files_to_translate):
Michael Thvedt828a4be2015-08-12 17:45:36 +000049 """Runs J2ObjC transpiler to translate Java source files to ObjC.
50
51 Args:
52 java: The path of the Java executable.
53 jvm_flags: A comma-separated list of flags to pass to JVM.
54 j2objc: The deploy jar of J2ObjC.
55 main_class: The J2ObjC main class to invoke.
Rumou Duana1a13ae2016-07-26 17:23:26 +000056 output_file_path: The output file directory.
Rumou Duan18742ad2015-09-02 23:45:03 +000057 j2objc_args: A list of args to pass to J2ObjC transpiler.
Rumou Duana1a13ae2016-07-26 17:23:26 +000058 source_paths: A list of directories that contain sources to translate.
59 files_to_translate: A list of relative paths (relative to source_paths) that
60 point to sources to translate.
Michael Thvedt828a4be2015-08-12 17:45:36 +000061 Returns:
62 None.
63 """
Googlerf7bc9e52017-06-16 17:06:10 +020064 j2objc_args.extend(['-sourcepath', ':'.join(source_paths)])
65 j2objc_args.extend(['-d', output_file_path])
66 j2objc_args.extend(files_to_translate)
67 param_file_content = ' '.join(j2objc_args)
Rumou Duan18742ad2015-09-02 23:45:03 +000068 fd = None
69 param_filename = None
70 try:
71 fd, param_filename = tempfile.mkstemp(text=True)
Googlerf7bc9e52017-06-16 17:06:10 +020072 os.write(fd, param_file_content)
Rumou Duan18742ad2015-09-02 23:45:03 +000073 finally:
74 if fd:
75 os.close(fd)
76 try:
77 j2objc_cmd = [java]
78 j2objc_cmd.extend(filter(None, jvm_flags.split(',')))
cushon7a080c72021-06-10 18:31:36 -070079 j2objc_cmd.extend(_ADD_EXPORTS)
Rumou Duan18742ad2015-09-02 23:45:03 +000080 j2objc_cmd.extend(['-cp', j2objc, main_class])
cushon7a080c72021-06-10 18:31:36 -070081 j2objc_cmd.append('@%s' % param_filename)
Rumou Duan18742ad2015-09-02 23:45:03 +000082 subprocess.check_call(j2objc_cmd, stderr=subprocess.STDOUT)
83 finally:
84 if param_filename:
85 os.remove(param_filename)
Michael Thvedt828a4be2015-08-12 17:45:36 +000086
87
Rumou Duana1a13ae2016-07-26 17:23:26 +000088def WriteDepMappingFile(objc_files,
89 objc_file_root,
Michael Thvedt828a4be2015-08-12 17:45:36 +000090 output_dependency_mapping_file,
91 file_open=open):
92 """Scans J2ObjC-translated files and outputs a dependency mapping file.
93
94 The mapping file contains mappings between translated source files and their
95 imported source files scanned from the import and include directives.
96
97 Args:
Rumou Duana1a13ae2016-07-26 17:23:26 +000098 objc_files: A list of ObjC files translated by J2ObjC.
99 objc_file_root: The file path which represents a directory where the
Michael Thvedt828a4be2015-08-12 17:45:36 +0000100 generated ObjC files reside.
101 output_dependency_mapping_file: The path of the dependency mapping file to
102 write to.
103 file_open: Reference to the builtin open function so it may be
104 overridden for testing.
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000105 Raises:
106 RuntimeError: If spawned threads throw errors during processing.
Michael Thvedt828a4be2015-08-12 17:45:36 +0000107 Returns:
108 None.
109 """
110 dep_mapping = dict()
111 input_file_queue = Queue.Queue()
112 output_dep_mapping_queue = Queue.Queue()
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000113 error_message_queue = Queue.Queue()
Rumou Duana1a13ae2016-07-26 17:23:26 +0000114 for objc_file in objc_files:
115 input_file_queue.put(os.path.join(objc_file_root, objc_file))
Michael Thvedt828a4be2015-08-12 17:45:36 +0000116
117 for _ in xrange(multiprocessing.cpu_count()):
118 t = threading.Thread(target=_ReadDepMapping, args=(input_file_queue,
119 output_dep_mapping_queue,
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000120 error_message_queue,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000121 objc_file_root,
Michael Thvedt828a4be2015-08-12 17:45:36 +0000122 file_open))
123 t.start()
124
125 input_file_queue.join()
126
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000127 if not error_message_queue.empty():
128 error_messages = [error_message for error_message in
129 error_message_queue.queue]
130 raise RuntimeError('\n'.join(error_messages))
131
Michael Thvedt828a4be2015-08-12 17:45:36 +0000132 while not output_dep_mapping_queue.empty():
133 entry_file, deps = output_dep_mapping_queue.get()
134 dep_mapping[entry_file] = deps
135
laszlocsomorf11c6bc2018-07-05 01:58:06 -0700136 with file_open(output_dependency_mapping_file, 'w') as f:
137 for entry in sorted(dep_mapping):
138 for dep in dep_mapping[entry]:
139 f.write(entry + ':' + dep + '\n')
Michael Thvedt828a4be2015-08-12 17:45:36 +0000140
141
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000142def _ReadDepMapping(input_file_queue, output_dep_mapping_queue,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000143 error_message_queue, output_root, file_open=open):
Michael Thvedt828a4be2015-08-12 17:45:36 +0000144 while True:
145 try:
146 input_file = input_file_queue.get_nowait()
147 except Queue.Empty:
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000148 # No more work left in the queue.
Michael Thvedt828a4be2015-08-12 17:45:36 +0000149 return
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000150
151 try:
Googlerfc031e22017-04-03 20:31:42 +0000152 deps = set()
153 input_file_name = os.path.splitext(input_file)[0]
154 entry = os.path.relpath(input_file_name, output_root)
155 for file_ext in ['.m', '.h']:
156 with file_open(input_file_name + file_ext, 'r') as f:
157 for line in f:
158 include = _INCLUDE_RE.match(line)
159 if include:
160 include_path = include.group(2)
161 dep = os.path.splitext(include_path)[0]
162 if dep != entry:
163 deps.add(dep)
164
165 output_dep_mapping_queue.put((entry, sorted(deps)))
Rumou Duan49cdb4b2015-12-04 18:03:44 +0000166 except Exception as e: # pylint: disable=broad-except
167 error_message_queue.put(str(e))
168 finally:
169 # We need to mark the task done to prevent blocking the main process
170 # indefinitely.
171 input_file_queue.task_done()
Michael Thvedt828a4be2015-08-12 17:45:36 +0000172
Rumou Duan18742ad2015-09-02 23:45:03 +0000173
Rumou Duan123e1c32016-02-01 16:16:15 +0000174def WriteArchiveSourceMappingFile(compiled_archive_file_path,
175 output_archive_source_mapping_file,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000176 objc_files,
Rumou Duan123e1c32016-02-01 16:16:15 +0000177 file_open=open):
178 """Writes a mapping file between archive file to associated ObjC source files.
179
180 Args:
181 compiled_archive_file_path: The path of the archive file.
182 output_archive_source_mapping_file: A path of the mapping file to write to.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000183 objc_files: A list of ObjC files translated by J2ObjC.
Rumou Duan123e1c32016-02-01 16:16:15 +0000184 file_open: Reference to the builtin open function so it may be
185 overridden for testing.
186 Returns:
187 None.
188 """
189 with file_open(output_archive_source_mapping_file, 'w') as f:
Rumou Duana1a13ae2016-07-26 17:23:26 +0000190 for objc_file in objc_files:
191 f.write(compiled_archive_file_path + ':' + objc_file + '\n')
192
193
Rumou Duan18742ad2015-09-02 23:45:03 +0000194def _ParseArgs(j2objc_args):
195 """Separate arguments passed to J2ObjC into source files and J2ObjC flags.
196
197 Args:
198 j2objc_args: A list of args to pass to J2ObjC transpiler.
199 Returns:
200 A tuple containing source files and J2ObjC flags
201 """
202 source_files = []
203 flags = []
204 is_next_flag_value = False
205 for j2objc_arg in j2objc_args:
206 if j2objc_arg.startswith('-'):
207 flags.append(j2objc_arg)
208 is_next_flag_value = True
209 elif is_next_flag_value:
210 flags.append(j2objc_arg)
211 is_next_flag_value = False
212 else:
213 source_files.append(j2objc_arg)
214 return (source_files, flags)
215
216
Rumou Duana1a13ae2016-07-26 17:23:26 +0000217def _J2ObjcOutputObjcFiles(java_files):
218 """Returns the relative paths of the associated output ObjC source files.
219
220 Args:
221 java_files: The list of Java files to translate.
222 Returns:
223 A list of associated output ObjC source files.
224 """
225 return [os.path.splitext(java_file)[0] + '.m' for java_file in java_files]
226
227
Rumou Duane7fd5392017-01-09 20:33:33 +0000228def UnzipSourceJarSources(source_jars):
229 """Unzips the source jars containing Java source files.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000230
231 Args:
Rumou Duane7fd5392017-01-09 20:33:33 +0000232 source_jars: The list of input Java source jars.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000233 Returns:
234 A tuple of the temporary output root and a list of root-relative paths of
235 unzipped Java files
236 """
Rumou Duane7fd5392017-01-09 20:33:33 +0000237 srcjar_java_files = []
238 if source_jars:
Rumou Duana1a13ae2016-07-26 17:23:26 +0000239 tmp_input_root = tempfile.mkdtemp()
Rumou Duane7fd5392017-01-09 20:33:33 +0000240 for source_jar in source_jars:
241 zip_ref = zipfile.ZipFile(source_jar, 'r')
242 zip_entries = []
Rumou Duana1a13ae2016-07-26 17:23:26 +0000243
Rumou Duane7fd5392017-01-09 20:33:33 +0000244 for file_entry in zip_ref.namelist():
245 # We only care about Java source files.
246 if file_entry.endswith('.java'):
247 zip_entries.append(file_entry)
Rumou Duana1a13ae2016-07-26 17:23:26 +0000248
Rumou Duane7fd5392017-01-09 20:33:33 +0000249 zip_ref.extractall(tmp_input_root, zip_entries)
250 zip_ref.close()
251 srcjar_java_files.extend(zip_entries)
252
253 return (tmp_input_root, srcjar_java_files)
Rumou Duana1a13ae2016-07-26 17:23:26 +0000254 else:
255 return None
256
257
258def RenameGenJarObjcFileRootInFileContent(tmp_objc_file_root,
259 j2objc_source_paths,
260 gen_src_jar, genjar_objc_files,
261 execute=subprocess.check_call):
262 """Renames references to temporary root inside ObjC sources from gen srcjar.
263
264 Args:
265 tmp_objc_file_root: The temporary output root containing ObjC sources.
266 j2objc_source_paths: The source paths used by J2ObjC.
267 gen_src_jar: The path of the gen srcjar.
268 genjar_objc_files: The list of ObjC sources translated from the gen srcjar.
269 execute: The function used to execute shell commands.
270 Returns:
271 None.
272 """
273 if genjar_objc_files:
274 abs_genjar_objc_source_files = [
275 os.path.join(tmp_objc_file_root, genjar_objc_file)
276 for genjar_objc_file in genjar_objc_files
277 ]
278 abs_genjar_objc_header_files = [
279 os.path.join(tmp_objc_file_root,
280 os.path.splitext(genjar_objc_file)[0] + '.h')
281 for genjar_objc_file in genjar_objc_files
282 ]
283
284 # We execute a command to change all references of the temporary Java root
285 # where we unzipped the gen srcjar sources, to the actual gen srcjar that
286 # contains the original Java sources.
287 cmd = [
288 'sed',
289 '-i',
290 '-e',
291 's|%s/|%s::|g' % (j2objc_source_paths[1], gen_src_jar)
292 ]
293 cmd.extend(abs_genjar_objc_source_files)
294 cmd.extend(abs_genjar_objc_header_files)
295 execute(cmd, stderr=subprocess.STDOUT)
296
297
Rumou Duand7cdc552016-11-03 19:42:48 +0000298def MoveObjcFileToFinalOutputRoot(objc_files,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000299 tmp_objc_file_root,
300 final_objc_file_root,
301 suffix,
302 os_module=os,
303 shutil_module=shutil):
Rumou Duand7cdc552016-11-03 19:42:48 +0000304 """Moves ObjC files from temporary location to the final output location.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000305
306 Args:
Rumou Duand7cdc552016-11-03 19:42:48 +0000307 objc_files: The list of objc files to move.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000308 tmp_objc_file_root: The temporary output root containing ObjC sources.
309 final_objc_file_root: The final output root.
Rumou Duand7cdc552016-11-03 19:42:48 +0000310 suffix: The suffix of the files to move.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000311 os_module: The os python module.
312 shutil_module: The shutil python module.
313 Returns:
314 None.
315 """
316 for objc_file in objc_files:
317 file_with_suffix = os_module.path.splitext(objc_file)[0] + suffix
318 dest_path = os_module.path.join(
319 final_objc_file_root, file_with_suffix)
320 dest_path_dir = os_module.path.dirname(dest_path)
321
322 if not os_module.path.isdir(dest_path_dir):
323 try:
324 os_module.makedirs(dest_path_dir)
325 except OSError as e:
326 if e.errno != errno.EEXIST or not os_module.path.isdir(dest_path_dir):
327 raise
328
Rumou Duand7cdc552016-11-03 19:42:48 +0000329 shutil_module.move(
Rumou Duana1a13ae2016-07-26 17:23:26 +0000330 os_module.path.join(tmp_objc_file_root, file_with_suffix),
331 dest_path)
332
333
334def PostJ2ObjcFileProcessing(normal_objc_files, genjar_objc_files,
335 tmp_objc_file_root, final_objc_file_root,
336 j2objc_source_paths, gen_src_jar,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000337 output_gen_source_dir, output_gen_header_dir):
338 """Performs cleanups on ObjC files and moves them to final output location.
339
340 Args:
341 normal_objc_files: The list of objc files translated from normal Java files.
342 genjar_objc_files: The list of ObjC sources translated from the gen srcjar.
343 tmp_objc_file_root: The temporary output root containing ObjC sources.
344 final_objc_file_root: The final output root.
345 j2objc_source_paths: The source paths used by J2ObjC.
346 gen_src_jar: The path of the gen srcjar.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000347 output_gen_source_dir: The final output directory of ObjC source files
348 translated from gen srcjar. Maybe null.
349 output_gen_header_dir: The final output directory of ObjC header files
350 translated from gen srcjar. Maybe null.
351 Returns:
352 None.
353 """
354 RenameGenJarObjcFileRootInFileContent(tmp_objc_file_root,
355 j2objc_source_paths,
356 gen_src_jar,
357 genjar_objc_files)
Rumou Duand7cdc552016-11-03 19:42:48 +0000358 MoveObjcFileToFinalOutputRoot(normal_objc_files,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000359 tmp_objc_file_root,
360 final_objc_file_root,
361 '.m')
Rumou Duand7cdc552016-11-03 19:42:48 +0000362 MoveObjcFileToFinalOutputRoot(normal_objc_files,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000363 tmp_objc_file_root,
364 final_objc_file_root,
365 '.h')
366
Rumou Duana1a13ae2016-07-26 17:23:26 +0000367 if output_gen_source_dir:
Rumou Duand7cdc552016-11-03 19:42:48 +0000368 MoveObjcFileToFinalOutputRoot(
Rumou Duana1a13ae2016-07-26 17:23:26 +0000369 genjar_objc_files,
370 tmp_objc_file_root,
371 output_gen_source_dir,
372 '.m')
373
374 if output_gen_header_dir:
Rumou Duand7cdc552016-11-03 19:42:48 +0000375 MoveObjcFileToFinalOutputRoot(
Rumou Duana1a13ae2016-07-26 17:23:26 +0000376 genjar_objc_files,
377 tmp_objc_file_root,
378 output_gen_header_dir,
379 '.h')
380
381
382def GenerateJ2objcMappingFiles(normal_objc_files,
383 genjar_objc_files,
384 tmp_objc_file_root,
385 output_dependency_mapping_file,
386 output_archive_source_mapping_file,
387 compiled_archive_file_path):
388 """Generates J2ObjC mapping files.
389
390 Args:
391 normal_objc_files: The list of objc files translated from normal Java files.
392 genjar_objc_files: The list of ObjC sources translated from the gen srcjar.
393 tmp_objc_file_root: The temporary output root containing ObjC sources.
394 output_dependency_mapping_file: The path of the dependency mapping file to
395 write to.
396 output_archive_source_mapping_file: A path of the mapping file to write to.
397 compiled_archive_file_path: The path of the archive file.
398 Returns:
399 None.
400 """
401 WriteDepMappingFile(normal_objc_files + genjar_objc_files,
402 tmp_objc_file_root,
403 output_dependency_mapping_file)
404
405 if output_archive_source_mapping_file:
406 WriteArchiveSourceMappingFile(compiled_archive_file_path,
407 output_archive_source_mapping_file,
408 normal_objc_files + genjar_objc_files)
409
410
411def main():
Rumou Duanab16dd62015-08-18 21:52:08 +0000412 parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
Michael Thvedt828a4be2015-08-12 17:45:36 +0000413 parser.add_argument(
414 '--java',
415 required=True,
416 help='The path to the Java executable.')
417 parser.add_argument(
418 '--jvm_flags',
Googlercc28a1c2017-08-23 18:37:08 +0200419 default='-Xss4m,-XX:+UseParallelGC',
Michael Thvedt828a4be2015-08-12 17:45:36 +0000420 help='A comma-separated list of flags to pass to the JVM.')
421 parser.add_argument(
422 '--j2objc',
423 required=True,
424 help='The path to the J2ObjC deploy jar.')
425 parser.add_argument(
426 '--main_class',
427 required=True,
428 help='The main class of the J2ObjC deploy jar to execute.')
Rumou Duana1a13ae2016-07-26 17:23:26 +0000429 # TODO(rduan): Remove, no longer needed.
Michael Thvedt828a4be2015-08-12 17:45:36 +0000430 parser.add_argument(
431 '--translated_source_files',
Rumou Duand7cdc552016-11-03 19:42:48 +0000432 required=False,
Michael Thvedt828a4be2015-08-12 17:45:36 +0000433 help=('A comma-separated list of file paths where J2ObjC will write the '
434 'translated files to.'))
435 parser.add_argument(
436 '--output_dependency_mapping_file',
437 required=True,
438 help='The file path of the dependency mapping file to write to.')
439 parser.add_argument(
Rumou Duana1a13ae2016-07-26 17:23:26 +0000440 '--objc_file_path', '-d',
Michael Thvedt828a4be2015-08-12 17:45:36 +0000441 required=True,
442 help=('The file path which represents a directory where the generated '
443 'ObjC files reside.'))
Rumou Duan123e1c32016-02-01 16:16:15 +0000444 parser.add_argument(
445 '--output_archive_source_mapping_file',
446 help='The file path of the mapping file containing mappings between the '
447 'translated source files and the to-be-generated archive file '
448 'compiled from those source files. --compile_archive_file_path must '
449 'be specified if this option is specified.')
450 parser.add_argument(
451 '--compiled_archive_file_path',
452 required=False,
453 help=('The archive file path that will be produced by ObjC compile action'
454 ' later'))
Rumou Duane7fd5392017-01-09 20:33:33 +0000455 # TODO(rduan): Remove this flag once it is fully replaced by flag --src_jars.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000456 parser.add_argument(
457 '--gen_src_jar',
458 required=False,
459 help='The jar containing Java sources generated by annotation processor.')
460 parser.add_argument(
Rumou Duane7fd5392017-01-09 20:33:33 +0000461 '--src_jars',
462 required=False,
jingwen4a74c522018-11-20 11:57:15 -0800463 help='The list of Java source jars containing Java sources to translate.')
Rumou Duane7fd5392017-01-09 20:33:33 +0000464 parser.add_argument(
Rumou Duana1a13ae2016-07-26 17:23:26 +0000465 '--output_gen_source_dir',
466 required=False,
467 help='The output directory of ObjC source files translated from the gen'
468 ' srcjar')
469 parser.add_argument(
470 '--output_gen_header_dir',
471 required=False,
472 help='The output directory of ObjC header files translated from the gen'
473 ' srcjar')
Michael Thvedt828a4be2015-08-12 17:45:36 +0000474
Rumou Duana1a13ae2016-07-26 17:23:26 +0000475 args, pass_through_args = parser.parse_known_args()
476 normal_java_files, j2objc_flags = _ParseArgs(pass_through_args)
Rumou Duane7fd5392017-01-09 20:33:33 +0000477 srcjar_java_files = []
Rumou Duana1a13ae2016-07-26 17:23:26 +0000478 j2objc_source_paths = [os.getcwd()]
479
Rumou Duane7fd5392017-01-09 20:33:33 +0000480 # Unzip the source jars, so J2ObjC can translate the contained sources.
Rumou Duana1a13ae2016-07-26 17:23:26 +0000481 # Also add the temporary directory containing the unzipped sources as a source
482 # path for J2ObjC, so it can find these sources.
Rumou Duane7fd5392017-01-09 20:33:33 +0000483 source_jars = []
484 if args.gen_src_jar:
485 source_jars.append(args.gen_src_jar)
486 if args.src_jars:
487 source_jars.extend(args.src_jars.split(','))
488
489 srcjar_source_tuple = UnzipSourceJarSources(source_jars)
490 if srcjar_source_tuple:
491 j2objc_source_paths.append(srcjar_source_tuple[0])
492 srcjar_java_files = srcjar_source_tuple[1]
Rumou Duana1a13ae2016-07-26 17:23:26 +0000493
494 # Run J2ObjC over the normal input Java files and unzipped gen jar Java files.
495 # The output is stored in a temporary directory.
496 tmp_objc_file_root = tempfile.mkdtemp()
Rumou Duan6773c152017-03-24 17:12:25 +0000497
498 # If we do not generate the header mapping from J2ObjC, we still
499 # need to specify --output-header-mapping, as it signals to J2ObjC that we
500 # are using source paths as import paths, not package paths.
501 # TODO(rduan): Make another flag in J2ObjC to specify using source paths.
502 if '--output-header-mapping' not in j2objc_flags:
503 j2objc_flags.extend(['--output-header-mapping', '/dev/null'])
504
Michael Thvedt828a4be2015-08-12 17:45:36 +0000505 RunJ2ObjC(args.java,
506 args.jvm_flags,
507 args.j2objc,
508 args.main_class,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000509 tmp_objc_file_root,
510 j2objc_flags,
511 j2objc_source_paths,
Rumou Duane7fd5392017-01-09 20:33:33 +0000512 normal_java_files + srcjar_java_files)
Rumou Duan123e1c32016-02-01 16:16:15 +0000513
Rumou Duana1a13ae2016-07-26 17:23:26 +0000514 # Calculate the relative paths of generated objc files.
515 normal_objc_files = _J2ObjcOutputObjcFiles(normal_java_files)
Rumou Duane7fd5392017-01-09 20:33:33 +0000516 genjar_objc_files = _J2ObjcOutputObjcFiles(srcjar_java_files)
Rumou Duana1a13ae2016-07-26 17:23:26 +0000517
518 # Generate J2ObjC mapping files needed for distributed builds.
519 GenerateJ2objcMappingFiles(normal_objc_files,
520 genjar_objc_files,
521 tmp_objc_file_root,
522 args.output_dependency_mapping_file,
523 args.output_archive_source_mapping_file,
524 args.compiled_archive_file_path)
525
Rumou Duand7cdc552016-11-03 19:42:48 +0000526 # Post J2ObjC-run processing, involving file editing, zipping and moving
Rumou Duana1a13ae2016-07-26 17:23:26 +0000527 # files to their final output locations.
528 PostJ2ObjcFileProcessing(
529 normal_objc_files,
530 genjar_objc_files,
531 tmp_objc_file_root,
532 args.objc_file_path,
533 j2objc_source_paths,
534 args.gen_src_jar,
Rumou Duana1a13ae2016-07-26 17:23:26 +0000535 args.output_gen_source_dir,
536 args.output_gen_header_dir)
537
538if __name__ == '__main__':
539 main()