~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to .pc/closure_path.diff/tools/shared.py

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-06-11 15:45:24 UTC
  • mfrom: (1.2.1) (2.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130611154524-rppb3w6tixlegv4n
Tags: 1.4.7~20130611~a1eb425-1
* New snapshot release
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
from tempfile import mkstemp
4
4
import jsrun, cache, tempfiles
5
5
from response_file import create_response_file
 
6
import logging, platform
6
7
 
7
8
def listify(x):
8
9
  if type(x) is not list: return [x]
46
47
      # Call the process with fixed streams.
47
48
      self.process = subprocess.Popen(args, bufsize, executable, self.stdin_, self.stdout_, self.stderr_, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags)
48
49
    except Exception, e:
49
 
      print >> sys.stderr, '\nsubprocess.Popen(args=%s) failed! Exception %s\n' % (' '.join(args), str(e))
 
50
      logging.error('\nsubprocess.Popen(args=%s) failed! Exception %s\n' % (' '.join(args), str(e)))
50
51
      raise e
51
52
 
52
53
  def communicate(self, input=None):
90
91
def path_from_root(*pathelems):
91
92
  return os.path.join(__rootpath__, *pathelems)
92
93
 
 
94
def add_coloring_to_emit_windows(fn):
 
95
  def _out_handle(self):
 
96
    import ctypes
 
97
    return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
 
98
  out_handle = property(_out_handle)
 
99
 
 
100
  def _set_color(self, code):
 
101
    import ctypes
 
102
    # Constants from the Windows API
 
103
    self.STD_OUTPUT_HANDLE = -11
 
104
    hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
 
105
    ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)
 
106
 
 
107
  setattr(logging.StreamHandler, '_set_color', _set_color)
 
108
 
 
109
  def new(*args):
 
110
    FOREGROUND_BLUE      = 0x0001 # text color contains blue.
 
111
    FOREGROUND_GREEN     = 0x0002 # text color contains green.
 
112
    FOREGROUND_RED       = 0x0004 # text color contains red.
 
113
    FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
 
114
    FOREGROUND_WHITE     = FOREGROUND_BLUE|FOREGROUND_GREEN |FOREGROUND_RED
 
115
    # winbase.h
 
116
    STD_INPUT_HANDLE = -10
 
117
    STD_OUTPUT_HANDLE = -11
 
118
    STD_ERROR_HANDLE = -12
 
119
 
 
120
    # wincon.h
 
121
    FOREGROUND_BLACK     = 0x0000
 
122
    FOREGROUND_BLUE      = 0x0001
 
123
    FOREGROUND_GREEN     = 0x0002
 
124
    FOREGROUND_CYAN      = 0x0003
 
125
    FOREGROUND_RED       = 0x0004
 
126
    FOREGROUND_MAGENTA   = 0x0005
 
127
    FOREGROUND_YELLOW    = 0x0006
 
128
    FOREGROUND_GREY      = 0x0007
 
129
    FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
 
130
 
 
131
    BACKGROUND_BLACK     = 0x0000
 
132
    BACKGROUND_BLUE      = 0x0010
 
133
    BACKGROUND_GREEN     = 0x0020
 
134
    BACKGROUND_CYAN      = 0x0030
 
135
    BACKGROUND_RED       = 0x0040
 
136
    BACKGROUND_MAGENTA   = 0x0050
 
137
    BACKGROUND_YELLOW    = 0x0060
 
138
    BACKGROUND_GREY      = 0x0070
 
139
    BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
 
140
    levelno = args[1].levelno
 
141
    if(levelno >= 50):
 
142
        color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY
 
143
    elif(levelno >= 40):
 
144
        color = FOREGROUND_RED | FOREGROUND_INTENSITY
 
145
    elif(levelno >= 30):
 
146
        color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
 
147
    elif(levelno >= 20):
 
148
        color = FOREGROUND_GREEN
 
149
    elif(levelno >= 10):
 
150
        color = FOREGROUND_MAGENTA
 
151
    else:
 
152
        color =  FOREGROUND_WHITE
 
153
    args[0]._set_color(color)
 
154
    ret = fn(*args)
 
155
    args[0]._set_color( FOREGROUND_WHITE )
 
156
    #print "after"
 
157
    return ret
 
158
  return new
 
159
 
 
160
def add_coloring_to_emit_ansi(fn):
 
161
  # add methods we need to the class
 
162
  def new(*args):
 
163
    levelno = args[1].levelno
 
164
    if(levelno >= 50):
 
165
      color = '\x1b[31m' # red
 
166
    elif(levelno >= 40):
 
167
      color = '\x1b[31m' # red
 
168
    elif(levelno >= 30):
 
169
      color = '\x1b[33m' # yellow
 
170
    elif(levelno >= 20):
 
171
      color = '\x1b[32m' # green
 
172
    elif(levelno >= 10):
 
173
      color = '\x1b[35m' # pink
 
174
    else:
 
175
      color = '\x1b[0m' # normal
 
176
    args[1].msg = color + args[1].msg +  '\x1b[0m'  # normal
 
177
    #print "after"
 
178
    return fn(*args)
 
179
  return new
 
180
 
 
181
WINDOWS = sys.platform.startswith('win')
 
182
 
 
183
if WINDOWS:
 
184
  logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
 
185
else:
 
186
  logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
 
187
 
93
188
# Emscripten configuration is done through the EM_CONFIG environment variable.
94
189
# If the string value contained in this environment variable contains newline
95
190
# separated definitions, then these definitions will be used to configure
122
217
    except:
123
218
      pass
124
219
    config_file = config_file.replace('{{{ NODE }}}', node)
125
 
    python = 'python'
 
220
    python = sys.executable or 'python'
126
221
    try:
127
222
      python = Popen(['which', 'python2'], stdout=PIPE).communicate()[0].replace('\n', '') or \
128
223
               Popen(['which', 'python'], stdout=PIPE).communicate()[0].replace('\n', '') or python
157
252
  config_text = open(CONFIG_FILE, 'r').read() if CONFIG_FILE else EM_CONFIG
158
253
  exec(config_text)
159
254
except Exception, e:
160
 
  print >> sys.stderr, 'Error in evaluating %s (at %s): %s, text: %s' % (EM_CONFIG, CONFIG_FILE, str(e), config_text)
 
255
  logging.error('Error in evaluating %s (at %s): %s, text: %s' % (EM_CONFIG, CONFIG_FILE, str(e), config_text))
161
256
  sys.exit(1)
162
257
 
163
258
# Expectations
169
264
  actual = Popen([CLANG, '-v'], stderr=PIPE).communicate()[1].split('\n')[0]
170
265
  if expected in actual:
171
266
    return True
172
 
  print >> sys.stderr, 'warning: LLVM version appears incorrect (seeing "%s", expected "%s")' % (actual, expected)
 
267
  logging.warning('LLVM version appears incorrect (seeing "%s", expected "%s")' % (actual, expected))
173
268
  return False
174
269
 
175
270
def check_llvm_version():
176
271
  try:
177
272
    check_clang_version();
178
273
  except Exception, e:
179
 
    print >> sys.stderr, 'warning: Could not verify LLVM version: %s' % str(e)
 
274
    logging.warning('Could not verify LLVM version: %s' % str(e))
180
275
 
181
276
EXPECTED_NODE_VERSION = (0,6,8)
182
277
 
187
282
    version = tuple(map(int, actual.replace('v', '').split('.')))
188
283
    if version >= EXPECTED_NODE_VERSION:
189
284
      return True
190
 
    print >> sys.stderr, 'warning: node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION))))
 
285
    logging.warning('node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION)))))
191
286
    return False
192
287
  except Exception, e:
193
 
    print >> sys.stderr, 'warning: cannot check node version:', e
 
288
    logging.warning('cannot check node version: %s',  e)
194
289
    return False
195
290
 
196
291
# Check that basic stuff we need (a JS engine to compile, Node.js, and Clang and LLVM)
200
295
# we re-check sanity when the settings are changed)
201
296
# We also re-check sanity and clear the cache when the version changes
202
297
 
203
 
EMSCRIPTEN_VERSION = '1.4.1'
 
298
EMSCRIPTEN_VERSION = '1.4.7'
204
299
 
205
300
def generate_sanity():
206
301
  return EMSCRIPTEN_VERSION + '|' + get_llvm_target()
227
322
        except Exception, e:
228
323
          reason = 'unknown: ' + str(e)
229
324
    if reason:
230
 
      print >> sys.stderr, '(Emscripten: %s, clearing cache)' % reason
 
325
      logging.warning('(Emscripten: %s, clearing cache)' % reason)
231
326
      Cache.erase()
232
327
 
233
328
    # some warning, not fatal checks - do them even if EM_IGNORE_SANITY is on
235
330
    check_node_version()
236
331
 
237
332
    if os.environ.get('EM_IGNORE_SANITY'):
238
 
      print >> sys.stderr, 'EM_IGNORE_SANITY set, ignoring sanity checks'
 
333
      logging.info('EM_IGNORE_SANITY set, ignoring sanity checks')
239
334
      return
240
335
 
241
 
    print >> sys.stderr, '(Emscripten: Running sanity checks)'
 
336
    logging.info('(Emscripten: Running sanity checks)')
242
337
 
243
338
    if not check_engine(COMPILER_ENGINE):
244
 
      print >> sys.stderr, 'FATAL: The JavaScript shell used for compiling (%s) does not seem to work, check the paths in %s' % (COMPILER_ENGINE, EM_CONFIG)
 
339
      logging.critical('The JavaScript shell used for compiling (%s) does not seem to work, check the paths in %s' % (COMPILER_ENGINE, EM_CONFIG))
245
340
      sys.exit(1)
246
341
 
247
342
    if NODE_JS != COMPILER_ENGINE:
248
343
      if not check_engine(NODE_JS):
249
 
        print >> sys.stderr, 'FATAL: Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG)
 
344
        logging.critical('Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG))
250
345
        sys.exit(1)
251
346
 
252
347
    for cmd in [CLANG, LLVM_LINK, LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM]:
253
348
      if not os.path.exists(cmd) and not os.path.exists(cmd + '.exe'): # .exe extension required for Windows
254
 
        print >> sys.stderr, 'FATAL: Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG)
 
349
        logging.critical('Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG))
255
350
        sys.exit(1)
256
351
 
257
352
    try:
258
353
      subprocess.call([JAVA, '-version'], stdout=PIPE, stderr=PIPE)
259
354
    except:
260
 
      print >> sys.stderr, 'WARNING: java does not seem to exist, required for closure compiler. -O2 and above will fail. You need to define JAVA in ~/.emscripten'
 
355
      logging.warning('java does not seem to exist, required for closure compiler. -O2 and above will fail. You need to define JAVA in ~/.emscripten')
261
356
 
262
357
    if not os.path.exists(CLOSURE_COMPILER):
263
 
      print >> sys.stderr, 'WARNING: Closure compiler (%s) does not exist, check the paths in %s. -O2 and above will fail' % (CLOSURE_COMPILER, EM_CONFIG)
 
358
     logging.warning('Closure compiler (%s) does not exist, check the paths in %s. -O2 and above will fail' % (CLOSURE_COMPILER, EM_CONFIG))
264
359
 
265
360
    # Sanity check passed!
266
361
 
335
430
    try:
336
431
      self.TEMP_DIR = TEMP_DIR
337
432
    except NameError:
338
 
      print >> sys.stderr, 'TEMP_DIR not defined in ~/.emscripten, using /tmp'
 
433
      logging.debug('TEMP_DIR not defined in ~/.emscripten, using /tmp')
339
434
      self.TEMP_DIR = '/tmp'
340
435
 
341
436
    self.CANONICAL_TEMP_DIR = os.path.join(self.TEMP_DIR, 'emscripten_temp')
346
441
        if not os.path.exists(self.EMSCRIPTEN_TEMP_DIR):
347
442
          os.makedirs(self.EMSCRIPTEN_TEMP_DIR)
348
443
      except Exception, e:
349
 
        print >> sys.stderr, e, 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten'
 
444
        logging.debug(e + 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten')
350
445
 
351
446
  def get_temp_files(self):
352
447
    return tempfiles.TempFiles(
353
448
      tmp=self.TEMP_DIR if not self.DEBUG else self.EMSCRIPTEN_TEMP_DIR,
354
449
      save_debug_files=os.environ.get('EMCC_DEBUG_SAVE'))
355
450
 
356
 
  def debug_log(self, msg):
357
 
    if self.DEBUG:
358
 
      print >> sys.stderr, msg
359
 
 
360
451
configuration = Configuration(environ=os.environ)
361
452
DEBUG = configuration.DEBUG
362
453
EMSCRIPTEN_TEMP_DIR = configuration.EMSCRIPTEN_TEMP_DIR
363
454
DEBUG_CACHE = configuration.DEBUG_CACHE
364
455
CANONICAL_TEMP_DIR = configuration.CANONICAL_TEMP_DIR
365
456
 
 
457
level = logging.DEBUG if os.environ.get('EMCC_DEBUG') else logging.INFO
 
458
logging.basicConfig(level=level, format='%(levelname)-8s %(name)s: %(message)s')
 
459
  
366
460
if not EMSCRIPTEN_TEMP_DIR:
367
461
  EMSCRIPTEN_TEMP_DIR = tempfile.mkdtemp(prefix='emscripten_temp_', dir=configuration.TEMP_DIR)
368
462
  def clean_temp():
388
482
try:
389
483
  PYTHON
390
484
except:
391
 
  if DEBUG: print >> sys.stderr, 'PYTHON not defined in ~/.emscripten, using "python"'
 
485
  logging.debug('PYTHON not defined in ~/.emscripten, using "python"')
392
486
  PYTHON = 'python'
393
487
 
394
488
try:
395
489
  JAVA
396
490
except:
397
 
  if DEBUG: print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"'
 
491
  logging.debug('JAVA not defined in ~/.emscripten, using "java"')
398
492
  JAVA = 'java'
399
493
 
400
494
# Additional compiler options
401
495
 
402
496
# Target choice. Must be synced with src/settings.js (TARGET_*)
403
497
def get_llvm_target():
404
 
  return os.environ.get('EMCC_LLVM_TARGET') or 'i386-pc-linux-gnu' # 'le32-unknown-nacl'
 
498
  return os.environ.get('EMCC_LLVM_TARGET') or 'le32-unknown-nacl' # 'i386-pc-linux-gnu'
405
499
LLVM_TARGET = get_llvm_target()
406
500
 
407
501
try:
412
506
COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-U__i386__', '-U__i386', '-Ui386',
413
507
                                 '-U__SSE__', '-U__SSE_MATH__', '-U__SSE2__', '-U__SSE2_MATH__', '-U__MMX__',
414
508
                                 '-DEMSCRIPTEN', '-D__EMSCRIPTEN__', '-U__STRICT_ANSI__',
415
 
                                 '-D__IEEE_LITTLE_ENDIAN', '-fno-math-errno',
 
509
                                 '-D__IEEE_LITTLE_ENDIAN', '-fno-math-errno', '-fno-threadsafe-statics',
416
510
                                 '-target', LLVM_TARGET]
417
511
 
 
512
if LLVM_TARGET == 'le32-unknown-nacl':
 
513
  COMPILER_OPTS += ['-U__native_client__', '-U__pnacl__', '-U__ELF__'] # The nacl target is originally used for Google Native Client. Emscripten is not NaCl, so remove the platform #define, when using their triple.
 
514
 
418
515
USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK')
419
516
 
420
517
if USE_EMSDK:
450
547
except NameError:
451
548
  pass
452
549
 
453
 
WINDOWS = sys.platform.startswith('win')
454
 
 
455
550
# If we have 'env', we should use that to find python, because |python| may fail while |env python| may work
456
551
# (For example, if system python is 3.x while we need 2.x, and env gives 2.x if told to do so.)
457
552
ENV_PREFIX = []
536
631
    return True
537
632
  return filter(check, values)
538
633
 
 
634
def expand_response(data):
 
635
  if type(data) == str and data[0] == '@':
 
636
    return json.loads(open(data[1:]).read())
 
637
  return data
 
638
 
539
639
# Settings. A global singleton. Not pretty, but nicer than passing |, settings| everywhere
540
640
 
541
641
class Settings:
581
681
          Settings.EMIT_GENERATED_FUNCTIONS = 1
582
682
        if opt_level >= 2:
583
683
          Settings.RELOOP = 1
 
684
          Settings.ALIASING_FUNCTION_POINTERS = 1
584
685
        if opt_level >= 3:
585
686
          # Aside from these, -O3 also runs closure compiler and llvm lto
 
687
          Settings.FORCE_ALIGNED_MEMORY = 1
586
688
          Settings.DOUBLE_MODE = 0
587
689
          Settings.PRECISE_I64_MATH = 0
588
 
          if noisy: print >> sys.stderr, 'Warning: Applying some potentially unsafe optimizations! (Use -O2 if this fails.)'
 
690
          if noisy: logging.warning('Applying some potentially unsafe optimizations! (Use -O2 if this fails.)')
589
691
 
590
692
    global Settings
591
693
    Settings = Settings2
625
727
    env['HOST_CXXFLAGS'] = "-W" #if set to nothing, CXXFLAGS is used, which we don't want
626
728
    env['PKG_CONFIG_LIBDIR'] = path_from_root('system', 'local', 'lib', 'pkgconfig') + os.path.pathsep + path_from_root('system', 'lib', 'pkgconfig')
627
729
    env['PKG_CONFIG_PATH'] = os.environ.get ('EM_PKG_CONFIG_PATH') or ''
 
730
    env['EMSCRIPTEN'] = '1'
628
731
    return env
629
732
 
630
733
  @staticmethod
671
774
      process = Popen(args, stdout=stdout, stderr=stderr, env=env)
672
775
      process.communicate()
673
776
    except Exception, e:
674
 
      print >> sys.stderr, 'Error: Exception thrown when invoking Popen in configure with args: "%s"!' % ' '.join(args)
 
777
      logging.error('Exception thrown when invoking Popen in configure with args: "%s"!' % ' '.join(args))
675
778
      raise
676
779
    del env['EMMAKEN_JUST_CONFIGURE']
677
780
    if process.returncode is not 0:
682
785
    if env is None:
683
786
      env = Building.get_building_env()
684
787
    if not args:
685
 
      print >> sys.stderr, 'Error: Executable to run not specified.'
 
788
      logging.error('Executable to run not specified.')
686
789
      sys.exit(1)
687
790
    #args += ['VERBOSE=1']
688
791
    try:
689
792
      process = Popen(args, stdout=stdout, stderr=stderr, env=env)
690
793
      process.communicate()
691
794
    except Exception, e:
692
 
      print >> sys.stderr, 'Error: Exception thrown when invoking Popen in make with args: "%s"!' % ' '.join(args)
 
795
      logging.error('Exception thrown when invoking Popen in make with args: "%s"!' % ' '.join(args))
693
796
      raise
694
797
    if process.returncode is not 0:
695
798
      raise subprocess.CalledProcessError(cmd=args, returncode=process.returncode)
796
899
          contents = filter(lambda x: len(x) > 0, Popen([LLVM_AR, 't', f], stdout=PIPE).communicate()[0].split('\n'))
797
900
          #print >> sys.stderr, '  considering archive', f, ':', contents
798
901
          if len(contents) == 0:
799
 
            print >> sys.stderr, 'Warning: Archive %s appears to be empty (recommendation: link an .so instead of .a)' % f
 
902
            logging.debug('Archive %s appears to be empty (recommendation: link an .so instead of .a)' % f)
800
903
          else:
801
904
            for content in contents: # ar will silently fail if the directory for the file does not exist, so make all the necessary directories
802
905
              dirname = os.path.dirname(content)
833
936
 
834
937
    # Finish link
835
938
    actual_files = unique_ordered(actual_files) # tolerate people trying to link a.so a.so etc.
836
 
    if DEBUG: print >>sys.stderr, 'emcc: llvm-linking:', actual_files
 
939
    logging.debug('emcc: llvm-linking: %s', actual_files)
837
940
 
838
941
    # check for too-long command line
839
942
    link_cmd = [LLVM_LINK] + actual_files + ['-o', target]
841
944
    # for max command line size before we use a respose file
842
945
    response_file = None
843
946
    if WINDOWS and len(' '.join(link_cmd)) > 8192:
844
 
      if DEBUG: print >>sys.stderr, 'using response file for llvm-link'
 
947
      logging.debug('using response file for llvm-link')
845
948
      [response_fd, response_file] = mkstemp(suffix='.response', dir=TEMP_DIR)
846
949
 
847
950
      link_cmd = [LLVM_LINK, "@" + response_file]
858
961
      link_cmd.append(target)
859
962
 
860
963
      if len(' '.join(link_cmd)) > 8192:
861
 
        print >>sys.stderr, 'emcc: warning: link command line is very long, even with response file -- use paths with no spaces'
 
964
        logging.warning('emcc: link command line is very long, even with response file -- use paths with no spaces')
862
965
 
863
966
    output = Popen(link_cmd, stdout=PIPE).communicate()[0]
864
967
 
887
990
    if type(opts) is int:
888
991
      opts = Building.pick_llvm_opts(opts)
889
992
    #opts += ['-debug-pass=Arguments']
890
 
    if DEBUG: print >> sys.stderr, 'emcc: LLVM opts:', opts
 
993
    logging.debug('emcc: LLVM opts: ' + str(opts))
891
994
    output = Popen([LLVM_OPT, filename] + opts + ['-o=' + filename + '.opt.bc'], stdout=PIPE).communicate()[0]
892
995
    assert os.path.exists(filename + '.opt.bc'), 'Failed to run llvm optimizations: ' + output
893
996
    shutil.move(filename + '.opt.bc', filename)
928
1031
  @staticmethod
929
1032
  def llvm_nm(filename, stdout=PIPE, stderr=None):
930
1033
    if filename in Building.nm_cache:
931
 
      #if DEBUG: print >> sys.stderr, 'loading nm results for %s from cache' % filename
 
1034
      #logging.debug('loading nm results for %s from cache' % filename)
932
1035
      return Building.nm_cache[filename]
933
1036
 
934
1037
    # LLVM binary ==> list of symbols
1000
1103
 
1001
1104
  @staticmethod
1002
1105
  def get_safe_internalize():
1003
 
    exports = ','.join(map(lambda exp: exp[1:], Settings.EXPORTED_FUNCTIONS))
 
1106
    exports = ','.join(map(lambda exp: exp[1:], expand_response(Settings.EXPORTED_FUNCTIONS)))
1004
1107
    # internalize carefully, llvm 3.2 will remove even main if not told not to
1005
1108
    return ['-internalize', '-internalize-public-api-list=' + exports]
1006
1109
 
1111
1214
    return js_optimizer.run(filename, passes, listify(NODE_JS), jcache)
1112
1215
 
1113
1216
  @staticmethod
1114
 
  def closure_compiler(filename):
 
1217
  def closure_compiler(filename, pretty=True):
1115
1218
    if not os.path.exists(CLOSURE_COMPILER):
1116
1219
      raise Exception('Closure compiler appears to be missing, looked at: ' + str(CLOSURE_COMPILER))
1117
1220
 
1121
1224
            '-Xmx' + (os.environ.get('JAVA_HEAP_SIZE') or '1024m'), # if you need a larger Java heap, use this environment variable
1122
1225
            '-jar', CLOSURE_COMPILER,
1123
1226
            '--compilation_level', 'ADVANCED_OPTIMIZATIONS',
1124
 
            '--formatting', 'PRETTY_PRINT',
1125
1227
            '--language_in', 'ECMASCRIPT5',
1126
1228
            #'--variable_map_output_file', filename + '.vars',
1127
1229
            '--js', filename, '--js_output_file', filename + '.cc.js']
 
1230
    if pretty: args += ['--formatting', 'PRETTY_PRINT']
1128
1231
    if os.environ.get('EMCC_CLOSURE_ARGS'):
1129
1232
      args += shlex.split(os.environ.get('EMCC_CLOSURE_ARGS'))
1130
1233
    process = Popen(args, stdout=PIPE, stderr=STDOUT)
1148
1251
      Building._is_ar_cache[filename] = sigcheck
1149
1252
      return sigcheck
1150
1253
    except Exception, e:
1151
 
      if DEBUG: print >> sys.stderr, 'shared.Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e)
 
1254
      logging.debug('Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e))
1152
1255
      return False
1153
1256
 
1154
1257
  @staticmethod
1175
1278
    curr = os.getcwd()
1176
1279
    try:
1177
1280
      ok = False
1178
 
      print >> sys.stderr, '======================================='
1179
 
      print >> sys.stderr, 'bootstrapping relooper...'
 
1281
      logging.info('=======================================')
 
1282
      logging.info('bootstrapping relooper...')
1180
1283
      os.chdir(path_from_root('src'))
1181
1284
 
1182
1285
      emcc_debug = os.environ.get('EMCC_DEBUG')
1201
1304
        f.close()
1202
1305
 
1203
1306
      # bootstrap phase 1: generate unrelooped relooper, for which we do not need a relooper (so we cannot recurse infinitely in this function)
1204
 
      print >> sys.stderr, '  bootstrap phase 1'
 
1307
      logging.info('  bootstrap phase 1')
1205
1308
      make(1)
1206
1309
      # bootstrap phase 2: generate relooped relooper, using the unrelooped relooper (we see relooper.js exists so we cannot recurse infinitely in this function)
1207
 
      print >> sys.stderr, '  bootstrap phase 2'
 
1310
      logging.info('  bootstrap phase 2')
1208
1311
      make(2)
1209
 
      print >> sys.stderr, 'bootstrapping relooper succeeded'
1210
 
      print >> sys.stderr, '======================================='
 
1312
      logging.info('bootstrapping relooper succeeded')
 
1313
      logging.info('=======================================')
1211
1314
      ok = True
1212
1315
    finally:
1213
1316
      os.chdir(curr)
1214
1317
      if emcc_debug: os.environ['EMCC_DEBUG'] = emcc_debug
1215
1318
      if not ok:
1216
 
        print >> sys.stderr, 'bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten'
 
1319
        logging.error('bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten')
1217
1320
        1/0
1218
1321
 
1219
1322
  @staticmethod
1274
1377
  except:
1275
1378
    if not isinstance(cmd, str):
1276
1379
      cmd = ' '.join(cmd)
1277
 
    print >> sys.stderr, 'Invoking Process failed: <<< ' + cmd + ' >>>'
 
1380
    logging.error('Invoking Process failed: <<< ' + cmd + ' >>>')
1278
1381
    raise
1279
1382
 
1280
1383
def suffix(name):