OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
3 # for details. All rights reserved. Use of this source code is governed by a | |
4 # BSD-style license that can be found in the LICENSE file. | |
5 | |
6 """Command line wrapper to run the frog compiler under the Dart VM""" | |
7 | |
8 # TODO(jimhug): This is a temporary hack to enable running on the VM. We need | |
9 # the ability to get command-line arguments, to return exit codes, and to | |
10 # communicate with spawned processes in the VM for this to go away. | |
11 | |
12 | |
13 import optparse | |
14 import os | |
15 import platform | |
16 import tempfile | |
17 import shutil | |
18 import subprocess | |
19 import sys | |
20 | |
21 | |
22 from os.path import dirname, join, realpath, exists, basename, relpath | |
23 | |
24 HOME = dirname(realpath(__file__)) | |
25 sys.path.append(join(HOME, os.pardir, 'tools')) | |
26 import utils | |
27 | |
28 HTML = '''<html> | |
29 <head><title>Frog</title><head> | |
30 <body> | |
31 <script type="application/javascript" src="out.js"></script> | |
32 </body> | |
33 </html> | |
34 ''' | |
35 | |
36 | |
37 # Returns the path to the Dart test runner (executes the .dart file). | |
38 def GetDartRunner(mode, arch, component): | |
39 build_root = utils.GetBuildRoot(utils.GuessOS(), mode, arch) | |
40 if component == 'frog': | |
41 return os.path.join(build_root, 'frog', 'bin', 'frog') | |
42 else: | |
43 suffix = '' | |
44 if utils.IsWindows(): | |
45 suffix = '.exe' | |
46 return os.path.join(build_root, 'dart') + suffix | |
47 | |
48 | |
49 def GetDart(): | |
50 # Get the release version. | |
51 return GetDartRunner('release', 'ia32', 'vm') | |
52 | |
53 def GetD8(): | |
54 return join(dirname(GetDart()), 'd8') | |
55 | |
56 D8 = GetD8() | |
57 | |
58 def execute(cmd): | |
59 """Execute a command in a subprocess. """ | |
60 try: | |
61 proc = subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr, | |
62 env=os.environ) | |
63 return proc.wait() | |
64 except Exception as e: | |
65 print 'Exception when executing: ' + ' '.join(cmd) | |
66 print e | |
67 return 1 | |
68 | |
69 def parseOptions(args): | |
70 optionParser = optparse.OptionParser() | |
71 | |
72 optionParser.add_option('--work', dest='workdir', | |
73 default=None, | |
74 metavar='DIR', help='Directory where temporary files are created.') | |
75 | |
76 # Meta-flag for VM running compiler, probably want more options here. | |
77 optionParser.add_option('--vm_flags', | |
78 # TODO(jimhug): Make it easier to enable and disable this for tests. | |
79 #default='--enable_type_checks --enable_asserts', | |
80 default='', | |
81 help='Flags to pass to the VM that is running frog itself.') | |
82 | |
83 optionParser.add_option('--vm', | |
84 default=GetDart(), | |
85 help='The location of the VM.') | |
86 | |
87 optionParser.add_option('--js_cmd', | |
88 default = '%s --crankshaft' % D8, | |
89 metavar='FILE', help='The shell cmd to use to run output JS code.') | |
90 | |
91 optionParser.add_option('--keep_files', | |
92 action='store_true', help='Do not remove temporary files.') | |
93 | |
94 # TODO(vsm): Hook in HtmlConverter. | |
95 optionParser.add_option('--html', | |
96 action='store_true', help='Invoke this in the browser instead of d8.') | |
97 optionParser.add_option('--browser', | |
98 default = None, | |
99 metavar='FILE', help='The browser to use to run output HTML.') | |
100 | |
101 optionParser.add_option('--verbose', | |
102 help='Verbose output', default=False, action='store_true') | |
103 | |
104 optionParser.set_usage("frog.py <dart-script-file> [<dart-options>]") | |
105 return optionParser.parse_args(args) | |
106 | |
107 | |
108 def main(args): | |
109 if '--' in args: | |
110 index = args.index('--') | |
111 pythonArgs = args[1:index] | |
112 dartArgs = args[index + 1:] | |
113 else: | |
114 pythonArgs = [] | |
115 dartArgs = args[1:] | |
116 | |
117 options, extraArgs = parseOptions(pythonArgs) | |
118 if options.verbose: | |
119 print ("dartArgs=%s pythonArgs=%s extraArgs=%s" % | |
120 (' '.join(dartArgs), ' '.join(pythonArgs), ' '.join(extraArgs))) | |
121 | |
122 if len(extraArgs) != 0: | |
123 optionParser.print_help() | |
124 return 1 | |
125 | |
126 dart = options.vm | |
127 if not exists(dart): | |
128 print "Dart VM not built. Please run the following command:" | |
129 build_file = relpath(join(HOME, os.pardir, 'tools', 'build.py')) | |
130 print ' ' + build_file + ' -m release' | |
131 return 1 | |
132 | |
133 return compileAndRun(options, dartArgs, dart) | |
134 | |
135 | |
136 def ensureJsEngine(options): | |
137 if not exists(D8): | |
138 print "No engine available for running JS code." | |
139 print "See frog/README.txt for instructions." | |
140 return 1 | |
141 return 0 | |
142 | |
143 def compileAndRun(options, args, dart): | |
144 jsArgs = [] | |
145 for i in range(len(args)): | |
146 if args[i].endswith('.dart'): | |
147 jsArgs = args[i+1:] | |
148 args = args[:i+1] | |
149 break | |
150 | |
151 outfile_given = False | |
152 execute_output = True | |
153 for i in range(len(args)): | |
154 if args[i].startswith('--out'): | |
155 outfile_given = True | |
156 outfile = args[i][6:] | |
157 execute_output = False | |
158 break; | |
159 if args[i] == '--compile-only': | |
160 execute_output = False | |
161 break; | |
162 | |
163 if options.verbose: print "jsArgs %s" % ' '.join(jsArgs); | |
164 | |
165 workdir = options.workdir | |
166 cleanup = False | |
167 if not workdir: | |
168 if not options.html: | |
169 workdir = tempfile.mkdtemp() | |
170 if not options.keep_files: | |
171 cleanup = True | |
172 else: | |
173 # A persistent location for the browser to load. | |
174 workdir = 'html' | |
175 if not os.path.exists(workdir): | |
176 os.mkdir(workdir) | |
177 | |
178 if not outfile_given: | |
179 outfile = join(workdir, 'out.js') | |
180 args = ['--out=%s' % outfile] + args | |
181 | |
182 outhtml = join(workdir, 'out.html') | |
183 | |
184 browser = options.browser | |
185 if not browser: | |
186 if platform.system() == 'Darwin': | |
187 # Use the default browser on the Mac | |
188 browser = 'Open' | |
189 else: | |
190 # TODO(vsm): This is only available on Goobuntu. | |
191 browser = 'google-chrome' | |
192 | |
193 args = ['--libdir=%s/lib' % HOME] + args | |
194 | |
195 compiler_cmd = [dart] | |
196 if options.vm_flags: | |
197 compiler_cmd.extend(options.vm_flags.split(' ')) | |
198 compiler_cmd.append(join(HOME, 'frogc.dart')) | |
199 compiler_cmd.extend(args) | |
200 exit_code = execute(compiler_cmd) | |
201 if exit_code: | |
202 if options.verbose: print ("cmd exited with status %d" % exit_code) | |
203 if cleanup: shutil.rmtree(workdir) | |
204 if exit_code < 0: | |
205 print("VM exited with signal %d" % (-exit_code)) | |
206 # TODO(ahe): Using 253 to signal a crash to test.dart. | |
207 return 253 | |
208 return exit_code | |
209 | |
210 result = 0 | |
211 if execute_output: | |
212 if not options.html: | |
213 if ensureJsEngine(options) != 0: | |
214 return 1 | |
215 js_cmd = options.js_cmd | |
216 result = execute(js_cmd.split(' ') + [outfile] + jsArgs) | |
217 else: | |
218 f = open(outhtml, 'w') | |
219 f.write(HTML) | |
220 f.close() | |
221 result = execute([browser, outhtml]) | |
222 elif outfile_given: | |
223 print 'Compilation succeded. Code generated in: %s' % outfile | |
224 else: | |
225 print 'Compilation succeded.' | |
226 | |
227 if cleanup: shutil.rmtree(workdir) | |
228 if result != 0: | |
229 return 1 | |
230 return 0 | |
231 | |
232 if __name__ == '__main__': | |
233 sys.exit(main(sys.argv)) | |
OLD | NEW |