| 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 |