diff options
Diffstat (limited to 'third_party/waf/waflib/Scripting.py')
-rw-r--r-- | third_party/waf/waflib/Scripting.py | 214 |
1 files changed, 102 insertions, 112 deletions
diff --git a/third_party/waf/waflib/Scripting.py b/third_party/waf/waflib/Scripting.py index 9b278403939..642d6d43e59 100644 --- a/third_party/waf/waflib/Scripting.py +++ b/third_party/waf/waflib/Scripting.py @@ -4,10 +4,12 @@ #!/usr/bin/env python # encoding: utf-8 -# Thomas Nagy, 2005-2016 (ita) +# Thomas Nagy, 2005-2018 (ita) "Module called for configuring, compiling and installing targets" +from __future__ import with_statement + import os, shlex, shutil, traceback, errno, sys, stat from waflib import Utils, Configure, Logs, Options, ConfigSet, Context, Errors, Build, Node @@ -28,58 +30,49 @@ def waf_entry_point(current_directory, version, wafdir): :param wafdir: absolute path representing the directory of the waf library :type wafdir: string """ - Logs.init_log() if Context.WAFVERSION != version: Logs.error('Waf script %r and library %r do not match (directory %r)', version, Context.WAFVERSION, wafdir) sys.exit(1) - if '--version' in sys.argv: - Context.run_dir = current_directory - ctx = Context.create_context('options') - ctx.curdir = current_directory - ctx.parse_args() - sys.exit(0) + # Store current directory before any chdir + Context.waf_dir = wafdir + Context.run_dir = Context.launch_dir = current_directory + start_dir = current_directory + no_climb = os.environ.get('NOCLIMB') if len(sys.argv) > 1: - # os.path.join handles absolute paths in sys.argv[1] accordingly (it discards the previous ones) + # os.path.join handles absolute paths # if sys.argv[1] is not an absolute path, then it is relative to the current working directory potential_wscript = os.path.join(current_directory, sys.argv[1]) - # maybe check if the file is executable - # perhaps extract 'wscript' as a constant - if os.path.basename(potential_wscript) == 'wscript' and os.path.isfile(potential_wscript): + if os.path.basename(potential_wscript) == Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): # need to explicitly normalize the path, as it may contain extra '/.' - # TODO abspath? - current_directory = os.path.normpath(os.path.dirname(potential_wscript)) + path = os.path.normpath(os.path.dirname(potential_wscript)) + start_dir = os.path.abspath(path) + no_climb = True sys.argv.pop(1) - Context.waf_dir = wafdir - Context.launch_dir = current_directory + ctx = Context.create_context('options') + (options, commands, env) = ctx.parse_cmd_args(allow_unknown=True) + if options.top: + start_dir = Context.run_dir = Context.top_dir = options.top + no_climb = True + if options.out: + Context.out_dir = options.out # if 'configure' is in the commands, do not search any further - no_climb = os.environ.get('NOCLIMB') if not no_climb: for k in no_climb_commands: - for y in sys.argv: + for y in commands: if y.startswith(k): no_climb = True break - # if --top is provided assume the build started in the top directory - for i, x in enumerate(sys.argv): - # WARNING: this modifies sys.argv - if x.startswith('--top='): - Context.run_dir = Context.top_dir = Utils.sane_path(x[6:]) - sys.argv[i] = '--top=' + Context.run_dir - if x.startswith('--out='): - Context.out_dir = Utils.sane_path(x[6:]) - sys.argv[i] = '--out=' + Context.out_dir - # try to find a lock file (if the project was configured) # at the same time, store the first wscript file seen - cur = current_directory - while cur and not Context.top_dir: + cur = start_dir + while cur: try: lst = os.listdir(cur) except OSError: @@ -134,14 +127,11 @@ def waf_entry_point(current_directory, version, wafdir): break if not Context.run_dir: - if '-h' in sys.argv or '--help' in sys.argv: - Logs.warn('No wscript file found: the help message may be incomplete') - Context.run_dir = current_directory - ctx = Context.create_context('options') - ctx.curdir = current_directory - ctx.parse_args() + if options.whelp: + Logs.warn('These are the generic options (no wscript/project found)') + ctx.parser.print_help() sys.exit(0) - Logs.error('Waf: Run from a directory containing a file named %r', Context.WSCRIPT_FILE) + Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)', Context.WSCRIPT_FILE) sys.exit(1) try: @@ -152,31 +142,40 @@ def waf_entry_point(current_directory, version, wafdir): try: set_main_module(os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE))) - except Errors.WafError ,e: + except Errors.WafError as e: Logs.pprint('RED', e.verbose_msg) Logs.error(str(e)) sys.exit(1) - except Exception ,e: + except Exception as e: Logs.error('Waf: The wscript in %r is unreadable', Context.run_dir) traceback.print_exc(file=sys.stdout) sys.exit(2) - if '--profile' in sys.argv: + if options.profile: import cProfile, pstats cProfile.runctx('from waflib import Scripting; Scripting.run_commands()', {}, {}, 'profi.txt') p = pstats.Stats('profi.txt') p.sort_stats('time').print_stats(75) # or 'cumulative' else: try: - run_commands() - except Errors.WafError ,e: + try: + run_commands() + except: + if options.pdb: + import pdb + type, value, tb = sys.exc_info() + traceback.print_exc() + pdb.post_mortem(tb) + else: + raise + except Errors.WafError as e: if Logs.verbose > 1: Logs.pprint('RED', e.verbose_msg) Logs.error(e.msg) sys.exit(1) except SystemExit: raise - except Exception ,e: + except Exception as e: traceback.print_exc(file=sys.stdout) sys.exit(2) except KeyboardInterrupt: @@ -217,29 +216,13 @@ def parse_options(): Parses the command-line options and initialize the logging system. Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. """ - Context.create_context('options').execute() - - for var in Options.envvars: - (name, value) = var.split('=', 1) - os.environ[name.strip()] = value - + ctx = Context.create_context('options') + ctx.execute() if not Options.commands: - Options.commands = [default_cmd] - Options.commands = [x for x in Options.commands if x != 'options'] # issue 1076 - - # process some internal Waf options - Logs.verbose = Options.options.verbose - #Logs.init_log() - - if Options.options.zones: - Logs.zones = Options.options.zones.split(',') - if not Logs.verbose: - Logs.verbose = 1 - elif Logs.verbose > 0: - Logs.zones = ['runner'] - - if Logs.verbose > 2: - Logs.zones = ['*'] + Options.commands.append(default_cmd) + if Options.options.whelp: + ctx.parser.print_help() + sys.exit(0) def run_command(cmd_name): """ @@ -305,38 +288,53 @@ def distclean_dir(dirname): pass def distclean(ctx): - '''removes the build directory''' - lst = os.listdir('.') - for f in lst: - if f == Options.lockfile: - try: - proj = ConfigSet.ConfigSet(f) - except IOError: - Logs.warn('Could not read %r', f) - continue + '''removes build folders and data''' - if proj['out_dir'] != proj['top_dir']: - try: - shutil.rmtree(proj['out_dir']) - except EnvironmentError ,e: - if e.errno != errno.ENOENT: - Logs.warn('Could not remove %r', proj['out_dir']) - else: - distclean_dir(proj['out_dir']) + def remove_and_log(k, fun): + try: + fun(k) + except EnvironmentError as e: + if e.errno != errno.ENOENT: + Logs.warn('Could not remove %r', k) - for k in (proj['out_dir'], proj['top_dir'], proj['run_dir']): - p = os.path.join(k, Options.lockfile) - try: - os.remove(p) - except OSError ,e: - if e.errno != errno.ENOENT: - Logs.warn('Could not remove %r', p) + # remove waf cache folders on the top-level + if not Options.commands: + for k in os.listdir('.'): + for x in '.waf-2 waf-2 .waf3-2 waf3-2'.split(): + if k.startswith(x): + remove_and_log(k, shutil.rmtree) + + # remove a build folder, if any + cur = '.' + if ctx.options.no_lock_in_top: + cur = ctx.options.out + + try: + lst = os.listdir(cur) + except OSError: + Logs.warn('Could not read %r', cur) + return + + if Options.lockfile in lst: + f = os.path.join(cur, Options.lockfile) + try: + env = ConfigSet.ConfigSet(f) + except EnvironmentError: + Logs.warn('Could not read %r', f) + return - # remove local waf cache folders - if not Options.commands: - for x in '.waf-1. waf-1. .waf3-1. waf3-1.'.split(): - if f.startswith(x): - shutil.rmtree(f, ignore_errors=True) + if not env.out_dir or not env.top_dir: + Logs.warn('Invalid lock file %r', f) + return + + if env.out_dir == env.top_dir: + distclean_dir(env.out_dir) + else: + remove_and_log(env.out_dir, shutil.rmtree) + + for k in (env.out_dir, env.top_dir, env.run_dir): + p = os.path.join(k, Options.lockfile) + remove_and_log(p, os.remove) class Dist(Context.Context): '''creates an archive containing the project source code''' @@ -391,11 +389,11 @@ class Dist(Context.Context): self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') try: - from hashlib import sha1 + from hashlib import sha256 except ImportError: digest = '' else: - digest = ' (sha=%r)' % sha1(node.read(flags='rb')).hexdigest() + digest = ' (sha256=%r)' % sha256(node.read(flags='rb')).hexdigest() Logs.info('New archive created: %s%s', self.arch_name, digest) @@ -424,11 +422,8 @@ class Dist(Context.Context): tinfo.gname = 'root' if os.path.isfile(p): - fu = open(p, 'rb') - try: - tar.addfile(tinfo, fileobj=fu) - finally: - fu.close() + with open(p, 'rb') as f: + tar.addfile(tinfo, fileobj=f) else: tar.addfile(tinfo) @@ -490,7 +485,7 @@ class Dist(Context.Context): try: return self.excl except AttributeError: - self.excl = Node.exclude_regs + ' **/waf-1.8.* **/.waf-1.8* **/waf3-1.8.* **/.waf3-1.8* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' + self.excl = Node.exclude_regs + ' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' if Context.out_dir: nd = self.root.find_node(Context.out_dir) if nd: @@ -523,11 +518,7 @@ def dist(ctx): pass class DistCheck(Dist): - """ - Creates an archive of the project, then attempts to build the project in a temporary directory:: - - $ waf distcheck - """ + """creates an archive with dist, then tries to build it""" fun = 'distcheck' cmd = 'distcheck' @@ -554,12 +545,9 @@ class DistCheck(Dist): """ import tempfile, tarfile - try: - t = tarfile.open(self.get_arch_name()) + with tarfile.open(self.get_arch_name()) as t: for x in t: t.extract(x) - finally: - t.close() instdir = tempfile.mkdtemp('.inst', self.get_base_name()) cmd = self.make_distcheck_cmd(instdir) @@ -613,7 +601,8 @@ def autoconfigure(execute_method): cmd = env.config_cmd or 'configure' if Configure.autoconfig == 'clobber': tmp = Options.options.__dict__ - Options.options.__dict__ = env.options + if env.options: + Options.options.__dict__ = env.options try: run_command(cmd) finally: @@ -625,3 +614,4 @@ def autoconfigure(execute_method): return execute_method(self) return execute Build.BuildContext.execute = autoconfigure(Build.BuildContext.execute) + |