1#!/usr/bin/env python
2#
3# Copyright 2014 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Creates a simple script to run a java "binary".
8
9This creates a script that sets up the java command line for running a java
10jar. This includes correctly setting the classpath and the main class.
11"""
12
13import optparse
14import os
15import sys
16
17from util import build_utils
18
19# The java command must be executed in the current directory because there may
20# be user-supplied paths in the args. The script receives the classpath relative
21# to the directory that the script is written in and then, when run, must
22# recalculate the paths relative to the current directory.
23script_template = """\
24#!/usr/bin/env python
25#
26# This file was generated by build/android/gyp/create_java_binary_script.py
27
28import argparse
29import os
30import sys
31
32self_dir = os.path.dirname(__file__)
33classpath = [{classpath}]
34extra_program_args = {extra_program_args}
35java_path = {java_path}
36if os.getcwd() != self_dir:
37  offset = os.path.relpath(self_dir, os.getcwd())
38  fix_path = lambda p: os.path.normpath(os.path.join(offset, p))
39  classpath = [fix_path(p) for p in classpath]
40  java_path = fix_path(java_path)
41java_cmd = [java_path]
42# This is a simple argparser for jvm, jar, and classpath arguments.
43parser = argparse.ArgumentParser()
44parser.add_argument('--jar-args')
45parser.add_argument('--jvm-args')
46parser.add_argument('--classpath')
47# Test_runner parses the classpath for sharding junit tests.
48parser.add_argument('--print-classpath', action='store_true',
49                    help='Prints the classpass. Used by test_runner.')
50known_args, unknown_args = parser.parse_known_args(sys.argv[1:])
51
52if known_args.print_classpath:
53  sys.stdout.write(':'.join(classpath))
54  sys.exit(0)
55
56if known_args.jvm_args:
57  jvm_arguments = known_args.jvm_args.strip('"').split()
58  java_cmd.extend(jvm_arguments)
59if known_args.jar_args:
60  jar_arguments = known_args.jar_args.strip('"').split()
61  if unknown_args:
62    raise Exception('There are unknown arguments')
63else:
64  jar_arguments = unknown_args
65
66if known_args.classpath:
67  classpath += [known_args.classpath]
68
69{noverify_flag}
70java_cmd.extend(
71    ['-classpath', ':'.join(classpath), '-enableassertions', \"{main_class}\"])
72java_cmd.extend(extra_program_args)
73java_cmd.extend(jar_arguments)
74os.execvp(java_cmd[0], java_cmd)
75"""
76
77def main(argv):
78  argv = build_utils.ExpandFileArgs(argv)
79  parser = optparse.OptionParser()
80  parser.add_option('--output', help='Output path for executable script.')
81  parser.add_option('--main-class',
82      help='Name of the java class with the "main" entry point.')
83  parser.add_option('--classpath', action='append', default=[],
84      help='Classpath for running the jar.')
85  parser.add_option('--noverify', action='store_true',
86      help='JVM flag: noverify.')
87
88  options, extra_program_args = parser.parse_args(argv)
89
90  if (options.noverify):
91    noverify_flag = 'java_cmd.append("-noverify")'
92  else:
93    noverify_flag = ''
94
95  classpath = []
96  for cp_arg in options.classpath:
97    classpath += build_utils.ParseGnList(cp_arg)
98
99  run_dir = os.path.dirname(options.output)
100  classpath = [os.path.relpath(p, run_dir) for p in classpath]
101  java_path = os.path.relpath(
102      os.path.join(build_utils.JAVA_HOME, 'bin', 'java'), run_dir)
103
104  with build_utils.AtomicOutput(options.output) as script:
105    script.write(
106        script_template.format(classpath=('"%s"' % '", "'.join(classpath)),
107                               java_path=repr(java_path),
108                               main_class=options.main_class,
109                               extra_program_args=repr(extra_program_args),
110                               noverify_flag=noverify_flag))
111
112  os.chmod(options.output, 0750)
113
114
115if __name__ == '__main__':
116  sys.exit(main(sys.argv[1:]))
117