diff --git a/.gitignore b/.gitignore index 6a5db6aff2..f54a7ef593 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ build demos/*/build* playground/*/build* .waf-* +.waf3-* *.log .DS_Store .AppleDouble diff --git a/playground/compress/optim.py b/playground/compress/optim.py index f61627329c..e318cef0b7 100755 --- a/playground/compress/optim.py +++ b/playground/compress/optim.py @@ -43,20 +43,20 @@ def compare(a, b): LEN = len(lst) POP = 3*LEN + 1 - popul = [range(LEN) for x in xrange(POP)] - fitn = [0 for x in xrange(POP)] + popul = [range(LEN) for x in range(POP)] + fitn = [0 for x in range(POP)] def rnd(): return random.randint(0, LEN -1) def mutate(): - for x in xrange(LEN): + for x in range(LEN): # rotate the previous element by one v = popul[x+LEN] = popul[x+LEN - 1] a = v.pop(0) v.append(a) - for x in xrange(LEN): + for x in range(LEN): # swap elements a = rnd() b = rnd() @@ -66,7 +66,7 @@ def mutate(): v[a] = v[b] v[b] = c - for x in xrange(LEN): + for x in range(LEN): # get one element out, add at the end v = popul[x+2*LEN] @@ -79,7 +79,7 @@ def evil(): best = opti_ref pos = -1 - for x in xrange(len(popul)): + for x in range(len(popul)): v = popul[x] arr = [lst[a] for a in v] tmp = '%s %s' % (cmd, ' '.join(arr)) @@ -99,14 +99,14 @@ def evil(): assert (sum(popul[x]) == sum(range(LEN))) #print pos - for x in xrange(len(popul)): + for x in range(len(popul)): if x == pos: continue popul[x] = popul[pos][:] assert(len(popul[x]) == LEN) return best - for i in xrange(10000): + for i in range(10000): mutate() print(evil()) diff --git a/waf-light b/waf-light index 29040b2160..d895b5be85 100755 --- a/waf-light +++ b/waf-light @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="2.0.8" +VERSION="2.0.9" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Build.py b/waflib/Build.py index 8347a287a8..772c66f60c 100644 --- a/waflib/Build.py +++ b/waflib/Build.py @@ -645,7 +645,7 @@ def add_group(self, name=None, move=True): :raises: :py:class:`waflib.Errors.WafError` if a group by the name given already exists """ if name and name in self.group_names: - raise Errors.WafError('add_group: name %s already present', name) + raise Errors.WafError('add_group: name %s already present' % name) g = [] self.group_names[name] = g self.groups.append(g) diff --git a/waflib/ConfigSet.py b/waflib/ConfigSet.py index b300bb56b7..84736c9c87 100644 --- a/waflib/ConfigSet.py +++ b/waflib/ConfigSet.py @@ -312,7 +312,7 @@ def load(self, filename): :type filename: string """ tbl = self.table - code = Utils.readf(filename, m='rU') + code = Utils.readf(filename, m='r') for m in re_imp.finditer(code): g = m.group tbl[g(2)] = eval(g(3)) diff --git a/waflib/Context.py b/waflib/Context.py index 3222fb1551..204d2a3051 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x2000800 +HEXVERSION=0x2000900 """Constant updated on new releases""" -WAFVERSION="2.0.8" +WAFVERSION="2.0.9" """Constant updated on new releases""" -WAFREVISION="f78fbc32bb355a3291c9b5f79bbe0c8dfe81282a" +WAFREVISION="8a950e7bca9a3a9b1ae62aae039ef76e2adc4177" """Git revision when the waf version is updated""" ABI = 20 @@ -662,7 +662,7 @@ def load_module(path, encoding=None): module = imp.new_module(WSCRIPT_FILE) try: - code = Utils.readf(path, m='rU', encoding=encoding) + code = Utils.readf(path, m='r', encoding=encoding) except EnvironmentError: raise Errors.WafError('Could not read the file %r' % path) diff --git a/waflib/Node.py b/waflib/Node.py index 4ac1ea8a0b..237d75e463 100644 --- a/waflib/Node.py +++ b/waflib/Node.py @@ -554,6 +554,17 @@ def abspath(self): self.cache_abspath = val return val + def relpath(self): + """ + Returns the relative path. This is used in place of abspath() to keep paths short + for environments like cygwin where path lengths to file operations are severely limited + (for example, when cross-compiling for arm-none-eabi on cygwin) + + :rtype: string + """ + return os.path.relpath(self.abspath()) + + def is_child_of(self, node): """ Returns whether the object belongs to a subtree of the input node:: diff --git a/waflib/Task.py b/waflib/Task.py index ffe7b16ead..c358ce4796 100644 --- a/waflib/Task.py +++ b/waflib/Task.py @@ -266,6 +266,16 @@ def split_argfile(self, cmd): """ return ([cmd[0]], [self.quote_flag(x) for x in cmd[1:]]) + def should_split(self, cmd): + """return True if this command needs splitting for argument length""" + if isinstance(cmd, str): + return False + if Utils.is_win32 and len(repr(cmd)) >= 8192: + return True + if sys.platform.startswith("cygwin") and len(repr(cmd)) > 20000: + return True + return len(repr(cmd)) > 200000 + def exec_command(self, cmd, **kw): """ Wrapper for :py:meth:`waflib.Context.Context.exec_command`. @@ -302,15 +312,15 @@ def exec_command(self, cmd, **kw): # workaround for command line length limit: # http://support.microsoft.com/kb/830473 - if not isinstance(cmd, str) and (len(repr(cmd)) >= 8192 if Utils.is_win32 else len(cmd) > 200000): + if self.should_split(cmd): cmd, args = self.split_argfile(cmd) try: (fd, tmp) = tempfile.mkstemp() - os.write(fd, '\r\n'.join(args).encode()) + os.write(fd, '\r\n'.join(args[1:]).encode()) os.close(fd) if Logs.verbose: Logs.debug('argfile: @%r -> %r', tmp, args) - return self.generator.bld.exec_command(cmd + ['@' + tmp], **kw) + return self.generator.bld.exec_command(cmd + args[:1] + ['@' + tmp], **kw) finally: try: os.remove(tmp) @@ -446,10 +456,15 @@ def format_error(self): elif not self.hasrun: return 'task in %r was not executed for some reason: %r' % (name, self) elif self.hasrun == CRASHED: + if isinstance(msg, str): + txt = msg + else: + txt = ' '.join(repr(x) if ' ' in x else x for x in msg) + try: - return ' -> task in %r failed with exit status %r%s' % (name, self.err_code, msg) + return ' -> task in %r failed (exit status %r): %r\n%s' % (name, self.err_code, self, txt) except AttributeError: - return ' -> task in %r failed%s' % (name, msg) + return ' -> task in %r failed: %r\n%s' % (name, self, txt) elif self.hasrun == MISSING: return ' -> missing files in %r%s' % (name, msg) elif self.hasrun == CANCELED: diff --git a/waflib/Tools/c.py b/waflib/Tools/c.py index effd6b6ee8..be7c746d71 100644 --- a/waflib/Tools/c.py +++ b/waflib/Tools/c.py @@ -17,14 +17,14 @@ def c_hook(self, node): class c(Task.Task): "Compiles C files into object files" - run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' + run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].relpath()} ${CPPFLAGS}' vars = ['CCDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan class cprogram(link_task): "Links object files into c programs" - run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' + run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].relpath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' ext_out = ['.bin'] vars = ['LINKDEPS'] inst_to = '${BINDIR}' diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 76082152cd..41b53ae7b2 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1011,7 +1011,7 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): cmd = cc + ['-dM', '-E', '-'] env = conf.env.env or None try: - out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) + out, err = conf.cmd_and_log(cmd, output=0, stdin=open('/dev/null','r'), env=env) except Errors.WafError: conf.fatal('Could not determine the compiler version %r' % cmd) diff --git a/waflib/Tools/cxx.py b/waflib/Tools/cxx.py index 194fad7437..705ec74d06 100644 --- a/waflib/Tools/cxx.py +++ b/waflib/Tools/cxx.py @@ -18,14 +18,14 @@ def cxx_hook(self, node): class cxx(Task.Task): "Compiles C++ files into object files" - run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' + run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].relpath()} ${CPPFLAGS}' vars = ['CXXDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan class cxxprogram(link_task): "Links object files into c++ programs" - run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' + run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].relpath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' vars = ['LINKDEPS'] ext_out = ['.bin'] inst_to = '${BINDIR}' diff --git a/waflib/Tools/gcc.py b/waflib/Tools/gcc.py index acdd473ada..2bda5f5242 100644 --- a/waflib/Tools/gcc.py +++ b/waflib/Tools/gcc.py @@ -76,7 +76,10 @@ def gcc_modifier_win32(conf): # 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']) + import sys + if sys.platform != "cygwin": + # disabled on cygwin as it breaks build with arm cross compiler + v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def gcc_modifier_cygwin(conf): diff --git a/waflib/Tools/gxx.py b/waflib/Tools/gxx.py index 22c5d26f2a..2667258197 100644 --- a/waflib/Tools/gxx.py +++ b/waflib/Tools/gxx.py @@ -76,7 +76,10 @@ def gxx_modifier_win32(conf): # 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']) + import sys + if sys.platform != "cygwin": + # disabled on cygwin as it breaks build with arm cross compiler + v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def gxx_modifier_cygwin(conf): diff --git a/waflib/Utils.py b/waflib/Utils.py index b4665c4dc2..05e5ad1ef2 100644 --- a/waflib/Utils.py +++ b/waflib/Utils.py @@ -51,8 +51,14 @@ class TimeoutExpired(Exception): try: from md5 import md5 except ImportError: - # never fail to enable fixes from another module + # never fail to enable potential fixes from another module pass +else: + try: + md5().digest() + except ValueError: + # Fips? #2213 + from hashlib import sha1 as md5 try: import threading diff --git a/waflib/extras/gccdeps.py b/waflib/extras/gccdeps.py index d9758ab34d..0dd07fd039 100644 --- a/waflib/extras/gccdeps.py +++ b/waflib/extras/gccdeps.py @@ -141,7 +141,7 @@ def post_run(self): node = path_to_node(path, x, cached_nodes) if not node: - raise ValueError('could not find %r for %r' % (x, self)) + continue if id(node) == id(self.inputs[0]): # ignore the source file, it is already in the dependencies # this way, successful config tests may be retrieved from the cache diff --git a/wscript b/wscript index 3158f58dae..e3567ef179 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ To add a tool that does not exist in the folder compat15, pass an absolute path: from __future__ import with_statement -VERSION="2.0.8" +VERSION="2.0.9" APPNAME='waf' REVISION=''