diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2009-12-09 16:27:33 +0300 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2009-12-09 16:27:33 +0300 |
commit | a73227bf28e07539867ee450288916bb87fb95f1 (patch) | |
tree | a33c5338acf0c9d00a43148c67c51f6d664921bf /tools | |
parent | 4ddfd8aa42c365a2351d9cbe2f98470fb81a8c41 (diff) |
Upgrade waf to 1.5.10
Diffstat (limited to 'tools')
45 files changed, 623 insertions, 385 deletions
diff --git a/tools/waf-light b/tools/waf-light index a506f82354e..6a02da1f73a 100755 --- a/tools/waf-light +++ b/tools/waf-light @@ -37,7 +37,7 @@ if 'PSYCOWAF' in os.environ: try:import psyco;psyco.full() except:pass -VERSION="1.5.9" +VERSION="1.5.10" REVISION="x" INSTALL="x" C1='x' @@ -75,8 +75,11 @@ def unpack_wafdir(dir): import shutil, tarfile try: shutil.rmtree(dir) except OSError: pass - try: os.makedirs(join(dir, 'wafadmin', 'Tools')) - except OSError: err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir) + try: + for x in ['Tools', '3rdparty']: + os.makedirs(join(dir, 'wafadmin', x)) + except OSError: + err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir) os.chdir(dir) tmp = 't.tbz2' @@ -94,7 +97,8 @@ def unpack_wafdir(dir): except OSError: pass err("Waf cannot be unpacked, check that bzip2 support is present") - os.chmod(join('wafadmin','Tools'), 493) + for x in ['Tools', '3rdparty']: + os.chmod(join('wafadmin',x), 493) os.unlink(tmp) @@ -142,7 +146,8 @@ def find_lib(): wafdir = find_lib() w = join(wafdir, 'wafadmin') t = join(w, 'Tools') -sys.path = [w, t] + sys.path +f = join(w, '3rdparty') +sys.path = [w, t, f] + sys.path import Scripting Scripting.prepare(t, cwd, VERSION, wafdir) diff --git a/tools/wafadmin/Tools/boost.py b/tools/wafadmin/3rdparty/boost.py index 47e4500d2e2..47e4500d2e2 100644 --- a/tools/wafadmin/Tools/boost.py +++ b/tools/wafadmin/3rdparty/boost.py diff --git a/tools/wafadmin/3rdparty/fluid.py b/tools/wafadmin/3rdparty/fluid.py new file mode 100644 index 00000000000..117edef7200 --- /dev/null +++ b/tools/wafadmin/3rdparty/fluid.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# encoding: utf-8 +# Grygoriy Fuchedzhy 2009 + +""" +Compile fluid files (fltk graphic library). Use the 'fluid' feature in conjuction with the 'cxx' feature. +""" + +import Task +from TaskGen import extension + +Task.simple_task_type('fluid', '${FLUID} -c -o ${TGT[0].abspath(env)} -h ${TGT[1].abspath(env)} ${SRC}', 'BLUE', shell=False, ext_out='.cxx') + +@extension('.fl') +def fluid(self, node): + """add the .fl to the source list; the cxx file generated will be compiled when possible""" + cpp = node.change_ext('.cpp') + hpp = node.change_ext('.hpp') + self.create_task('fluid', node, [cpp, hpp]) + + if 'cxx' in self.features: + self.allnodes.append(cpp) + +def detect(conf): + fluid = conf.find_program('fluid', var='FLUID', mandatory=True) + conf.check_cfg(path='fltk-config', package='', args='--cxxflags --ldflags', uselib_store='FLTK', mandatory=True) + diff --git a/tools/wafadmin/Build.py b/tools/wafadmin/Build.py index 98c22abbbbb..509b625108b 100644 --- a/tools/wafadmin/Build.py +++ b/tools/wafadmin/Build.py @@ -57,8 +57,10 @@ def group_method(fun): postpone = kw['postpone'] del kw['postpone'] + # TODO waf 1.6 in theory there should be no reference to the TaskManager internals here if postpone: m = k[0].task_manager + if not m.groups: m.add_group() m.groups[m.current_group].post_funs.append((fun, k, kw)) kw['cwd'] = k[0].path else: @@ -801,6 +803,9 @@ class BuildContext(Utils.Context): else: lst = Utils.to_list(files) + if not getattr(lst, '__iter__', False): + lst = [lst] + destpath = self.get_install_path(path, env) Utils.check_dir(destpath) diff --git a/tools/wafadmin/Constants.py b/tools/wafadmin/Constants.py index 4df0b9b36b5..35147b9b505 100644 --- a/tools/wafadmin/Constants.py +++ b/tools/wafadmin/Constants.py @@ -9,9 +9,9 @@ maintainer: the version number is updated from the top-level wscript file """ # do not touch these three lines, they are updated automatically -HEXVERSION = 0x10509 -WAFVERSION="1.5.9" -WAFREVISION = "6626:6639M" +HEXVERSION = 0x105010 +WAFVERSION="1.5.10" +WAFREVISION = "6794M" ABI = 7 # permissions diff --git a/tools/wafadmin/Environment.py b/tools/wafadmin/Environment.py index 7838bd149db..984d2ff04f3 100644 --- a/tools/wafadmin/Environment.py +++ b/tools/wafadmin/Environment.py @@ -86,7 +86,7 @@ class Environment(object): else: keys = tbl.keys() for x in keys: - tbl[x] = copy.copy(tbl[x]) + tbl[x] = copy.deepcopy(tbl[x]) self.table = tbl def get_flat(self, key): diff --git a/tools/wafadmin/Logs.py b/tools/wafadmin/Logs.py index 0d55e1fe2d6..c2da1ddb8c4 100644 --- a/tools/wafadmin/Logs.py +++ b/tools/wafadmin/Logs.py @@ -2,6 +2,7 @@ # encoding: utf-8 # Thomas Nagy, 2005 (ita) +import ansiterm import os, re, logging, traceback, sys from Constants import * @@ -11,7 +12,7 @@ verbose = 0 colors_lst = { 'USE' : True, 'BOLD' :'\x1b[01;1m', -'RED' :'\x1b[01;91m', +'RED' :'\x1b[01;31m', 'GREEN' :'\x1b[32m', 'YELLOW':'\x1b[33m', 'PINK' :'\x1b[35m', @@ -31,9 +32,13 @@ if got_tty: import Utils -if not got_tty or sys.platform == 'win32' or 'NOCOLOR' in os.environ: +if not got_tty or 'NOCOLOR' in os.environ: colors_lst['USE'] = False +# test +#if sys.platform == 'win32': +# colors_lst['USE'] = True + def get_color(cl): if not colors_lst['USE']: return '' return colors_lst.get(cl, '') diff --git a/tools/wafadmin/Node.py b/tools/wafadmin/Node.py index ba17ab434b1..6157aaa78c8 100644 --- a/tools/wafadmin/Node.py +++ b/tools/wafadmin/Node.py @@ -6,15 +6,15 @@ Node: filesystem structure, contains lists of nodes IMPORTANT: -1. Each file/folder is represented by exactly one node +1. Each file/folder is represented by exactly one node. 2. Most would-be class properties are stored in Build: nodes to depend on, signature, flags, .. -unused class members increase the .wafpickle file size sensibly with lots of objects +unused class members increase the .wafpickle file size sensibly with lots of objects. -3. The build is launched from the top of the build dir (for example, in _build_/) +3. The build is launched from the top of the build dir (for example, in _build_/). 4. Node should not be instantiated directly. -Each instance of Build.BuildContext has a Node sublass. +Each instance of Build.BuildContext has a Node subclass. (aka: 'Nodu', see BuildContext initializer) The BuildContext is referenced here as self.__class__.bld Its Node class is referenced here as self.__class__ diff --git a/tools/wafadmin/Scripting.py b/tools/wafadmin/Scripting.py index 0aee26d2a53..a1d53b3c874 100644 --- a/tools/wafadmin/Scripting.py +++ b/tools/wafadmin/Scripting.py @@ -27,7 +27,7 @@ def prepare_impl(t, cwd, ver, wafdir): # now find the wscript file msg1 = 'Waf: Please run waf from a directory containing a file named "%s" or run distclean' % WSCRIPT_FILE - # in theory projects can be configured in a gcc manner: + # in theory projects can be configured in an autotool-like manner: # mkdir build && cd build && ../waf configure && ../waf build_dir_override = None candidate = None @@ -39,7 +39,7 @@ def prepare_impl(t, cwd, ver, wafdir): candidate = cwd elif 'configure' in sys.argv and not WSCRIPT_BUILD_FILE in lst: - # gcc-like configuration + # autotool-like configuration calldir = os.path.abspath(os.path.dirname(sys.argv[0])) if WSCRIPT_FILE in os.listdir(calldir): candidate = calldir @@ -60,7 +60,10 @@ def prepare_impl(t, cwd, ver, wafdir): break if Options.lockfile in dirlst: env = Environment.Environment() - env.load(os.path.join(cwd, Options.lockfile)) + try: + env.load(os.path.join(cwd, Options.lockfile)) + except: + error('could not load %r' % Options.lockfile) try: os.stat(env['cwd']) except: diff --git a/tools/wafadmin/Task.py b/tools/wafadmin/Task.py index 79b37b04c1d..9efaf417ea8 100644 --- a/tools/wafadmin/Task.py +++ b/tools/wafadmin/Task.py @@ -569,7 +569,7 @@ class Task(TaskBase): def add_file_dependency(self, filename): "TODO user-provided file dependencies" - node = self.generator.bld.current.find_resource(filename) + node = self.generator.bld.path.find_resource(filename) self.deps_nodes.append(node) def signature(self): diff --git a/tools/wafadmin/TaskGen.py b/tools/wafadmin/TaskGen.py index 07a6e958b7b..97f2f016839 100644 --- a/tools/wafadmin/TaskGen.py +++ b/tools/wafadmin/TaskGen.py @@ -228,9 +228,13 @@ class task_gen(object): # TODO waf 1.6: always set the environment # TODO waf 1.6: create_task(self, name, inputs, outputs) - def create_task(self, name, env=None): + def create_task(self, name, src=None, tgt=None, env=None): env = env or self.env task = Task.TaskBase.classes[name](env.copy(), generator=self) + if src: + task.set_inputs(src) + if tgt: + task.set_outputs(tgt) self.tasks.append(task) return task @@ -260,7 +264,7 @@ class task_gen(object): #make sure dirnames is a list helps with dirnames with spaces dirnames = self.to_list(dirnames) - ext_lst = exts or self.mappings.keys() + task_gen.mappings.keys() + ext_lst = exts or list(self.mappings.keys()) + list(task_gen.mappings.keys()) for name in dirnames: anode = self.path.find_dir(name) @@ -375,11 +379,9 @@ def declare_chain(name='', action='', ext_in='', ext_out='', reentrant=1, color= # XXX: useless: it will fail on Utils.to_list above... raise Utils.WafError("do not know how to process %s" % str(ext)) - tsk = self.create_task(name) - tsk.set_inputs(node) - tsk.set_outputs(out_source) + tsk = self.create_task(name, node, out_source) - if node.__class__.bld.is_install == INSTALL: + if node.__class__.bld.is_install: tsk.install = install declare_extension(act.ext_in, x_file) @@ -511,7 +513,7 @@ def exec_rule(self): if getattr(self, 'target', None): cls.quiet = True - tsk.outputs=[self.path.find_or_declare(x) for x in self.to_list(self.target)] + tsk.outputs = [self.path.find_or_declare(x) for x in self.to_list(self.target)] if getattr(self, 'source', None): cls.quiet = True diff --git a/tools/wafadmin/Tools/UnitTest.py b/tools/wafadmin/Tools/UnitTest.py index 4c41a59ebf4..a65f0312184 100644 --- a/tools/wafadmin/Tools/UnitTest.py +++ b/tools/wafadmin/Tools/UnitTest.py @@ -19,6 +19,7 @@ Each object to use as a unit test must be a program and must have X{obj.unit_tes """ import os, sys import Build, TaskGen, Utils, Options, Logs, Task +from TaskGen import before, after, feature from Constants import * class unit_test(object): @@ -210,37 +211,58 @@ bld.add_post_fun(UnitTest.summary) import threading testlock = threading.Lock() -@TaskGen.feature('test') -@TaskGen.after('apply_link') +@feature('test') +@after('apply_link', 'vars_target_cprogram') def make_test(self): if not 'cprogram' in self.features: Logs.error('test cannot be executed %s' % self) return + self.default_install_path = None tsk = self.create_task('utest') tsk.set_inputs(self.link_task.outputs) def exec_test(self): + testlock.acquire() fail = False try: - testlock.acquire() - filename = self.inputs[0].abspath(self.env) + + try: + fu = getattr(self.generator.bld, 'all_test_paths') + except AttributeError: + fu = os.environ.copy() + self.generator.bld.all_test_paths = fu + + lst = [] + for obj in self.generator.bld.all_task_gen: + link_task = getattr(obj, 'link_task', None) + if link_task: + lst.append(link_task.outputs[0].parent.abspath(obj.env)) + + def add_path(dct, path, var): + dct[var] = os.pathsep.join(Utils.to_list(path) + [os.environ.get(var, '')]) + if sys.platform == 'win32': + add_path(fu, lst, 'PATH') + elif sys.platform == 'darwin': + add_path(fu, lst, 'DYLD_LIBRARY_PATH') + add_path(fu, lst, 'LD_LIBRARY_PATH') + else: + add_path(fu, lst, 'LD_LIBRARY_PATH') + try: - ret = Utils.cmd_output(filename, cwd='/cygdrive/c/home/waf-1.5.8/demos/unit_test/tests/test0') + ret = Utils.cmd_output(filename, cwd=self.inputs[0].parent.abspath(self.env), env=fu) except Exception, e: fail = True - ret = "" + ret = '' + str(e) else: pass stats = getattr(self.generator.bld, 'utest_results', []) stats.append((filename, fail, ret)) self.generator.bld.utest_results = stats - + finally: testlock.release() - except Exception, e: - print e cls = Task.task_type_from_func('utest', func=exec_test, color='RED', ext_in='.bin') @@ -260,6 +282,7 @@ def summary(bld): for (f, fail, ret) in lst: col = fail and 'RED' or 'GREEN' Utils.pprint(col, (fail and 'FAIL' or 'ok') + " " + f) + if fail: Utils.pprint('NORMAL', ret.replace('\\n', '\n')) def set_options(opt): opt.add_option('--alltests', action='store_true', default=False, help='Exec all unit tests', dest='all_tests') diff --git a/tools/wafadmin/Tools/bison.py b/tools/wafadmin/Tools/bison.py index d56fc706db8..39e1c4beabe 100644 --- a/tools/wafadmin/Tools/bison.py +++ b/tools/wafadmin/Tools/bison.py @@ -14,9 +14,6 @@ cls = Task.simple_task_type('bison', bison, 'GREEN', ext_in='.yc .y .yy', ext_ou @extension(['.y', '.yc', '.yy']) def big_bison(self, node): """when it becomes complicated (unlike flex), the old recipes work better (cwd)""" - tsk = self.create_task('bison') - tsk.set_inputs(node) - has_h = '-d' in self.env['BISONFLAGS'] outs = [] @@ -29,7 +26,7 @@ def big_bison(self, node): if has_h: outs.append(node.change_ext('.tab.h')) - tsk.set_outputs(outs) + tsk = self.create_task('bison', node, outs) tsk.cwd = node.bld_dir(tsk.env) # and the c/cxx file must be compiled too diff --git a/tools/wafadmin/Tools/cc.py b/tools/wafadmin/Tools/cc.py index 0d6f037b1fc..59edae44fe7 100644 --- a/tools/wafadmin/Tools/cc.py +++ b/tools/wafadmin/Tools/cc.py @@ -76,14 +76,12 @@ def apply_defines_cc(self): @extension(EXT_CC) def c_hook(self, node): # create the compilation task: cpp or cc - task = self.create_task('cc') if getattr(self, 'obj_ext', None): obj_ext = self.obj_ext else: obj_ext = '_%d.o' % self.idx - task.inputs = [node] - task.outputs = [node.change_ext(obj_ext)] + task = self.create_task('cc', node, node.change_ext(obj_ext)) try: self.compiled_tasks.append(task) except AttributeError: diff --git a/tools/wafadmin/Tools/ccroot.py b/tools/wafadmin/Tools/ccroot.py index 2f71e0c0a19..0ee2609a1b4 100644 --- a/tools/wafadmin/Tools/ccroot.py +++ b/tools/wafadmin/Tools/ccroot.py @@ -10,6 +10,7 @@ from Logs import error, debug, warn from Utils import md5 from TaskGen import taskgen, after, before, feature from Constants import * +from Configure import conftest try: from cStringIO import StringIO except ImportError: @@ -136,14 +137,14 @@ def scan(self): all_nodes = [] all_names = [] - seen = [] + seen = set() for node in self.inputs: (nodes, names) = preproc.get_deps(node, self.env, nodepaths = self.env['INC_PATHS']) if Logs.verbose: debug('deps: deps for %s: %r; unresolved %r' % (str(node), nodes, names)) for x in nodes: if id(x) in seen: continue - seen.append(id(x)) + seen.add(id(x)) all_nodes.append(x) for x in names: if not x in all_names: @@ -239,7 +240,7 @@ def default_link_install(self): """you may kill this method to inject your own installation for the first element any other install should only process its own nodes and not those from the others""" if self.install_path: - self.bld.install_files(self.install_path, [self.link_task.outputs[0]], env=self.env, chmod=self.chmod) + self.bld.install_files(self.install_path, self.link_task.outputs[0], env=self.env, chmod=self.chmod) @feature('cc', 'cxx') @after('apply_type_vars', 'apply_lib_vars', 'apply_core') @@ -336,13 +337,13 @@ def apply_lib_vars(self): # 1. the case of the libs defined in the project (visit ancestors first) # the ancestors external libraries (uselib) will be prepended - uselib = self.to_list(self.uselib) + self.uselib = self.to_list(self.uselib) names = self.to_list(self.uselib_local) - seen = [] - tmp = names[:] # consume a copy of the list of names + seen = set([]) + tmp = Utils.deque(names) # consume a copy of the list of names while tmp: - lib_name = tmp.pop(0) + lib_name = tmp.popleft() # visit dependencies only once if lib_name in seen: continue @@ -351,7 +352,7 @@ def apply_lib_vars(self): if not y: raise Utils.WafError('object %r was not found in uselib_local (required by %r)' % (lib_name, self.name)) y.post() - seen.append(lib_name) + seen.add(lib_name) # object has ancestors to process (shared libraries): add them to the end of the list if getattr(y, 'uselib_local', None): @@ -381,12 +382,11 @@ def apply_lib_vars(self): tmp_path = y.link_task.outputs[0].parent.bldpath(self.env) if not tmp_path in env['LIBPATH']: env.prepend_value('LIBPATH', tmp_path) - # add ancestors uselib too - # WARNING providing STATICLIB_FOO in env will result in broken builds - # TODO waf 1.6 prevent this behaviour somehow + # add ancestors uselib too - but only propagate those that have no staticlib for v in self.to_list(y.uselib): - if v in uselib: continue - uselib = [v] + uselib + if not env['STATICLIB_' + v]: + if not v in self.uselib: + self.uselib.insert(0, v) # if the library task generator provides 'export_incdirs', add to the include path # the export_incdirs must be a list of paths relative to the other library @@ -398,13 +398,13 @@ def apply_lib_vars(self): self.env.append_unique('INC_PATHS', node) # 2. the case of the libs defined outside - for x in uselib: + for x in self.uselib: for v in self.p_flag_vars: val = self.env[v + '_' + x] if val: self.env.append_value(v, val) @feature('cprogram', 'cstaticlib', 'cshlib') -@after('apply_link') +@after('init_cc', 'init_cxx', 'apply_link') def apply_objdeps(self): "add the .o files produced by some other object files in the same manner as uselib_local" if not getattr(self, 'add_objects', None): return @@ -542,7 +542,7 @@ def apply_implib(self): # install the dll in the bin dir dll = self.link_task.outputs[0] - self.bld.install_files(bindir, [dll], self.env, self.chmod) + self.bld.install_files(bindir, dll, self.env, self.chmod) # add linker flags to generate the import lib implib = self.env['implib_PATTERN'] % os.path.split(self.target)[1] @@ -562,7 +562,7 @@ def apply_vnum(self): """ libfoo.so is installed as libfoo.so.1.2.3 """ - if not getattr(self, 'vnum', '') or not 'cshlib' in self.features or os.name != 'posix' or self.env.DEST_BINFMT != 'elf': + if not getattr(self, 'vnum', '') or not 'cshlib' in self.features or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): return self.meths.remove('default_link_install') @@ -573,13 +573,15 @@ def apply_vnum(self): libname = node.name if libname.endswith('.dylib'): - name3 = libname.replace('.dylib', '.%s.dylib' % task.vnum) + name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum) name2 = libname.replace('.dylib', '.%s.dylib' % nums[0]) else: name3 = libname + '.' + self.vnum name2 = libname + '.' + nums[0] - self.env.append_value('LINKFLAGS', (self.env['SONAME_ST'] % name2).split()) + if self.env.SONAME_ST: + v = self.env.SONAME_ST % name2 + self.env.append_value('LINKFLAGS', v.split()) bld = self.bld nums = self.vnum.split('.') @@ -597,17 +599,24 @@ def apply_vnum(self): tsk.set_outputs(node.parent.find_or_declare(name2)) def exec_vnum_link(self): - path = self.inputs[0].parent.abspath(self.env) + path = self.outputs[0].abspath(self.env) try: - os.remove(self.outputs[0].abspath()) - except OSError, e: + os.remove(path) + except OSError: pass try: - os.symlink(self.inputs[0].name, self.outputs[0].abspath(self.env)) - except Exception, e: + os.symlink(self.inputs[0].name, path) + except OSError: return 1 cls = Task.task_type_from_func('vnum', func=exec_vnum_link, ext_in='.bin', color='CYAN') cls.quiet = 1 +# ============ the --as-needed flag should added during the configuration, not at runtime ========= + +@conftest +def add_as_needed(conf): + if conf.env.DEST_BINFMT == 'elf' and 'gcc' in (conf.env.CXX_NAME, conf.env.CC_NAME): + conf.env.append_unique('LINKFLAGS', '--as-needed') + diff --git a/tools/wafadmin/Tools/config_c.py b/tools/wafadmin/Tools/config_c.py index 0e293d8e4ae..beb17abb6c0 100644 --- a/tools/wafadmin/Tools/config_c.py +++ b/tools/wafadmin/Tools/config_c.py @@ -66,8 +66,9 @@ def parse_flags(line, uselib, env): env.append_unique('CXXFLAGS_' + uselib, x) env.append_unique('LINKFLAGS_' + uselib, x) elif x == '-framework': - framework = lst.pop(0) - env.append_unique('FRAMEWORK_' + uselib, framework) + env.append_unique('FRAMEWORK_' + uselib, lst.pop(0)) + elif x.startswith('-F'): + env.append_unique('FRAMEWORKPATH_' + uselib, x[2:]) elif x.startswith('-std'): env.append_unique('CCFLAGS_' + uselib, x) env.append_unique('LINKFLAGS_' + uselib, x) @@ -642,9 +643,10 @@ def get_config_header(self): config_header.append('#define %s' % key) elif value is UNDEFINED: config_header.append('/* #undef %s */' % key) + elif isinstance(value, str): + config_header.append('#define %s %s' % (key, repr(value)[1:-1])) else: config_header.append('#define %s %s' % (key, value)) - return "\n".join(config_header) @conftest @@ -662,13 +664,16 @@ def find_cpp(conf): def cc_add_flags(conf): conf.add_os_flags('CFLAGS', 'CCFLAGS') conf.add_os_flags('CPPFLAGS') - conf.add_os_flags('LINKFLAGS') @conftest def cxx_add_flags(conf): conf.add_os_flags('CXXFLAGS') conf.add_os_flags('CPPFLAGS') + +@conftest +def link_add_flags(conf): conf.add_os_flags('LINKFLAGS') + conf.add_os_flags('LDFLAGS', 'LINKFLAGS') @conftest def cc_load_tools(conf): diff --git a/tools/wafadmin/Tools/cs.py b/tools/wafadmin/Tools/cs.py index a54e8d32880..43544856f34 100644 --- a/tools/wafadmin/Tools/cs.py +++ b/tools/wafadmin/Tools/cs.py @@ -4,7 +4,7 @@ "C# support" -import TaskGen, Utils, Task +import TaskGen, Utils, Task, Options from Logs import error from TaskGen import before, after, taskgen, feature @@ -37,33 +37,32 @@ def apply_cs(self): except ValueError: pass # process the flags for the assemblies - assemblies_flags = [] for i in self.to_list(self.assemblies) + self.env['ASSEMBLIES']: - assemblies_flags += '/r:'+i - self.env['_ASSEMBLIES'] += assemblies_flags + self.env.append_unique('_ASSEMBLIES', '/r:'+i) # process the flags for the resources for i in self.to_list(self.resources): - self.env['_RESOURCES'].append('/resource:'+i) + self.env.append_unique('_RESOURCES', '/resource:'+i) - # additional flags - self.env['_FLAGS'] += self.to_list(self.flags) + self.env['FLAGS'] + # what kind of assembly are we generating? + self.env['_TYPE'] = getattr(self, 'type', 'exe') - curnode = self.path + # additional flags + self.env.append_unique('_FLAGS', self.to_list(self.flags)) + self.env.append_unique('_FLAGS', self.env.FLAGS) # process the sources - nodes = [] - for i in self.to_list(self.source): - nodes.append(curnode.find_resource(i)) + nodes = [self.path.find_resource(i) for i in self.to_list(self.source)] + self.create_task('mcs', nodes, self.path.find_or_declare(self.target)) - # create the task - task = self.create_task('mcs') - task.inputs = nodes - task.set_outputs(self.path.find_or_declare(self.target)) - -Task.simple_task_type('mcs', '${MCS} ${SRC} /out:${TGT} ${_FLAGS} ${_ASSEMBLIES} ${_RESOURCES}', color='YELLOW') +Task.simple_task_type('mcs', '${MCS} ${SRC} /target:${_TYPE} /out:${TGT} ${_FLAGS} ${_ASSEMBLIES} ${_RESOURCES}', color='YELLOW') def detect(conf): - mcs = conf.find_program('mcs', var='MCS') - if not mcs: mcs = conf.find_program('gmcs', var='MCS') + csc = getattr(Options.options, 'cscbinary', None) + if csc: + conf.env.MCS = csc + conf.find_program(['gmcs', 'mcs'], var='MCS') + +def set_options(opt): + opt.add_option('--with-csc-binary', type='string', dest='cscbinary') diff --git a/tools/wafadmin/Tools/cxx.py b/tools/wafadmin/Tools/cxx.py index e82adb2e08b..052bcef9241 100644 --- a/tools/wafadmin/Tools/cxx.py +++ b/tools/wafadmin/Tools/cxx.py @@ -80,14 +80,12 @@ def apply_defines_cxx(self): @extension(EXT_CXX) def cxx_hook(self, node): # create the compilation task: cpp or cc - task = self.create_task('cxx') if getattr(self, 'obj_ext', None): obj_ext = self.obj_ext else: obj_ext = '_%d.o' % self.idx - task.inputs = [node] - task.outputs = [node.change_ext(obj_ext)] + task = self.create_task('cxx', node, node.change_ext(obj_ext)) try: self.compiled_tasks.append(task) except AttributeError: diff --git a/tools/wafadmin/Tools/d.py b/tools/wafadmin/Tools/d.py index 256e33a2a31..4f4bddb749f 100644 --- a/tools/wafadmin/Tools/d.py +++ b/tools/wafadmin/Tools/d.py @@ -38,7 +38,7 @@ def filter_comments(filename): else: break #print "cnt is ", str(cnt) if (cnt%2)==0: break - # i -= 1 # <- useless in practice + i += 1 # skip a char elif c == "'": i += 1 @@ -260,66 +260,67 @@ def init_d(self): link_task=None) @feature('d') -@after('apply_d_link') +@after('apply_d_link', 'init_d') @before('apply_vnum') def apply_d_libs(self): - uselib = self.to_list(self.uselib) - seen = [] - local_libs = self.to_list(self.uselib_local) - libs = [] - libpaths = [] + """after apply_link because of 'link_task' + after default_cc because of the attribute 'uselib'""" env = self.env - while local_libs: - x = local_libs.pop() + # 1. the case of the libs defined in the project (visit ancestors first) + # the ancestors external libraries (uselib) will be prepended + self.uselib = self.to_list(self.uselib) + names = self.to_list(self.uselib_local) + + seen = set([]) + tmp = Utils.deque(names) # consume a copy of the list of names + while tmp: + lib_name = tmp.popleft() # visit dependencies only once - if x in seen: + if lib_name in seen: continue - else: - seen.append(x) - y = self.name_to_obj(x) + y = self.name_to_obj(lib_name) if not y: - raise Utils.WafError('object not found in uselib_local: obj %s uselib %s' % (self.name, x)) + raise Utils.WafError('object %r was not found in uselib_local (required by %r)' % (lib_name, self.name)) + y.post() + seen.add(lib_name) - # object has ancestors to process first ? update the list of names - if y.uselib_local: - added = 0 + # object has ancestors to process (shared libraries): add them to the end of the list + if getattr(y, 'uselib_local', None): lst = y.to_list(y.uselib_local) - lst.reverse() - for u in lst: - if u in seen: continue - added = 1 - local_libs = [u]+local_libs - if added: continue # list of names modified, loop - - # safe to process the current object - y.post() - seen.append(x) + if 'dshlib' in y.features or 'cprogram' in y.features: + lst = [x for x in lst if not 'cstaticlib' in self.name_to_obj(x).features] + tmp.extend(lst) - libname = y.target[y.target.rfind(os.sep) + 1:] - if 'dshlib' in y.features or 'dstaticlib' in y.features: - #libs.append(y.target) - env.append_unique('DLINKFLAGS', env['DLIBPATH_ST'] % y.link_task.outputs[0].parent.bldpath(env)) - env.append_unique('DLINKFLAGS', env['DLIB_ST'] % libname) + # link task and flags + if getattr(y, 'link_task', None): - # add the link path too - tmp_path = y.path.bldpath(env) - if not tmp_path in libpaths: libpaths = [tmp_path] + libpaths + link_name = y.target[y.target.rfind(os.sep) + 1:] + if 'dstaticlib' in y.features or 'dshlib' in y.features: + env.append_unique('DLINKFLAGS', env.DLIB_ST % link_name) + env.append_unique('DLINKFLAGS', env.DLIBPATH_ST % y.link_task.outputs[0].parent.bldpath(env)) - # set the dependency over the link task - if y.link_task is not None: + # the order self.link_task.set_run_after(y.link_task) + + # for the recompilation dep_nodes = getattr(self.link_task, 'dep_nodes', []) self.link_task.dep_nodes = dep_nodes + y.link_task.outputs - # add ancestors uselib too - # TODO potential problems with static libraries ? - morelibs = y.to_list(y.uselib) - for v in morelibs: - if v in uselib: continue - uselib = [v]+uselib - self.uselib = uselib + # add ancestors uselib too - but only propagate those that have no staticlib + for v in self.to_list(y.uselib): + if not v in self.uselib: + self.uselib.insert(0, v) + + # if the library task generator provides 'export_incdirs', add to the include path + # the export_incdirs must be a list of paths relative to the other library + if getattr(y, 'export_incdirs', None): + for x in self.to_list(y.export_incdirs): + node = y.path.find_dir(x) + if not node: + raise Utils.WafError('object %r: invalid folder %r in export_incdirs' % (y.target, x)) + self.env.append_unique('INC_PATHS', node) @feature('dprogram', 'dshlib', 'dstaticlib') @after('apply_core') @@ -328,12 +329,9 @@ def apply_d_link(self): if not link: if 'dstaticlib' in self.features: link = 'static_link' else: link = 'd_link' - linktask = self.create_task(link) - outputs = [t.outputs[0] for t in self.compiled_tasks] - linktask.set_inputs(outputs) - linktask.set_outputs(self.path.find_or_declare(get_target_name(self))) - self.link_task = linktask + outputs = [t.outputs[0] for t in self.compiled_tasks] + self.link_task = self.create_task(link, outputs, self.path.find_or_declare(get_target_name(self))) @feature('d') @after('apply_core') @@ -343,7 +341,6 @@ def apply_d_vars(self): lib_st = env['DLIB_ST'] libpath_st = env['DLIBPATH_ST'] - #dflags = [] importpaths = self.to_list(self.importpaths) libpaths = [] libs = [] @@ -383,10 +380,11 @@ def apply_d_vars(self): if env['LIBPATH_' + i]: for entry in self.to_list(env['LIBPATH_' + i]): if not entry in libpaths: - libpaths += [entry] + libpaths.append(entry) libpaths = self.to_list(self.libpaths) + libpaths # now process the library paths + # apply same path manipulation as used with import paths for path in libpaths: env.append_unique('DLINKFLAGS', libpath_st % path) @@ -395,8 +393,12 @@ def apply_d_vars(self): if env['LIB_' + i]: for entry in self.to_list(env['LIB_' + i]): if not entry in libs: - libs += [entry] - libs = libs + self.to_list(self.libs) + libs.append(entry) + libs.extend(self.to_list(self.libs)) + + # process user flags + for flag in self.to_list(self.dflags): + env.append_unique('DFLAGS', flag) # now process the libraries for lib in libs: @@ -486,8 +488,9 @@ Task.simple_task_type('d_header', d_header_str, color='BLUE', shell=False) @conftest def d_platform_flags(conf): - binfmt = conf.env.DEST_BINFMT or Utils.unversioned_sys_platform_to_binary_format( - conf.env.DEST_OS or Utils.unversioned_sys_platform()) + v = conf.env + binfmt = v.DEST_BINFMT or Utils.unversioned_sys_platform_to_binary_format( + v.DEST_OS or Utils.unversioned_sys_platform()) if binfmt == 'pe': v['D_program_PATTERN'] = '%s.exe' v['D_shlib_PATTERN'] = 'lib%s.dll' @@ -497,7 +500,6 @@ def d_platform_flags(conf): v['D_shlib_PATTERN'] = 'lib%s.so' v['D_staticlib_PATTERN'] = 'lib%s.a' - # quick test # if __name__ == "__main__": #Logs.verbose = 2 diff --git a/tools/wafadmin/Tools/dbus.py b/tools/wafadmin/Tools/dbus.py index e454177fd2c..31799993921 100644 --- a/tools/wafadmin/Tools/dbus.py +++ b/tools/wafadmin/Tools/dbus.py @@ -15,18 +15,15 @@ def add_dbus_file(self, filename, prefix, mode): @before('apply_core') def process_dbus(self): for filename, prefix, mode in getattr(self, 'dbus_lst', []): - env = self.env.copy() node = self.path.find_resource(filename) if not node: raise Utils.WafError('file not found ' + filename) - env['DBUS_BINDING_TOOL_PREFIX'] = prefix - env['DBUS_BINDING_TOOL_MODE'] = mode + tsk = self.create_task('dbus_binding_tool', node, node.change_ext('.h')) - task = self.create_task('dbus_binding_tool', env) - task.set_inputs(node) - task.set_outputs(node.change_ext('.h')) + tsk.env.DBUS_BINDING_TOOL_PREFIX = prefix + tsk.env.DBUS_BINDING_TOOL_MODE = mode Task.simple_task_type('dbus_binding_tool', '${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}', diff --git a/tools/wafadmin/Tools/gas.py b/tools/wafadmin/Tools/gas.py index 7484c8af091..89c1524f07c 100644 --- a/tools/wafadmin/Tools/gas.py +++ b/tools/wafadmin/Tools/gas.py @@ -16,12 +16,10 @@ Task.simple_task_type('asm', as_str, 'PINK', ext_out='.o', shell=False) @extension(EXT_ASM) def asm_hook(self, node): # create the compilation task: cpp or cc - task = self.create_task('asm') try: obj_ext = self.obj_ext except AttributeError: obj_ext = '_%d.o' % self.idx - task.inputs = [node] - task.outputs = [node.change_ext(obj_ext)] + task = self.create_task('asm', node, node.change_ext(obj_ext)) self.compiled_tasks.append(task) self.meths.append('asm_incflags') diff --git a/tools/wafadmin/Tools/gcc.py b/tools/wafadmin/Tools/gcc.py index 9e20d9b72ba..40a788e63f5 100644 --- a/tools/wafadmin/Tools/gcc.py +++ b/tools/wafadmin/Tools/gcc.py @@ -23,6 +23,10 @@ def gcc_common_flags(conf): # CPPFLAGS CCDEFINES _CCINCFLAGS _CCDEFFLAGS + v['CCFLAGS_DEBUG'] = ['-g'] + + v['CCFLAGS_RELEASE'] = ['-O2'] + v['CC_SRC_F'] = '' v['CC_TGT_F'] = ['-c', '-o', ''] # shell hack for -MD v['CPPPATH_ST'] = '-I%s' # template for adding include paths @@ -69,8 +73,18 @@ def gcc_modifier_win32(conf): v['shlib_PATTERN'] = '%s.dll' v['implib_PATTERN'] = 'lib%s.dll.a' v['IMPLIB_ST'] = '-Wl,--out-implib,%s' - v['shlib_CCFLAGS'] = ['-DPIC', '-DDLL_EXPORT'] # TODO 64-bit platforms may need -fPIC - v.append_value('LINKFLAGS', '-Wl,--enable-auto-import') # suppress information messages + + dest_arch = v['DEST_CPU'] + if dest_arch == 'x86': + # On 32-bit x86, gcc emits a message telling the -fPIC option is ignored on this arch, so we remove that flag. + v['shlib_CCFLAGS'] = ['-DPIC'] # TODO this is a wrong define, we don't use -fPIC! + + v.append_value('shlib_CCFLAGS', '-DDLL_EXPORT') # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea + + # Auto-import is enabled by default even without this option, + # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages + # that the linker emits otherwise. + v.append_value('LINKFLAGS', '-Wl,--enable-auto-import') @conftest def gcc_modifier_cygwin(conf): @@ -90,6 +104,7 @@ def gcc_modifier_darwin(conf): v['SHLIB_MARKER'] = '' v['STATICLIB_MARKER'] = '' + v['SONAME_ST'] = '' @conftest def gcc_modifier_aix(conf): @@ -118,4 +133,5 @@ def detect(conf): conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() + conf.link_add_flags() diff --git a/tools/wafadmin/Tools/glib2.py b/tools/wafadmin/Tools/glib2.py index a9dc4f0753e..042d612cbe4 100644 --- a/tools/wafadmin/Tools/glib2.py +++ b/tools/wafadmin/Tools/glib2.py @@ -29,10 +29,8 @@ def process_marshal(self): h_node = node.change_ext('.h') c_node = node.change_ext('.c') - task = self.create_task('glib_genmarshal') - task.set_inputs(node) - task.set_outputs([h_node, c_node]) - task.env['GLIB_GENMARSHAL_PREFIX'] = prefix + task = self.create_task('glib_genmarshal', node, [h_node, c_node]) + task.env.GLIB_GENMARSHAL_PREFIX = prefix self.allnodes.append(c_node) def genmarshal_func(self): @@ -52,7 +50,8 @@ def genmarshal_func(self): #print self.outputs[1].abspath(self.env) f = open(self.outputs[1].abspath(self.env), 'wb') - f.write('''#include "%s"\n''' % self.outputs[0].name) + c = '''#include "%s"\n''' % self.outputs[0].name + f.write(c) f.close() cmd2 = "%s %s --prefix=%s --body >> %s" % ( @@ -107,9 +106,9 @@ def add_enums(self, source='', target='', @before('apply_core') def process_enums(self): for enum in getattr(self, 'enums_list', []): - # temporary - env = self.env.copy() - task = self.create_task('glib_mkenums', env) + task = self.create_task('glib_mkenums') + env = task.env + inputs = [] # process the source @@ -154,10 +153,10 @@ def process_enums(self): task.set_outputs(tgt_node) Task.task_type_from_func('glib_genmarshal', func=genmarshal_func, vars=['GLIB_GENMARSHAL_PREFIX', 'GLIB_GENMARSHAL'], - color='BLUE', before='cc') + color='BLUE', before='cc cxx') Task.simple_task_type('glib_mkenums', '${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}', - color='PINK', before='cc') + color='PINK', before='cc cxx') def detect(conf): glib_genmarshal = conf.find_program('glib-genmarshal', var='GLIB_GENMARSHAL') diff --git a/tools/wafadmin/Tools/gnome.py b/tools/wafadmin/Tools/gnome.py index 77c810406ae..39aebd65cb7 100644 --- a/tools/wafadmin/Tools/gnome.py +++ b/tools/wafadmin/Tools/gnome.py @@ -112,9 +112,7 @@ def init_xml_to(self): def apply_xml_to(self): xmlfile = self.path.find_resource(self.source) xsltfile = self.path.find_resource(self.xslt) - tsk = self.create_task('xmlto') - tsk.set_inputs([xmlfile, xsltfile]) - tsk.set_outputs(xmlfile.change_ext('html')) + tsk = self.create_task('xmlto', [xmlfile, xsltfile], xmlfile.change_ext('html')) tsk.install_path = self.install_path def sgml_scan(self): diff --git a/tools/wafadmin/Tools/gnu_dirs.py b/tools/wafadmin/Tools/gnu_dirs.py index b4882127b04..3fc452d02dd 100644 --- a/tools/wafadmin/Tools/gnu_dirs.py +++ b/tools/wafadmin/Tools/gnu_dirs.py @@ -65,7 +65,7 @@ def detect(conf): env = conf.env env['EXEC_PREFIX'] = get_param('EXEC_PREFIX', env['PREFIX']) - env['PACKAGE'] = Utils.g_module.APPNAME or env['PACKAGE'] + env['PACKAGE'] = getattr(Utils.g_module, 'APPNAME', None) or env['PACKAGE'] complete = False iter = 0 diff --git a/tools/wafadmin/Tools/gxx.py b/tools/wafadmin/Tools/gxx.py index ccec9999d93..133e1164f3f 100644 --- a/tools/wafadmin/Tools/gxx.py +++ b/tools/wafadmin/Tools/gxx.py @@ -22,6 +22,8 @@ def gxx_common_flags(conf): v = conf.env # CPPFLAGS CXXDEFINES _CXXINCFLAGS _CXXDEFFLAGS + v['CXXFLAGS_DEBUG'] = ['-g'] + v['CXXFLAGS_RELEASE'] = ['-O2'] v['CXX_SRC_F'] = '' v['CXX_TGT_F'] = ['-c', '-o', ''] # shell hack for -MD @@ -69,7 +71,13 @@ def gxx_modifier_win32(conf): v['shlib_PATTERN'] = '%s.dll' v['implib_PATTERN'] = 'lib%s.dll.a' v['IMPLIB_ST'] = '-Wl,--out-implib,%s' - v['shlib_CXXFLAGS'] = ['-DPIC', '-DDLL_EXPORT'] # TODO 64-bit platforms may need -fPIC + + dest_arch = v['DEST_CPU'] + if dest_arch == 'x86': + # On 32-bit x86, gcc emits a message telling the -fPIC option is ignored on this arch, so we remove that flag. + v['shlib_CXXFLAGS'] = ['-DPIC'] # TODO this is a wrong define, we don't use -fPIC! + + v.append_value('shlib_CXXFLAGS', '-DDLL_EXPORT') # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea # Auto-import is enabled by default even without this option, # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages @@ -94,6 +102,7 @@ def gxx_modifier_darwin(conf): v['SHLIB_MARKER'] = '' v['STATICLIB_MARKER'] = '' + v['SONAME_ST'] = '' @conftest def gxx_modifier_aix(conf): diff --git a/tools/wafadmin/Tools/icc.py b/tools/wafadmin/Tools/icc.py index 56712a3df10..9c9a92602c7 100644 --- a/tools/wafadmin/Tools/icc.py +++ b/tools/wafadmin/Tools/icc.py @@ -33,4 +33,5 @@ gcc_common_flags gcc_modifier_platform cc_load_tools cc_add_flags +link_add_flags ''' diff --git a/tools/wafadmin/Tools/intltool.py b/tools/wafadmin/Tools/intltool.py index d47f8e114ac..27ab8c6d78e 100644 --- a/tools/wafadmin/Tools/intltool.py +++ b/tools/wafadmin/Tools/intltool.py @@ -42,10 +42,7 @@ def iapply_intltool_in_f(self): self.env['INTLPODIR'] = podirnode.srcpath(self.env) self.env['INTLFLAGS'] = getattr(self, 'flags', ['-q', '-u', '-c']) - task = self.create_task('intltool') - task.set_inputs(node) - task.set_outputs(node.change_ext('')) - + task = self.create_task('intltool', node, node.change_ext('')) task.install_path = self.install_path class intltool_po_taskgen(TaskGen.task_gen): diff --git a/tools/wafadmin/Tools/kde4.py b/tools/wafadmin/Tools/kde4.py index 7f7a78046dc..f480929da65 100644 --- a/tools/wafadmin/Tools/kde4.py +++ b/tools/wafadmin/Tools/kde4.py @@ -20,9 +20,7 @@ def init_msgfmt(self): def apply_msgfmt(self): for lang in self.to_list(self.langs): node = self.path.find_resource(lang+'.po') - task = self.create_task('msgfmt') - task.set_inputs(node) - task.set_outputs(node.change_ext('.mo')) + task = self.create_task('msgfmt', node, node.change_ext('.mo')) if not self.bld.is_install: continue langname = lang.split('/') diff --git a/tools/wafadmin/Tools/libtool.py b/tools/wafadmin/Tools/libtool.py index 69d027ea591..a9b56894cdb 100644 --- a/tools/wafadmin/Tools/libtool.py +++ b/tools/wafadmin/Tools/libtool.py @@ -68,10 +68,7 @@ def read_la_file(path): def apply_link_libtool(self): if self.type != 'program': linktask = self.link_task - latask = self.create_task('fakelibtool') - latask.set_inputs(linktask.outputs) - latask.set_outputs(linktask.outputs[0].change_ext('.la')) - self.latask = latask + self.latask = self.create_task('fakelibtool', linktask.outputs, linktask.outputs[0].change_ext('.la')) if self.bld.is_install: self.bld.install_files('${PREFIX}/lib', linktask.outputs[0], self.env) diff --git a/tools/wafadmin/Tools/misc.py b/tools/wafadmin/Tools/misc.py index f289133e89c..9e6a48f60fa 100644 --- a/tools/wafadmin/Tools/misc.py +++ b/tools/wafadmin/Tools/misc.py @@ -69,9 +69,7 @@ def apply_copy(self): # TODO the file path may be incorrect newnode = self.path.find_or_declare(target) - tsk = self.create_task('copy') - tsk.set_inputs(node) - tsk.set_outputs(newnode) + tsk = self.create_task('copy', node, newnode) tsk.fun = self.fun tsk.chmod = self.chmod @@ -141,9 +139,7 @@ def apply_subst(self): lst = [self.dict[x] for x in keys] self.env['DICT_HASH'] = str(Utils.h_list(lst)) - tsk = self.create_task('copy') - tsk.set_inputs(node) - tsk.set_outputs(newnode) + tsk = self.create_task('copy', node, newnode) tsk.fun = self.fun tsk.dict = self.dict tsk.dep_vars = ['DICT_HASH'] diff --git a/tools/wafadmin/Tools/msvc.py b/tools/wafadmin/Tools/msvc.py index 8f05516e638..6e382ceccef 100644 --- a/tools/wafadmin/Tools/msvc.py +++ b/tools/wafadmin/Tools/msvc.py @@ -443,6 +443,7 @@ cc_load_tools cxx_load_tools cc_add_flags cxx_add_flags +link_add_flags ''' @conftest @@ -536,7 +537,7 @@ def find_msvc(conf): def msvc_common_flags(conf): v = conf.env - v['CPPFLAGS'] = ['/W3', '/nologo', '/EHsc'] + v['CPPFLAGS'] = ['/W3', '/nologo'] v['CCDEFINES_ST'] = '/D%s' v['CXXDEFINES_ST'] = '/D%s' @@ -585,16 +586,15 @@ def msvc_common_flags(conf): v['CCFLAGS'] = ['/TC'] v['CCFLAGS_OPTIMIZED'] = ['/O2', '/DNDEBUG'] v['CCFLAGS_RELEASE'] = ['/O2', '/DNDEBUG'] - # TODO _DEBUG is defined by the compiler itself! - v['CCFLAGS_DEBUG'] = ['/Od', '/RTC1', '/D_DEBUG', '/ZI'] - v['CCFLAGS_ULTRADEBUG'] = ['/Od', '/RTC1', '/D_DEBUG', '/ZI'] + v['CCFLAGS_DEBUG'] = ['/Od', '/RTC1', '/ZI'] + v['CCFLAGS_ULTRADEBUG'] = ['/Od', '/RTC1', '/ZI'] - v['CXXFLAGS'] = ['/TP'] + v['CXXFLAGS'] = ['/TP', '/EHsc'] v['CXXFLAGS_OPTIMIZED'] = ['/O2', '/DNDEBUG'] v['CXXFLAGS_RELEASE'] = ['/O2', '/DNDEBUG'] - # TODO _DEBUG is defined by the compiler itself! - v['CXXFLAGS_DEBUG'] = ['/Od', '/RTC1', '/D_DEBUG', '/ZI'] - v['CXXFLAGS_ULTRADEBUG'] = ['/Od', '/RTC1', '/D_DEBUG', '/ZI'] + + v['CXXFLAGS_DEBUG'] = ['/Od', '/RTC1', '/ZI'] + v['CXXFLAGS_ULTRADEBUG'] = ['/Od', '/RTC1', '/ZI'] # linker v['LIB'] = [] @@ -604,7 +604,9 @@ def msvc_common_flags(conf): v['STATICLIB_ST'] = 'lib%s.lib' # Note: to be able to distinguish between a static lib and a dll import lib, it's a good pratice to name the static lib 'lib%s.lib' and the dll import lib '%s.lib' v['STATICLIBPATH_ST'] = '/LIBPATH:%s' - v['LINKFLAGS'] = ['/NOLOGO', '/MANIFEST'] + v['LINKFLAGS'] = ['/NOLOGO', '/MANIFEST'] + v['LINKFLAGS_DEBUG'] = ['/DEBUG'] + v['LINKFLAGS_ULTRADEBUG'] = ['/DEBUG'] # shared library v['shlib_CCFLAGS'] = [''] @@ -628,7 +630,7 @@ def msvc_common_flags(conf): @after('apply_link') @feature('cc', 'cxx') def apply_flags_msvc(self): - if self.env.CC_NAME != 'msvc': + if self.env.CC_NAME != 'msvc' or not self.link_task: return subsystem = getattr(self, 'subsystem', '') @@ -637,8 +639,9 @@ def apply_flags_msvc(self): flags = 'cstaticlib' in self.features and 'ARFLAGS' or 'LINKFLAGS' self.env.append_value(flags, subsystem) - if 'cstaticlib' not in self.features: - for d in (f.lower() for f in self.env.LINKFLAGS): + if getattr(self, 'link_task', None) and not 'cstaticlib' in self.features: + for f in self.env.LINKFLAGS: + d = f.lower() if d[1:] == 'debug': pdbnode = self.link_task.outputs[0].change_ext('.pdb') pdbfile = pdbnode.bldpath(self.env) @@ -768,7 +771,7 @@ def exec_command_msvc(self, *k, **kw): return self.generator.bld.exec_command(*k, **kw) -for k in 'cc cxx winrc cc_link cxx_link static_link'.split(): +for k in 'cc cxx winrc cc_link cxx_link static_link qxx'.split(): cls = Task.TaskBase.classes.get(k, None) if cls: cls.exec_command = exec_command_msvc diff --git a/tools/wafadmin/Tools/nasm.py b/tools/wafadmin/Tools/nasm.py index 9ee42a8255e..b99c3c73404 100644 --- a/tools/wafadmin/Tools/nasm.py +++ b/tools/wafadmin/Tools/nasm.py @@ -36,10 +36,7 @@ def nasm_file(self, node): try: obj_ext = self.obj_ext except AttributeError: obj_ext = '_%d.o' % self.idx - task = self.create_task('nasm') - task.inputs = [node] - task.outputs = [node.change_ext(obj_ext)] - + task = self.create_task('nasm', node, node.change_ext(obj_ext)) self.compiled_tasks.append(task) self.meths.append('apply_nasm_vars') diff --git a/tools/wafadmin/Tools/ocaml.py b/tools/wafadmin/Tools/ocaml.py index 2efd2c882df..20c926969a1 100644 --- a/tools/wafadmin/Tools/ocaml.py +++ b/tools/wafadmin/Tools/ocaml.py @@ -168,57 +168,42 @@ def apply_link_ml(self): @extension(EXT_MLL) def mll_hook(self, node): - mll_task = self.create_task('ocamllex', self.native_env) - mll_task.set_inputs(node) - mll_task.set_outputs(node.change_ext('.ml')) + mll_task = self.create_task('ocamllex', node, node.change_ext('.ml'), env=self.native_env) self.mlltasks.append(mll_task) self.allnodes.append(mll_task.outputs[0]) @extension(EXT_MLY) def mly_hook(self, node): - mly_task = self.create_task('ocamlyacc', self.native_env) - mly_task.set_inputs(node) - mly_task.set_outputs([node.change_ext('.ml'), node.change_ext('.mli')]) + mly_task = self.create_task('ocamlyacc', node, [node.change_ext('.ml'), node.change_ext('.mli')], env=self.native_env) self.mlytasks.append(mly_task) self.allnodes.append(mly_task.outputs[0]) - task = self.create_task('ocamlcmi', self.native_env) - task.set_inputs(mly_task.outputs[1]) - task.set_outputs(mly_task.outputs[1].change_ext('.cmi')) + task = self.create_task('ocamlcmi', mly_task.outputs[1], mly_task.outputs[1].change_ext('.cmi'), env=self.native_env) @extension(EXT_MLI) def mli_hook(self, node): - task = self.create_task('ocamlcmi', self.native_env) - task.set_inputs(node) - task.set_outputs(node.change_ext('.cmi')) + task = self.create_task('ocamlcmi', node, node.change_ext('.cmi'), env=self.native_env) self.mlitasks.append(task) @extension(EXT_MLC) def mlc_hook(self, node): - task = self.create_task('ocamlcc', self.native_env) - task.set_inputs(node) - task.set_outputs(node.change_ext('.o')) - + task = self.create_task('ocamlcc', node, node.change_ext('.o'), env=self.native_env) self.compiled_tasks.append(task) @extension(EXT_ML) def ml_hook(self, node): if self.native_env: - task = self.create_task('ocamlx', self.native_env) - task.set_inputs(node) - task.set_outputs(node.change_ext('.cmx')) + task = self.create_task('ocamlx', node, node.change_ext('.cmx'), env=self.native_env) task.obj = self task.incpaths = self.bld_incpaths_lst self.native_tasks.append(task) if self.bytecode_env: - task = self.create_task('ocaml', self.bytecode_env) - task.set_inputs(node) + task = self.create_task('ocaml', node, node.change_ext('.cmo'), env=self.bytecode_env) task.obj = self task.bytecode = 1 task.incpaths = self.bld_incpaths_lst - task.set_outputs(node.change_ext('.cmo')) self.bytecode_tasks.append(task) def compile_may_start(self): diff --git a/tools/wafadmin/Tools/osx.py b/tools/wafadmin/Tools/osx.py index 15a1ec96670..4f72b9b573e 100644 --- a/tools/wafadmin/Tools/osx.py +++ b/tools/wafadmin/Tools/osx.py @@ -89,7 +89,7 @@ def create_task_macapp(self): """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications or use obj.mac_app = True to build specific targets as Mac apps""" if self.env['MACAPP'] or getattr(self, 'mac_app', False): - apptask = self.create_task('macapp', self.env) + apptask = self.create_task('macapp') apptask.set_inputs(self.link_task.outputs) out = self.link_task.outputs[0] @@ -114,7 +114,7 @@ def create_task_macplist(self): if not getattr(self, 'mac_plist', False): self.mac_plist = app_info - plisttask = self.create_task('macplist', self.env) + plisttask = self.create_task('macplist') plisttask.set_inputs(self.link_task.outputs) out = self.link_task.outputs[0] diff --git a/tools/wafadmin/Tools/perl.py b/tools/wafadmin/Tools/perl.py index c41a588d7c3..9e3b12ac773 100644 --- a/tools/wafadmin/Tools/perl.py +++ b/tools/wafadmin/Tools/perl.py @@ -20,14 +20,11 @@ def init_perlext(self): @extension(EXT_XS) def xsubpp_file(self, node): - gentask = self.create_task('xsubpp') - gentask.set_inputs(node) outnode = node.change_ext('.c') - gentask.set_outputs(outnode) - + self.create_task('xsubpp', node, outnode) self.allnodes.append(outnode) -Task.simple_task_type('xsubpp', xsubpp_str, color='BLUE', before="cc cxx", shell=False) +Task.simple_task_type('xsubpp', xsubpp_str, color='BLUE', before='cc cxx', shell=False) @conf def check_perl_version(conf, minver=None): diff --git a/tools/wafadmin/Tools/python.py b/tools/wafadmin/Tools/python.py index 641fa116b61..b3f925126a8 100644 --- a/tools/wafadmin/Tools/python.py +++ b/tools/wafadmin/Tools/python.py @@ -159,7 +159,8 @@ def check_python_headers(conf): env = conf.env python = env['PYTHON'] - assert python, ("python is %r !" % (python,)) + if not python: + conf.fatal('could not find the python executable') ## On Mac OSX we need to use mac bundles for python plugins if Options.platform == 'darwin': @@ -309,7 +310,8 @@ def check_python_version(conf, minver=None): """ assert minver is None or isinstance(minver, tuple) python = conf.env['PYTHON'] - assert python, ("python is %r !" % (python,)) + if not python: + conf.fatal('could not find the python executable') # Get python version string cmd = [python, "-c", "import sys\nfor x in sys.version_info: print(str(x))"] @@ -361,7 +363,7 @@ def check_python_version(conf, minver=None): conf.check_message('Python version', ">= %s" % (minver_str,), result, option=pyver_full) if not result: - conf.fatal("Python too old.") + conf.fatal('The python version is too old (%r)' % minver) @conf def check_python_module(conf, module_name): @@ -372,11 +374,16 @@ def check_python_module(conf, module_name): stderr=Utils.pproc.PIPE, stdout=Utils.pproc.PIPE).wait() conf.check_message('Python module', module_name, result) if not result: - conf.fatal("Python module not found.") + conf.fatal('Could not find the python module %r' % module_name) def detect(conf): + + if not conf.env.PYTHON: + conf.env.PYTHON = sys.executable + python = conf.find_program('python', var='PYTHON') - if not python: return + if not python: + conf.fatal('Could not find the path of the python executable') v = conf.env diff --git a/tools/wafadmin/Tools/qt4.py b/tools/wafadmin/Tools/qt4.py index dce270335ca..669e6d755f3 100644 --- a/tools/wafadmin/Tools/qt4.py +++ b/tools/wafadmin/Tools/qt4.py @@ -197,7 +197,6 @@ def scan(self): names = [] root = self.inputs[0].parent for x in curHandler.files: - x = x.encode('utf8') nd = root.find_resource(x) if nd: nodes.append(nd) else: names.append(x) @@ -207,25 +206,16 @@ def scan(self): @extension(EXT_RCC) def create_rcc_task(self, node): "hook for rcc files" - rcnode = node.change_ext('_rc.cpp') - - rcctask = self.create_task('rcc') - rcctask.inputs = [node] - rcctask.outputs = [rcnode] - - cpptask = self.create_task('cxx') - cpptask.inputs = [rcnode] - cpptask.outputs = [rcnode.change_ext('.o')] + rcctask = self.create_task('rcc', node, rcnode) + cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) self.compiled_tasks.append(cpptask) - return cpptask @extension(EXT_UI) def create_uic_task(self, node): "hook for uic tasks" - uictask = self.create_task('ui4') - uictask.inputs = [node] + uictask = self.create_task('ui4', node) uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])] class qt4_taskgen(cxx.cxx_taskgen): @@ -250,9 +240,7 @@ def apply_qt4(self): if not isinstance(l, Node.Node): l = self.path.find_resource(l+'.ts') - t = self.create_task('ts2qm') - t.set_inputs(l) - t.set_outputs(l.change_ext('.qm')) + t = self.create_task('ts2qm', l, l.change_ext('.qm')) lst.append(t.outputs[0]) if update: @@ -283,13 +271,11 @@ def apply_qt4(self): @extension(EXT_QT4) def cxx_hook(self, node): # create the compilation task: cpp or cc - task = self.create_task('qxx') - self.compiled_tasks.append(task) try: obj_ext = self.obj_ext except AttributeError: obj_ext = '_%d.o' % self.idx - task.inputs = [node] - task.outputs = [node.change_ext(obj_ext)] + task = self.create_task('qxx', node, node.change_ext(obj_ext)) + self.compiled_tasks.append(task) def process_qm2rcc(task): outfile = task.outputs[0].abspath(task.env) @@ -393,45 +379,6 @@ def detect_qt4(conf): vars = "QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtWebKit Qt3Support".split() - framework_ok = False - if sys.platform == "darwin" and useframework: - for i in vars: - e = conf.create_framework_configurator() - e.path = [qtlibs, '/Library/Frameworks'] - e.name = i - e.remove_dot_h = True - e.run() - - if not i == 'QtCore': - # strip -F flag so it don't get reduant - for r in env['CCFLAGS_' + i.upper()]: - if r.startswith('-F'): - env['CCFLAGS_' + i.upper()].remove(r) - break - -# incflag = '-I%s' % os.path.join(qtincludes, i) -# if not incflag in env["CCFLAGS_" + i.upper ()]: -# env['CCFLAGS_' + i.upper ()] += [incflag] -# if not incflag in env["CXXFLAGS_" + i.upper ()]: -# env['CXXFLAGS_' + i.upper ()] += [incflag] - - # now we add some static depends. - if conf.is_defined('HAVE_QTOPENGL'): - env.append_unique('FRAMEWORK_QTOPENGL', 'OpenGL') - - if conf.is_defined('HAVE_QTGUI'): - env.append_unique('FRAMEWORK_QTGUI', ['AppKit', 'ApplicationServices']) - - framework_ok = True - - # check for the qt includes first - if not conf.is_defined("HAVE_QTGUI"): - if not qtincludes: qtincludes = os.path.join(qtdir, 'include') - env.QTINCLUDEPATH = qtincludes - - lst = [qtincludes, '/usr/share/qt4/include/', '/opt/qt4/include'] - conf.check(header_name='QtGui/QFont', define_name='HAVE_QTGUI', mandatory=1, includes=lst) - find_bin(['uic-qt3', 'uic3'], 'QT_UIC3') find_bin(['uic-qt4', 'uic'], 'QT_UIC') if not env['QT_UIC']: @@ -460,52 +407,51 @@ def detect_qt4(conf): env['ui_PATTERN'] = 'ui_%s.h' env['QT_LRELEASE_FLAGS'] = ['-silent'] - if not framework_ok: # framework_ok is false either when the platform isn't OSX, Qt4 shall not be used as framework, or Qt4 could not be found as framework - vars_debug = [a+'_debug' for a in vars] + vars_debug = [a+'_debug' for a in vars] - pkgconfig = env['pkg-config'] or 'PKG_CONFIG_PATH=%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib pkg-config --silence-errors' % (qtlibs, qtlibs) - for i in vars_debug+vars: - try: - conf.check_cfg(package=i, args='--cflags --libs', path=pkgconfig) - except ValueError: - pass + pkgconfig = env['pkg-config'] or 'PKG_CONFIG_PATH=%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib pkg-config --silence-errors' % (qtlibs, qtlibs) + for i in vars_debug+vars: + try: + conf.check_cfg(package=i, args='--cflags --libs', path=pkgconfig) + except ValueError: + pass - # the libpaths are set nicely, unfortunately they make really long command-lines - # remove the qtcore ones from qtgui, etc - def process_lib(vars_, coreval): + # the libpaths are set nicely, unfortunately they make really long command-lines + # remove the qtcore ones from qtgui, etc + def process_lib(vars_, coreval): + for d in vars_: + var = d.upper() + if var == 'QTCORE': continue + + value = env['LIBPATH_'+var] + if value: + core = env[coreval] + accu = [] + for lib in value: + if lib in core: continue + accu.append(lib) + env['LIBPATH_'+var] = accu + + process_lib(vars, 'LIBPATH_QTCORE') + process_lib(vars_debug, 'LIBPATH_QTCORE_DEBUG') + + # rpath if wanted + if Options.options.want_rpath: + def process_rpath(vars_, coreval): for d in vars_: var = d.upper() - if var == 'QTCORE': continue - value = env['LIBPATH_'+var] if value: core = env[coreval] accu = [] for lib in value: - if lib in core: continue - accu.append(lib) - env['LIBPATH_'+var] = accu - - process_lib(vars, 'LIBPATH_QTCORE') - process_lib(vars_debug, 'LIBPATH_QTCORE_DEBUG') - - # rpath if wanted - if Options.options.want_rpath: - def process_rpath(vars_, coreval): - for d in vars_: - var = d.upper() - value = env['LIBPATH_'+var] - if value: - core = env[coreval] - accu = [] - for lib in value: - if var != 'QTCORE': - if lib in core: - continue - accu.append('-Wl,--rpath='+lib) - env['RPATH_'+var] = accu - process_rpath(vars, 'LIBPATH_QTCORE') - process_rpath(vars_debug, 'LIBPATH_QTCORE_DEBUG') + if var != 'QTCORE': + if lib in core: + continue + accu.append('-Wl,--rpath='+lib) + env['RPATH_'+var] = accu + process_rpath(vars, 'LIBPATH_QTCORE') + process_rpath(vars_debug, 'LIBPATH_QTCORE_DEBUG') env['QTLOCALE'] = str(env['PREFIX'])+'/share/locale' diff --git a/tools/wafadmin/Tools/suncc.py b/tools/wafadmin/Tools/suncc.py index 8f79315a5b8..0aa430556c8 100644 --- a/tools/wafadmin/Tools/suncc.py +++ b/tools/wafadmin/Tools/suncc.py @@ -71,5 +71,6 @@ find_ar scc_common_flags cc_load_tools cc_add_flags +link_add_flags ''' diff --git a/tools/wafadmin/Tools/tex.py b/tools/wafadmin/Tools/tex.py index dd8ec2afa8b..424667ce228 100644 --- a/tools/wafadmin/Tools/tex.py +++ b/tools/wafadmin/Tools/tex.py @@ -176,13 +176,9 @@ def apply_tex(self): if not node: raise Utils.WafError('cannot find %s' % filename) if self.type == 'latex': - task = self.create_task('latex') - task.set_inputs(node) - task.set_outputs(node.change_ext('.dvi')) + task = self.create_task('latex', node, node.change_ext('.dvi')) elif self.type == 'pdflatex': - task = self.create_task('pdflatex') - task.set_inputs(node) - task.set_outputs(node.change_ext('.pdf')) + task = self.create_task('pdflatex', node, node.change_ext('.pdf')) task.env = self.env task.curdirnode = self.path @@ -200,18 +196,12 @@ def apply_tex(self): if self.type == 'latex': if 'ps' in outs: - pstask = self.create_task('dvips') - pstask.set_inputs(task.outputs) - pstask.set_outputs(node.change_ext('.ps')) + self.create_task('dvips', task.outputs, node.change_ext('.ps')) if 'pdf' in outs: - pdftask = self.create_task('dvipdf') - pdftask.set_inputs(task.outputs) - pdftask.set_outputs(node.change_ext('.pdf')) + self.create_task('dvipdf', task.outputs, node.change_ext('.pdf')) elif self.type == 'pdflatex': if 'ps' in outs: - pstask = self.create_task('pdf2ps') - pstask.set_inputs(task.outputs) - pstask.set_outputs(node.change_ext('.ps')) + self.create_task('pdf2ps', task.outputs, node.change_ext('.ps')) self.source = [] def detect(conf): diff --git a/tools/wafadmin/Tools/vala.py b/tools/wafadmin/Tools/vala.py index 31f91a42d25..43b802c33e6 100644 --- a/tools/wafadmin/Tools/vala.py +++ b/tools/wafadmin/Tools/vala.py @@ -114,10 +114,8 @@ class valac_task(Task.Task): api_version = version[0] + ".0" install_path = '${INCLUDEDIR}/%s-%s/%s' % (package, api_version, header.relpath_gen(top_src)) bld.install_as(install_path, header, self.env) - for vapi in vapi_list: - bld.install_files('${DATAROOTDIR}/vala/vapi', vapi, self.env) - for gir in gir_list: - bld.install_files('${DATAROOTDIR}/gir-1.0', gir, self.env) + bld.install_files('${DATAROOTDIR}/vala/vapi', vapi_list, self.env) + bld.install_files('${DATAROOTDIR}/gir-1.0', gir_list, self.env) def _fix_output(self, output): top_bld = self.generator.bld.srcnode.abspath(self.env) diff --git a/tools/wafadmin/Tools/winres.py b/tools/wafadmin/Tools/winres.py index e0148cb1677..2500d431de9 100644 --- a/tools/wafadmin/Tools/winres.py +++ b/tools/wafadmin/Tools/winres.py @@ -18,11 +18,7 @@ def rc_file(self, node): obj_ext = '.rc.o' if self.env['WINRC_TGT_F'] == '/fo': obj_ext = '.res' - rctask = self.create_task('winrc') - rctask.set_inputs(node) - rctask.set_outputs(node.change_ext(obj_ext)) - - # make linker can find compiled resource files + rctask = self.create_task('winrc', node, node.change_ext(obj_ext)) self.compiled_tasks.append(rctask) # create our action, for use with rc file diff --git a/tools/wafadmin/Utils.py b/tools/wafadmin/Utils.py index 2223b834f6f..698eab78030 100644 --- a/tools/wafadmin/Utils.py +++ b/tools/wafadmin/Utils.py @@ -46,6 +46,13 @@ else: import Logs from Constants import * +try: + from collections import deque +except ImportError: + class deque(list): + def popleft(self): + return self.pop(0) + is_win32 = sys.platform == 'win32' try: @@ -67,7 +74,10 @@ except ImportError: class WafError(Exception): def __init__(self, *args): self.args = args - self.stack = traceback.extract_stack() + try: + self.stack = traceback.extract_stack() + except: + pass Exception.__init__(self, *args) def __str__(self): return str(len(self.args) == 1 and self.args[0] or self.args) @@ -78,7 +88,10 @@ class WscriptError(WafError): self.wscript_file = wscript_file self.wscript_line = None else: - (self.wscript_file, self.wscript_line) = self.locate_error() + try: + (self.wscript_file, self.wscript_line) = self.locate_error() + except: + (self.wscript_file, self.wscript_line) = (None, None) msg_file_line = '' if self.wscript_file: @@ -124,7 +137,6 @@ except ImportError: def h_file(filename): f = open(filename, 'rb') m = md5() - readBytes = 100000 while (filename): filename = f.read(100000) m.update(filename) @@ -171,10 +183,12 @@ if is_win32: try: if 'stdout' not in kw: kw['stdout'] = pproc.PIPE - kw['stderr'] = pproc.STDOUT + kw['stderr'] = pproc.PIPE proc = pproc.Popen(s,**kw) - (stdout, _) = proc.communicate() + (stdout, stderr) = proc.communicate() Logs.info(stdout) + if stderr: + Logs.error(stderr) else: proc = pproc.Popen(s,**kw) return proc.wait() @@ -252,8 +266,11 @@ def load_module(file_path, name=WSCRIPT_FILE): sys.path.insert(0, module_dir) try: exec(code, module.__dict__) - except Exception: - raise WscriptError(traceback.format_exc(), file_path) + except Exception, e: + try: + raise WscriptError(traceback.format_exc(), file_path) + except: + raise e sys.path.remove(module_dir) g_loaded_modules[file_path] = module @@ -347,14 +364,10 @@ def def_attrs(cls, **kw): if not hasattr(cls, k): setattr(cls, k, v) -quote_define_name_table = None def quote_define_name(path): - "Converts a string to a constant name, foo/zbr-xpto.h -> FOO_ZBR_XPTO_H" - global quote_define_name_table - if not quote_define_name_table: - invalid_chars = set([chr(x) for x in xrange(256)]) - set(string.digits + string.uppercase) - quote_define_name_table = string.maketrans(''.join(invalid_chars), '_'*len(invalid_chars)) - return string.translate(string.upper(path), quote_define_name_table) + fu = re.compile("[^a-zA-Z0-9]").sub("_", path) + fu = fu.upper() + return fu def quote_whitespace(path): return (path.strip().find(' ') > 0 and '"%s"' % path or path).replace('""', '"') @@ -524,12 +537,11 @@ def load_tool(tool, tooldir=None): def readf(fname, m='r'): "get the contents of a file, it is not used anywhere for the moment" - f = None + f = open(fname, m) try: - f = open(fname, m) txt = f.read() finally: - if f: f.close() + f.close() return txt def nada(*k, **kw): @@ -610,8 +622,11 @@ class Context(object): try: try: exec(txt, dc) - except Exception: - raise WscriptError(traceback.format_exc(), base) + except Exception, e: + try: + raise WscriptError(traceback.format_exc(), base) + except: + raise e finally: self.curdir = old if getattr(self.__class__, 'post_recurse', None): diff --git a/tools/wafadmin/ansiterm.py b/tools/wafadmin/ansiterm.py new file mode 100644 index 00000000000..2372df9e4c5 --- /dev/null +++ b/tools/wafadmin/ansiterm.py @@ -0,0 +1,202 @@ +import sys, os +try: + from ctypes import * + + class COORD(Structure): + _fields_ = [("X", c_short), ("Y", c_short)] + + class SMALL_RECT(Structure): + _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)] + + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_short), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)] + + sbinfo = CONSOLE_SCREEN_BUFFER_INFO() + hconsole = windll.kernel32.GetStdHandle(-11) + windll.kernel32.GetConsoleScreenBufferInfo(hconsole, byref(sbinfo)) +except Exception: + pass +else: + import re + + to_int = lambda number, default: number and int(number) or default + + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + + class AnsiTerm(object): + def __init__(self): + self.hconsole = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) + self.cursor_history = [] + + def screen_buffer_info(self): + sbinfo = CONSOLE_SCREEN_BUFFER_INFO() + windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(sbinfo)) + return sbinfo + + def clear_line(self, param): + mode = param and int(param) or 0 + sbinfo = self.screen_buffer_info() + if mode == 1: # Clear from begining of line to cursor position + line_start = COORD(0, sbinfo.CursorPosition.Y) + line_length = sbinfo.Size.X + elif mode == 2: # Clear entire line + line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y) + line_length = sbinfo.Size.X - sbinfo.CursorPosition.X + else: # Clear from cursor position to end of line + line_start = sbinfo.CursorPosition + line_length = sbinfo.Size.X - sbinfo.CursorPosition.X + chars_written = c_int() + windll.kernel32.FillConsoleOutputCharacterA(self.hconsole, c_char(' '), line_length, line_start, byref(chars_written)) + windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written)) + + def clear_screen(self, param): + mode = to_int(param, 0) + sbinfo = self.screen_buffer_info() + if mode == 1: # Clear from begining of screen to cursor position + clear_start = COORD(0, 0) + clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y + elif mode == 2: # Clear entire screen and return cursor to home + clear_start = COORD(0, 0) + clear_length = sbinfo.Size.X * sbinfo.Size.Y + windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start) + else: # Clear from cursor position to end of screen + clear_start = sbinfo.CursorPosition + clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y)) + chars_written = c_int() + windll.kernel32.FillConsoleOutputCharacterA(self.hconsole, c_char(' '), clear_length, clear_start, byref(chars_written)) + windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written)) + + def push_cursor(self, param): + sbinfo = self.screen_buffer_info() + self.cursor_history.push(sbinfo.CursorPosition) + + def pop_cursor(self, param): + if self.cursor_history: + old_pos = self.cursor_history.pop() + windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos) + + def set_cursor(self, param): + x, sep, y = param.partition(';') + x = to_int(x, 1) - 1 + y = to_int(y, 1) - 1 + sbinfo = self.screen_buffer_info() + new_pos = COORD( + min(max(0, x), sbinfo.Size.X), + min(max(0, y), sbinfo.Size.Y) + ) + windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) + + def set_column(self, param): + x = to_int(param, 1) - 1 + sbinfo = self.screen_buffer_info() + new_pos = COORD( + min(max(0, x), sbinfo.Size.X), + sbinfo.CursorPosition.Y + ) + windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) + + def move_cursor(self, x_offset=0, y_offset=0): + sbinfo = self.screen_buffer_info() + new_pos = COORD( + min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X), + min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y) + ) + windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) + + def move_up(self, param): + self.move_cursor(y_offset = -to_int(param, 1)) + + def move_down(self, param): + self.move_cursor(y_offset = to_int(param, 1)) + + def move_left(self, param): + self.move_cursor(x_offset = -to_int(param, 1)) + + def move_right(self, param): + self.move_cursor(x_offset = to_int(param, 1)) + + def next_line(self, param): + sbinfo = self.screen_buffer_info() + self.move_cursor( + x_offset = -sbinfo.CursorPosition.X, + y_offset = to_int(param, 1) + ) + + def prev_line(self, param): + sbinfo = self.screen_buffer_info() + self.move_cursor( + x_offset = -sbinfo.CursorPosition.X, + y_offset = -to_int(param, 1) + ) + + escape_to_color = { (0, 30): 0x0, #black + (0, 31): 0x4, #red + (0, 32): 0x2, #green + (0, 33): 0x4+0x2, #dark yellow + (0, 34): 0x1, #blue + (0, 35): 0x1+0x4, #purple + (0, 36): 0x2+0x4, #cyan + (0, 37): 0x1+0x2+0x4, #grey + (1, 30): 0x1+0x2+0x4, #dark gray + (1, 31): 0x4+0x8, #red + (1, 32): 0x2+0x8, #light green + (1, 33): 0x4+0x2+0x8, #yellow + (1, 34): 0x1+0x8, #light blue + (1, 35): 0x1+0x4+0x8, #light purple + (1, 36): 0x1+0x2+0x8, #light cyan + (1, 37): 0x1+0x2+0x4+0x8, #white + } + + def set_color(self, param): + intensity, sep, color = param.partition(';') + intensity = to_int(intensity, 0) + color = to_int(color, 0) + if intensity and not color: + color, intensity = intensity, color + attrib = self.escape_to_color.get((intensity, color), 0x7) + windll.kernel32.SetConsoleTextAttribute(self.hconsole, attrib) + + ansi_command_table = { + 'A': move_up, + 'B': move_down, + 'C': move_right, + 'D': move_left, + 'E': next_line, + 'F': prev_line, + 'G': set_column, + 'H': set_cursor, + 'f': set_cursor, + 'J': clear_screen, + 'K': clear_line, + 'm': set_color, + 's': push_cursor, + 'u': pop_cursor, + } + # Match either the escape sequence or text not containing escape sequence + ansi_tokans = re.compile('(?:\x1b\[([0-9;]*)([a-zA-Z])|([^\x1b]+))') + def write(self, text): + for param, cmd, txt in self.ansi_tokans.findall(text): + if cmd: + cmd_func = self.ansi_command_table.get(cmd) + if cmd_func: + cmd_func(self, param) + else: + chars_written = c_int() + if isinstance(txt, unicode): + windll.kernel32.WriteConsoleW(self.hconsole, txt, len(txt), byref(chars_written), None) + else: + windll.kernel32.WriteConsoleA(self.hconsole, txt, len(txt), byref(chars_written), None) + + + def flush(self): + pass + + def isatty(self): + return True + + sys.stderr = sys.stdout = AnsiTerm() + os.environ['TERM'] = 'vt100' + diff --git a/tools/wafadmin/py3kfixes.py b/tools/wafadmin/py3kfixes.py index 252dd994bfc..ca08b36f467 100644 --- a/tools/wafadmin/py3kfixes.py +++ b/tools/wafadmin/py3kfixes.py @@ -12,10 +12,14 @@ all_modifs = {} def modif(dir, name, fun): if name == '*': - lst = os.listdir(dir) + ['Tools' + os.sep + x for x in os.listdir(os.path.join(dir, 'Tools'))] + lst = [] + for y in '. Tools 3rdparty'.split(): + for x in os.listdir(os.path.join(dir, y)): + if x.endswith('.py'): + lst.append(y + os.sep + x) + #lst = [y + os.sep + x for x in os.listdir(os.path.join(dir, y)) for y in '. Tools 3rdparty'.split() if x.endswith('.py')] for x in lst: - if x.endswith('.py'): - modif(dir, x, fun) + modif(dir, x, fun) return filename = os.path.join(dir, name) @@ -48,12 +52,13 @@ def r1(code): @subst('Tools/ccroot.py') def r2(code): code = code.replace("p.stdin.write('\\n')", "p.stdin.write(b'\\n')") - code = code.replace("out=str(out)", "out=out.decode('utf-8')") + code = code.replace('p.communicate()[0]', 'p.communicate()[0].decode("utf-8")') return code @subst('Utils.py') def r3(code): code = code.replace("m.update(str(lst))", "m.update(str(lst).encode())") + code = code.replace('p.communicate()[0]', 'p.communicate()[0].decode("utf-8")') return code @subst('Task.py') @@ -87,9 +92,21 @@ def r7(code): code = code.replace('class task_gen(object):\n\t__metaclass__=register_obj', 'class task_gen(object, metaclass=register_obj):') return code +@subst('Tools/config_c.py') +def r8(code): + code = code.replace('p.communicate()[0]', 'p.communicate()[0].decode("utf-8")') + return code + +@subst('Tools/glib2.py') +def r9(code): + code = code.replace('f.write(c)', 'f.write(c.encode("utf-8"))') + return code + + def fixdir(dir): global all_modifs for k in all_modifs: for v in all_modifs[k]: modif(os.path.join(dir, 'wafadmin'), k, v) #print('substitutions finished') + |