aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorÉloi Rivard <azmeuk@gmail.com>2013-04-27 13:06:42 +0200
committerÉloi Rivard <azmeuk@gmail.com>2013-05-03 10:13:04 +0200
commitce122916a38c1fdc8b82e3eb4804c979fe06a242 (patch)
treed1b2d58997bc157dc75f2b2b4da62dc7bf12abe3 /tools
parent34bce791b6b1c34e85c5deda7fb71869dcdd6435 (diff)
* Added some colors to messages displayed from python files.
Diffstat (limited to 'tools')
-rw-r--r--tools/shared.py174
1 files changed, 133 insertions, 41 deletions
diff --git a/tools/shared.py b/tools/shared.py
index e9284bf7..97d30f0c 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -3,6 +3,7 @@ from subprocess import Popen, PIPE, STDOUT
from tempfile import mkstemp
import jsrun, cache, tempfiles
from response_file import create_response_file
+import logging, platform
def listify(x):
if type(x) is not list: return [x]
@@ -90,6 +91,100 @@ __rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
def path_from_root(*pathelems):
return os.path.join(__rootpath__, *pathelems)
+def add_coloring_to_emit_windows(fn):
+ def _out_handle(self):
+ import ctypes
+ return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
+ out_handle = property(_out_handle)
+
+ def _set_color(self, code):
+ import ctypes
+ # Constants from the Windows API
+ self.STD_OUTPUT_HANDLE = -11
+ hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
+ ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)
+
+ setattr(logging.StreamHandler, '_set_color', _set_color)
+
+ def new(*args):
+ FOREGROUND_BLUE = 0x0001 # text color contains blue.
+ FOREGROUND_GREEN = 0x0002 # text color contains green.
+ FOREGROUND_RED = 0x0004 # text color contains red.
+ FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
+ FOREGROUND_WHITE = FOREGROUND_BLUE|FOREGROUND_GREEN |FOREGROUND_RED
+ # winbase.h
+ STD_INPUT_HANDLE = -10
+ STD_OUTPUT_HANDLE = -11
+ STD_ERROR_HANDLE = -12
+
+ # wincon.h
+ FOREGROUND_BLACK = 0x0000
+ FOREGROUND_BLUE = 0x0001
+ FOREGROUND_GREEN = 0x0002
+ FOREGROUND_CYAN = 0x0003
+ FOREGROUND_RED = 0x0004
+ FOREGROUND_MAGENTA = 0x0005
+ FOREGROUND_YELLOW = 0x0006
+ FOREGROUND_GREY = 0x0007
+ FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
+
+ BACKGROUND_BLACK = 0x0000
+ BACKGROUND_BLUE = 0x0010
+ BACKGROUND_GREEN = 0x0020
+ BACKGROUND_CYAN = 0x0030
+ BACKGROUND_RED = 0x0040
+ BACKGROUND_MAGENTA = 0x0050
+ BACKGROUND_YELLOW = 0x0060
+ BACKGROUND_GREY = 0x0070
+ BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
+ levelno = args[1].levelno
+ if(levelno>=50):
+ color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY
+ elif(levelno>=40):
+ color = FOREGROUND_RED | FOREGROUND_INTENSITY
+ elif(levelno>=30):
+ color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
+ elif(levelno>=20):
+ color = FOREGROUND_GREEN
+ elif(levelno>=10):
+ color = FOREGROUND_MAGENTA
+ else:
+ color = FOREGROUND_WHITE
+ args[0]._set_color(color)
+ ret = fn(*args)
+ args[0]._set_color( FOREGROUND_WHITE )
+ #print "after"
+ return ret
+ return new
+
+def add_coloring_to_emit_ansi(fn):
+ # add methods we need to the class
+ def new(*args):
+ levelno = args[1].levelno
+ if(levelno>=50):
+ color = '\x1b[31m' # red
+ elif(levelno>=40):
+ color = '\x1b[31m' # red
+ elif(levelno>=30):
+ color = '\x1b[33m' # yellow
+ elif(levelno>=20):
+ color = '\x1b[32m' # green
+ elif(levelno>=10):
+ color = '\x1b[35m' # pink
+ else:
+ color = '\x1b[0m' # normal
+ args[1].msg = color + args[1].msg + '\x1b[0m' # normal
+ #print "after"
+ return fn(*args)
+ return new
+
+WINDOWS = sys.platform.startswith('win')
+
+if WINDOWS:
+ logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
+else:
+ logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
+
# Emscripten configuration is done through the EM_CONFIG environment variable.
# If the string value contained in this environment variable contains newline
# separated definitions, then these definitions will be used to configure
@@ -157,7 +252,7 @@ try:
config_text = open(CONFIG_FILE, 'r').read() if CONFIG_FILE else EM_CONFIG
exec(config_text)
except Exception, e:
- print >> sys.stderr, 'Error in evaluating %s (at %s): %s, text: %s' % (EM_CONFIG, CONFIG_FILE, str(e), config_text)
+ logging.error('Error in evaluating %s (at %s): %s, text: %s' % (EM_CONFIG, CONFIG_FILE, str(e), config_text))
sys.exit(1)
# Expectations
@@ -169,14 +264,14 @@ def check_clang_version():
actual = Popen([CLANG, '-v'], stderr=PIPE).communicate()[1].split('\n')[0]
if expected in actual:
return True
- print >> sys.stderr, 'warning: LLVM version appears incorrect (seeing "%s", expected "%s")' % (actual, expected)
+ logging.warning('LLVM version appears incorrect (seeing "%s", expected "%s")' % (actual, expected))
return False
def check_llvm_version():
try:
check_clang_version();
except Exception, e:
- print >> sys.stderr, 'warning: Could not verify LLVM version: %s' % str(e)
+ logging.warning('Could not verify LLVM version: %s' % str(e))
EXPECTED_NODE_VERSION = (0,6,8)
@@ -187,10 +282,10 @@ def check_node_version():
version = tuple(map(int, actual.replace('v', '').split('.')))
if version >= EXPECTED_NODE_VERSION:
return True
- print >> sys.stderr, 'warning: node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION))))
+ logging.warning('node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION)))))
return False
except Exception, e:
- print >> sys.stderr, 'warning: cannot check node version:', e
+ logging.warning('cannot check node version:' + e)
return False
# Check that basic stuff we need (a JS engine to compile, Node.js, and Clang and LLVM)
@@ -227,7 +322,7 @@ def check_sanity(force=False):
except Exception, e:
reason = 'unknown: ' + str(e)
if reason:
- print >> sys.stderr, '(Emscripten: %s, clearing cache)' % reason
+ logging.info('(Emscripten: %s, clearing cache)' % reason)
Cache.erase()
# some warning, not fatal checks - do them even if EM_IGNORE_SANITY is on
@@ -235,32 +330,32 @@ def check_sanity(force=False):
check_node_version()
if os.environ.get('EM_IGNORE_SANITY'):
- print >> sys.stderr, 'EM_IGNORE_SANITY set, ignoring sanity checks'
+ logging.info('EM_IGNORE_SANITY set, ignoring sanity checks')
return
- print >> sys.stderr, '(Emscripten: Running sanity checks)'
+ logging.info('(Emscripten: Running sanity checks)')
if not check_engine(COMPILER_ENGINE):
- 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)
+ logging.critical('The JavaScript shell used for compiling (%s) does not seem to work, check the paths in %s' % (COMPILER_ENGINE, EM_CONFIG))
sys.exit(1)
if NODE_JS != COMPILER_ENGINE:
if not check_engine(NODE_JS):
- print >> sys.stderr, 'FATAL: Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG)
+ logging.critical('Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG))
sys.exit(1)
for cmd in [CLANG, LLVM_LINK, LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM]:
if not os.path.exists(cmd) and not os.path.exists(cmd + '.exe'): # .exe extension required for Windows
- print >> sys.stderr, 'FATAL: Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG)
+ logging.critical('Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG))
sys.exit(1)
try:
subprocess.call([JAVA, '-version'], stdout=PIPE, stderr=PIPE)
except:
- 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'
+ logging.warning('java does not seem to exist, required for closure compiler. -O2 and above will fail. You need to define JAVA in ~/.emscripten')
if not os.path.exists(CLOSURE_COMPILER):
- print >> sys.stderr, 'WARNING: Closure compiler (%s) does not exist, check the paths in %s. -O2 and above will fail' % (CLOSURE_COMPILER, EM_CONFIG)
+ logging.warning('Closure compiler (%s) does not exist, check the paths in %s. -O2 and above will fail' % (CLOSURE_COMPILER, EM_CONFIG))
# Sanity check passed!
@@ -335,7 +430,7 @@ class Configuration:
try:
self.TEMP_DIR = TEMP_DIR
except NameError:
- print >> sys.stderr, 'TEMP_DIR not defined in ~/.emscripten, using /tmp'
+ logging.info('TEMP_DIR not defined in ~/.emscripten, using /tmp')
self.TEMP_DIR = '/tmp'
self.CANONICAL_TEMP_DIR = os.path.join(self.TEMP_DIR, 'emscripten_temp')
@@ -346,23 +441,22 @@ class Configuration:
if not os.path.exists(self.EMSCRIPTEN_TEMP_DIR):
os.makedirs(self.EMSCRIPTEN_TEMP_DIR)
except Exception, e:
- print >> sys.stderr, e, 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten'
+ logging.debug(e + 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten')
def get_temp_files(self):
return tempfiles.TempFiles(
tmp=self.TEMP_DIR if not self.DEBUG else self.EMSCRIPTEN_TEMP_DIR,
save_debug_files=os.environ.get('EMCC_DEBUG_SAVE'))
- def debug_log(self, msg):
- if self.DEBUG:
- print >> sys.stderr, msg
-
configuration = Configuration(environ=os.environ)
DEBUG = configuration.DEBUG
EMSCRIPTEN_TEMP_DIR = configuration.EMSCRIPTEN_TEMP_DIR
DEBUG_CACHE = configuration.DEBUG_CACHE
CANONICAL_TEMP_DIR = configuration.CANONICAL_TEMP_DIR
+level = logging.DEBUG if os.environ.get('EMCC_DEBUG') else logging.INFO
+logging.basicConfig(level=level, format='%(levelname)-8s %(name)s: %(message)s')
+
if not EMSCRIPTEN_TEMP_DIR:
EMSCRIPTEN_TEMP_DIR = tempfile.mkdtemp(prefix='emscripten_temp_', dir=configuration.TEMP_DIR)
def clean_temp():
@@ -388,13 +482,13 @@ except:
try:
PYTHON
except:
- if DEBUG: print >> sys.stderr, 'PYTHON not defined in ~/.emscripten, using "python"'
+ logging.debug('PYTHON not defined in ~/.emscripten, using "python"')
PYTHON = 'python'
try:
JAVA
except:
- if DEBUG: print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"'
+ logging.debug('JAVA not defined in ~/.emscripten, using "java"')
JAVA = 'java'
# Additional compiler options
@@ -450,8 +544,6 @@ try:
except NameError:
pass
-WINDOWS = sys.platform.startswith('win')
-
# If we have 'env', we should use that to find python, because |python| may fail while |env python| may work
# (For example, if system python is 3.x while we need 2.x, and env gives 2.x if told to do so.)
ENV_PREFIX = []
@@ -585,7 +677,7 @@ class Settings:
# Aside from these, -O3 also runs closure compiler and llvm lto
Settings.DOUBLE_MODE = 0
Settings.PRECISE_I64_MATH = 0
- if noisy: print >> sys.stderr, 'Warning: Applying some potentially unsafe optimizations! (Use -O2 if this fails.)'
+ if noisy: logging.warning('Applying some potentially unsafe optimizations! (Use -O2 if this fails.)')
global Settings
Settings = Settings2
@@ -671,7 +763,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
process = Popen(args, stdout=stdout, stderr=stderr, env=env)
process.communicate()
except Exception, e:
- print >> sys.stderr, 'Error: Exception thrown when invoking Popen in configure with args: "%s"!' % ' '.join(args)
+ logging.error('Exception thrown when invoking Popen in configure with args: "%s"!' % ' '.join(args))
raise
del env['EMMAKEN_JUST_CONFIGURE']
if process.returncode is not 0:
@@ -682,14 +774,14 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
if env is None:
env = Building.get_building_env()
if not args:
- print >> sys.stderr, 'Error: Executable to run not specified.'
+ logging.error('Executable to run not specified.')
sys.exit(1)
#args += ['VERBOSE=1']
try:
process = Popen(args, stdout=stdout, stderr=stderr, env=env)
process.communicate()
except Exception, e:
- print >> sys.stderr, 'Error: Exception thrown when invoking Popen in make with args: "%s"!' % ' '.join(args)
+ logging.error('Exception thrown when invoking Popen in make with args: "%s"!' % ' '.join(args))
raise
if process.returncode is not 0:
raise subprocess.CalledProcessError(cmd=args, returncode=process.returncode)
@@ -796,7 +888,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
contents = filter(lambda x: len(x) > 0, Popen([LLVM_AR, 't', f], stdout=PIPE).communicate()[0].split('\n'))
#print >> sys.stderr, ' considering archive', f, ':', contents
if len(contents) == 0:
- print >> sys.stderr, 'Warning: Archive %s appears to be empty (recommendation: link an .so instead of .a)' % f
+ logging.debug('Archive %s appears to be empty (recommendation: link an .so instead of .a)' % f)
else:
for content in contents: # ar will silently fail if the directory for the file does not exist, so make all the necessary directories
dirname = os.path.dirname(content)
@@ -833,7 +925,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Finish link
actual_files = unique_ordered(actual_files) # tolerate people trying to link a.so a.so etc.
- if DEBUG: print >>sys.stderr, 'emcc: llvm-linking:', actual_files
+ logging.debug('emcc: llvm-linking:', actual_files)
# check for too-long command line
link_cmd = [LLVM_LINK] + actual_files + ['-o', target]
@@ -841,7 +933,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# for max command line size before we use a respose file
response_file = None
if WINDOWS and len(' '.join(link_cmd)) > 8192:
- if DEBUG: print >>sys.stderr, 'using response file for llvm-link'
+ logging.debug('using response file for llvm-link')
[response_fd, response_file] = mkstemp(suffix='.response', dir=TEMP_DIR)
link_cmd = [LLVM_LINK, "@" + response_file]
@@ -858,7 +950,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
link_cmd.append(target)
if len(' '.join(link_cmd)) > 8192:
- print >>sys.stderr, 'emcc: warning: link command line is very long, even with response file -- use paths with no spaces'
+ logging.warning('emcc: link command line is very long, even with response file -- use paths with no spaces')
output = Popen(link_cmd, stdout=PIPE).communicate()[0]
@@ -887,7 +979,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
if type(opts) is int:
opts = Building.pick_llvm_opts(opts)
#opts += ['-debug-pass=Arguments']
- if DEBUG: print >> sys.stderr, 'emcc: LLVM opts:', opts
+ logging.debug('emcc: LLVM opts:', opts)
output = Popen([LLVM_OPT, filename] + opts + ['-o=' + filename + '.opt.bc'], stdout=PIPE).communicate()[0]
assert os.path.exists(filename + '.opt.bc'), 'Failed to run llvm optimizations: ' + output
shutil.move(filename + '.opt.bc', filename)
@@ -1148,7 +1240,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
Building._is_ar_cache[filename] = sigcheck
return sigcheck
except Exception, e:
- 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)
+ logging.debug('Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e))
return False
@staticmethod
@@ -1175,8 +1267,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
curr = os.getcwd()
try:
ok = False
- print >> sys.stderr, '======================================='
- print >> sys.stderr, 'bootstrapping relooper...'
+ logging.info('=======================================')
+ logging.info('bootstrapping relooper...')
os.chdir(path_from_root('src'))
emcc_debug = os.environ.get('EMCC_DEBUG')
@@ -1201,19 +1293,19 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
f.close()
# bootstrap phase 1: generate unrelooped relooper, for which we do not need a relooper (so we cannot recurse infinitely in this function)
- print >> sys.stderr, ' bootstrap phase 1'
+ logging.info(' bootstrap phase 1')
make(1)
# bootstrap phase 2: generate relooped relooper, using the unrelooped relooper (we see relooper.js exists so we cannot recurse infinitely in this function)
- print >> sys.stderr, ' bootstrap phase 2'
+ logging.info(' bootstrap phase 2')
make(2)
- print >> sys.stderr, 'bootstrapping relooper succeeded'
- print >> sys.stderr, '======================================='
+ logging.info('bootstrapping relooper succeeded')
+ logging.info('=======================================')
ok = True
finally:
os.chdir(curr)
if emcc_debug: os.environ['EMCC_DEBUG'] = emcc_debug
if not ok:
- print >> sys.stderr, 'bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten'
+ logging.error('bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten')
1/0
@staticmethod
@@ -1274,7 +1366,7 @@ def execute(cmd, *args, **kw):
except:
if not isinstance(cmd, str):
cmd = ' '.join(cmd)
- print >> sys.stderr, 'Invoking Process failed: <<< ' + cmd + ' >>>'
+ logging.error('Invoking Process failed: <<< ' + cmd + ' >>>')
raise
def suffix(name):