Browse Source

Update to waf 1.8.17.

tags/v1.9.11-RC1
Karl Linden 9 years ago
parent
commit
bb8e749736
No known key found for this signature in database GPG Key ID: 764C09795C812B97
32 changed files with 306 additions and 141 deletions
  1. +1
    -0
      .wafupdaterc
  2. +1
    -1
      waf
  3. +12
    -13
      waflib/Build.py
  4. +7
    -13
      waflib/Configure.py
  5. +8
    -4
      waflib/Context.py
  6. +8
    -3
      waflib/Logs.py
  7. +67
    -7
      waflib/Node.py
  8. +1
    -1
      waflib/Options.py
  9. +7
    -0
      waflib/Runner.py
  10. +8
    -4
      waflib/Scripting.py
  11. +37
    -18
      waflib/Task.py
  12. +27
    -10
      waflib/TaskGen.py
  13. +3
    -4
      waflib/Tools/c_aliases.py
  14. +24
    -12
      waflib/Tools/c_config.py
  15. +4
    -5
      waflib/Tools/c_osx.py
  16. +0
    -1
      waflib/Tools/c_tests.py
  17. +6
    -3
      waflib/Tools/ccroot.py
  18. +0
    -1
      waflib/Tools/clang.py
  19. +0
    -1
      waflib/Tools/clangxx.py
  20. +2
    -2
      waflib/Tools/compiler_c.py
  21. +2
    -2
      waflib/Tools/compiler_cxx.py
  22. +4
    -1
      waflib/Tools/errcheck.py
  23. +0
    -2
      waflib/Tools/gcc.py
  24. +0
    -2
      waflib/Tools/gxx.py
  25. +1
    -1
      waflib/Tools/icc.py
  26. +1
    -1
      waflib/Tools/icpc.py
  27. +0
    -2
      waflib/Tools/irixcc.py
  28. +22
    -21
      waflib/Tools/msvc.py
  29. +46
    -1
      waflib/Utils.py
  30. +7
    -3
      waflib/extras/build_logs.py
  31. +0
    -1
      waflib/extras/c_bgxlc.py
  32. +0
    -1
      waflib/extras/c_nec.py

+ 1
- 0
.wafupdaterc View File

@@ -134,4 +134,5 @@ WAFLIB_STRIP_EXTRAS="
why
win32_opts
xcode
xcode6
"

+ 1
- 1
waf View File

@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.

import os, sys, inspect

VERSION="1.8.14"
VERSION="1.8.17"
REVISION="x"
GIT="x"
INSTALL="x"


+ 12
- 13
waflib/Build.py View File

@@ -44,6 +44,10 @@ POST_LAZY = 1
POST_BOTH = 2
"""Post mode: post the task generators at once, then re-check them for each group"""

PROTOCOL = -1
if sys.platform == 'cli':
PROTOCOL = 0

class BuildContext(Context.Context):
'''executes the build'''

@@ -322,7 +326,7 @@ class BuildContext(Context.Context):
try:
waflib.Node.pickle_lock.acquire()
waflib.Node.Nod3 = self.node_class
x = cPickle.dumps(data, -1)
x = cPickle.dumps(data, PROTOCOL)
finally:
waflib.Node.pickle_lock.release()

@@ -821,17 +825,10 @@ class inst(Task.Task):
else:
y = self.path.find_resource(x)
if not y:
if Logs.verbose:
Logs.warn('Could not find %s immediately (may cause broken builds)' % x)
idx = self.generator.bld.get_group_idx(self)
for tg in self.generator.bld.groups[idx]:
if not isinstance(tg, inst) and id(tg) != id(self):
tg.post()
y = self.path.find_resource(x)
if y:
break
if os.path.isabs(x):
y = self.bld.root.make_node(x)
else:
raise Errors.WafError('Could not find %r in %r' % (x, self.path))
y = self.path.make_node(x)
buf.append(y)
self.inputs = buf

@@ -1039,6 +1036,7 @@ class InstallContext(BuildContext):
:param postpone: execute the task immediately to perform the installation
:type postpone: bool
"""
assert(dest)
tsk = inst(env=env or self.env)
tsk.bld = self
tsk.path = cwd or self.path
@@ -1075,6 +1073,7 @@ class InstallContext(BuildContext):
:param postpone: execute the task immediately to perform the installation
:type postpone: bool
"""
assert(dest)
tsk = inst(env=env or self.env)
tsk.bld = self
tsk.path = cwd or self.path
@@ -1107,11 +1106,11 @@ class InstallContext(BuildContext):
:param relative_trick: make the symlink relative (default: ``False``)
:type relative_trick: bool
"""

if Utils.is_win32:
# symlinks *cannot* work on that platform
# TODO waf 1.9 - replace by install_as
return
assert(dest)
tsk = inst(env=env or self.env)
tsk.bld = self
tsk.dest = dest


+ 7
- 13
waflib/Configure.py View File

@@ -151,14 +151,8 @@ class ConfigurationContext(Context.Context):
if ver:
app = "%s (%s)" % (app, ver)

now = time.ctime()
pyver = sys.hexversion
systype = sys.platform
args = " ".join(sys.argv)
wafver = Context.WAFVERSION
abi = Context.ABI
self.to_log(conf_template % vars())

params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app}
self.to_log(conf_template % params)
self.msg('Setting top to', self.srcnode.abspath())
self.msg('Setting out to', self.bldnode.abspath())

@@ -208,17 +202,17 @@ class ConfigurationContext(Context.Context):
"""
if not env.PREFIX:
if Options.options.prefix or Utils.is_win32:
env.PREFIX = os.path.abspath(os.path.expanduser(Options.options.prefix))
env.PREFIX = Utils.sane_path(Options.options.prefix)
else:
env.PREFIX = ''
if not env.BINDIR:
if Options.options.bindir:
env.BINDIR = os.path.abspath(os.path.expanduser(Options.options.bindir))
env.BINDIR = Utils.sane_path(Options.options.bindir)
else:
env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env)
if not env.LIBDIR:
if Options.options.libdir:
env.LIBDIR = os.path.abspath(os.path.expanduser(Options.options.libdir))
env.LIBDIR = Utils.sane_path(Options.options.libdir)
else:
env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env)

@@ -347,6 +341,7 @@ def conf(f):
if mandatory:
raise

fun.__name__ = f.__name__
setattr(ConfigurationContext, f.__name__, fun)
setattr(Build.BuildContext, f.__name__, fun)
return f
@@ -422,7 +417,7 @@ def find_file(self, filename, path_list=[]):
"""
for n in Utils.to_list(filename):
for d in Utils.to_list(path_list):
p = os.path.join(d, n)
p = os.path.expanduser(os.path.join(d, n))
if os.path.exists(p):
return p
self.fatal('Could not find %r' % filename)
@@ -529,7 +524,6 @@ def find_binary(self, filenames, exts, paths):
return x
return None


@conf
def run_build(self, *k, **kw):
"""


+ 8
- 4
waflib/Context.py View File

@@ -11,13 +11,13 @@ from waflib import Utils, Errors, Logs
import waflib.Node

# the following 3 constants are updated on each new release (do not touch)
HEXVERSION=0x1080e00
HEXVERSION=0x1081100
"""Constant updated on new releases"""

WAFVERSION="1.8.14"
WAFVERSION="1.8.17"
"""Constant updated on new releases"""

WAFREVISION="ce8234c396bb246a20ea9f51594ee051d5b378e7"
WAFREVISION="cd7579a727d1b390bf9cbf111c1b20e811370bc0"
"""Git revision when the waf version is updated"""

ABI = 98
@@ -307,6 +307,10 @@ class Context(ctx):
elif not node:
if not mandatory:
continue
try:
os.listdir(d)
except OSError:
raise Errors.WafError('Cannot read the folder %r' % d)
raise Errors.WafError('No wscript file in directory %s' % d)

def exec_command(self, cmd, **kw):
@@ -610,7 +614,7 @@ class Context(ctx):
doban = False
for b in ban:
r = b.replace("*", ".*")
if re.match(b, f):
if re.match(r, f):
doban = True
if not doban:
f = f.replace('.py', '')


+ 8
- 3
waflib/Logs.py View File

@@ -6,7 +6,7 @@
logging, colors, terminal width and pretty-print
"""

import os, re, traceback, sys, types
import os, re, traceback, sys
from waflib import Utils, ansiterm

if not os.environ.get('NOSYNC', False):
@@ -43,6 +43,11 @@ colors_lst = {

indicator = '\r\x1b[K%s%s%s'

try:
unicode
except NameError:
unicode = None

def enable_colors(use):
if use == 1:
if not (sys.stderr.isatty() or sys.stdout.isatty()):
@@ -150,7 +155,7 @@ class log_handler(logging.StreamHandler):
def emit_override(self, record, **kw):
self.terminator = getattr(record, 'terminator', '\n')
stream = self.stream
if hasattr(types, "UnicodeType"):
if unicode:
# python2
msg = self.formatter.format(record)
fs = '%s' + self.terminator
@@ -316,7 +321,7 @@ def free_logger(logger):
for x in logger.handlers:
x.close()
logger.removeHandler(x)
except Exception as e:
except Exception:
pass

def pprint(col, msg, label='', sep='\n'):


+ 67
- 7
waflib/Node.py View File

@@ -59,14 +59,11 @@ Ant patterns for files and folders to exclude while doing the
recursive traversal in :py:meth:`waflib.Node.Node.ant_glob`
"""

# TODO waf 1.9
split_path = Utils.split_path_unix
# TODO remove in waf 1.9
split_path = Utils.split_path
split_path_unix = Utils.split_path_unix
split_path_cygwin = Utils.split_path_cygwin
split_path_win32 = Utils.split_path_win32
if sys.platform == 'cygwin':
split_path = split_path_cygwin
elif Utils.is_win32:
split_path = split_path_win32

class Node(object):
"""
@@ -152,6 +149,69 @@ class Node(object):
"""
Utils.writef(self.abspath(), data, flags, encoding)

def read_json(self, convert=True, encoding='utf-8'):
"""
Read and parse the contents of this node as JSON::

def build(bld):
bld.path.find_node('abc.json').read_json()

Note that this by default automatically decodes unicode strings on Python2, unlike what the Python JSON module does.

:type convert: boolean
:param convert: Prevents decoding of unicode strings on Python2
:type encoding: string
:param encoding: The encoding of the file to read. This default to UTF8 as per the JSON standard
:rtype: object
:return: Parsed file contents
"""
import json # Python 2.6 and up
object_pairs_hook = None
if convert and sys.hexversion < 0x3000000:
try:
_type = unicode
except NameError:
_type = str

def convert(value):
if isinstance(value, list):
return [convert(element) for element in value]
elif isinstance(value, _type):
return str(value)
else:
return value

def object_pairs(pairs):
return dict((str(pair[0]), convert(pair[1])) for pair in pairs)

object_pairs_hook = object_pairs

return json.loads(self.read(encoding=encoding), object_pairs_hook=object_pairs_hook)

def write_json(self, data, pretty=True):
"""
Writes a python object as JSON to disk. Files are always written as UTF8 as per the JSON standard::

def build(bld):
bld.path.find_node('xyz.json').write_json(199)

:type data: object
:param data: The data to write to disk
:type pretty: boolean
:param pretty: Determines if the JSON will be nicely space separated
"""
import json # Python 2.6 and up
indent = 2
separators = (',', ': ')
sort_keys = pretty
newline = os.linesep
if not pretty:
indent = None
separators = (',', ':')
newline = ''
output = json.dumps(data, indent=indent, separators=separators, sort_keys=sort_keys) + newline
self.write(output, encoding='utf-8')

def chmod(self, val):
"""
Change file/dir permissions::
@@ -251,7 +311,7 @@ class Node(object):
cur.children = self.dict_class()
else:
try:
cur = cur.children[x]
cur = ch[x]
continue
except KeyError:
pass


+ 1
- 1
waflib/Options.py View File

@@ -256,7 +256,7 @@ class OptionsContext(Context.Context):
commands.append(arg)

if options.destdir:
options.destdir = os.path.abspath(os.path.expanduser(options.destdir))
options.destdir = Utils.sane_path(options.destdir)

if options.verbose >= 1:
self.load('errcheck')


+ 7
- 0
waflib/Runner.py View File

@@ -278,6 +278,13 @@ class Parallel(object):
:param tsk: task
:type tsk: :py:attr:`waflib.Task.TaskBase`
"""
if hasattr(tsk, 'scan') and hasattr(tsk, 'uid'):
# TODO waf 1.9 - this breaks encapsulation
key = (tsk.uid(), 'imp')
try:
del self.bld.task_sigs[key]
except KeyError:
pass
if not self.bld.keep:
self.stop = True
self.error.append(tsk)


+ 8
- 4
waflib/Scripting.py View File

@@ -46,6 +46,7 @@ def waf_entry_point(current_directory, version, wafdir):
# perhaps extract 'wscript' as a constant
if os.path.basename(potential_wscript) == 'wscript' 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))
sys.argv.pop(1)

@@ -62,11 +63,14 @@ def waf_entry_point(current_directory, version, wafdir):
break

# if --top is provided assume the build started in the top directory
for x in sys.argv:
for i, x in enumerate(sys.argv):
# WARNING: this modifies sys.argv
if x.startswith('--top='):
Context.run_dir = Context.top_dir = x[6:]
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 = x[6:]
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
@@ -137,7 +141,7 @@ def waf_entry_point(current_directory, version, wafdir):
sys.exit(1)

try:
set_main_module(os.path.join(Context.run_dir, Context.WSCRIPT_FILE))
set_main_module(os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE)))
except Errors.WafError as e:
Logs.pprint('RED', e.verbose_msg)
Logs.error(str(e))


+ 37
- 18
waflib/Task.py View File

@@ -37,11 +37,14 @@ SKIP_ME = -2
RUN_ME = -3
"""The task must be executed"""

# To save some memory during the build, consider discarding tsk.last_cmd in the two templates below

COMPILE_TEMPLATE_SHELL = '''
def f(tsk):
env = tsk.env
gen = tsk.generator
bld = gen.bld
cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9
wd = getattr(tsk, 'cwd', None)
p = env.get_flat
tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
@@ -53,6 +56,7 @@ def f(tsk):
env = tsk.env
gen = tsk.generator
bld = gen.bld
cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9
wd = getattr(tsk, 'cwd', None)
def to_list(xx):
if isinstance(xx, str): return [xx]
@@ -81,11 +85,10 @@ class store_task_type(type):
name = name.replace('_task', '')
if name != 'evil' and name != 'TaskBase':
global classes

if getattr(cls, 'run_str', None):
# if a string is provided, convert it to a method
(f, dvars) = compile_fun(cls.run_str, cls.shell)
cls.hcode = cls.run_str
cls.hcode = Utils.h_cmd(cls.run_str)
cls.orig_run_str = cls.run_str
# change the name of run_str or it is impossible to subclass with a function
cls.run_str = None
@@ -94,10 +97,7 @@ class store_task_type(type):
cls.vars.sort()
elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__:
# getattr(cls, 'hcode') would look in the upper classes
cls.hcode = Utils.h_fun(cls.run)

if sys.hexversion > 0x3000000:
cls.hcode = cls.hcode.encode('iso8859-1', 'xmlcharrefreplace')
cls.hcode = Utils.h_cmd(cls.run)

# be creative
getattr(cls, 'register', classes)[name] = cls
@@ -206,6 +206,7 @@ class TaskBase(evil):
# remove the task signature immediately before it is executed
# in case of failure the task will be executed again
try:
# TODO waf 1.9 - this breaks encapsulation
del self.generator.bld.task_sigs[self.uid()]
except KeyError:
pass
@@ -972,17 +973,17 @@ def compile_fun_shell(line):
for (var, meth) in extr:
if var == 'SRC':
if meth: app('tsk.inputs%s' % meth)
else: app('" ".join([a.path_from(bld.bldnode) for a in tsk.inputs])')
else: app('" ".join([a.path_from(cwdx) for a in tsk.inputs])')
elif var == 'TGT':
if meth: app('tsk.outputs%s' % meth)
else: app('" ".join([a.path_from(bld.bldnode) for a in tsk.outputs])')
else: app('" ".join([a.path_from(cwdx) for a in tsk.outputs])')
elif meth:
if meth.startswith(':'):
m = meth[1:]
if m == 'SRC':
m = '[a.path_from(bld.bldnode) for a in tsk.inputs]'
m = '[a.path_from(cwdx) for a in tsk.inputs]'
elif m == 'TGT':
m = '[a.path_from(bld.bldnode) for a in tsk.outputs]'
m = '[a.path_from(cwdx) for a in tsk.outputs]'
elif m[:3] not in ('tsk', 'gen', 'bld'):
dvars.extend([var, meth[1:]])
m = '%r' % m
@@ -1027,17 +1028,17 @@ def compile_fun_noshell(line):
(var, meth) = extr[x]
if var == 'SRC':
if meth: app('lst.append(tsk.inputs%s)' % meth)
else: app("lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])")
else: app("lst.extend([a.path_from(cwdx) for a in tsk.inputs])")
elif var == 'TGT':
if meth: app('lst.append(tsk.outputs%s)' % meth)
else: app("lst.extend([a.path_from(bld.bldnode) for a in tsk.outputs])")
else: app("lst.extend([a.path_from(cwdx) for a in tsk.outputs])")
elif meth:
if meth.startswith(':'):
m = meth[1:]
if m == 'SRC':
m = '[a.path_from(bld.bldnode) for a in tsk.inputs]'
m = '[a.path_from(cwdx) for a in tsk.inputs]'
elif m == 'TGT':
m = '[a.path_from(bld.bldnode) for a in tsk.outputs]'
m = '[a.path_from(cwdx) for a in tsk.outputs]'
elif m[:3] not in ('tsk', 'gen', 'bld'):
dvars.extend([var, m])
m = '%r' % m
@@ -1074,9 +1075,27 @@ def compile_fun(line, shell=False):
The reserved keywords *TGT* and *SRC* represent the task input and output nodes

"""
if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0:
shell = True

if isinstance(line, str):
if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0:
shell = True
else:
dvars_lst = []
funs_lst = []
for x in line:
if isinstance(x, str):
fun, dvars = compile_fun(x, shell)
dvars_lst += dvars
funs_lst.append(fun)
else:
# assume a function to let through
funs_lst.append(x)
def composed_fun(task):
for x in funs_lst:
ret = x(task)
if ret:
return ret
return None
return composed_fun, dvars
if shell:
return compile_fun_shell(line)
else:
@@ -1111,7 +1130,7 @@ def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[
'scan': scan,
}

if isinstance(func, str):
if isinstance(func, str) or isinstance(func, tuple):
params['run_str'] = func
else:
params['run'] = func


+ 27
- 10
waflib/TaskGen.py View File

@@ -564,7 +564,15 @@ def process_rule(self):
except KeyError:
pass
if not cls:
cls = Task.task_factory(name, self.rule,

rule = self.rule
if hasattr(self, 'chmod'):
def chmod_fun(tsk):
for x in tsk.outputs:
os.chmod(x.abspath(), self.chmod)
rule = (self.rule, chmod_fun)

cls = Task.task_factory(name, rule,
getattr(self, 'vars', []),
shell=getattr(self, 'shell', True), color=getattr(self, 'color', 'BLUE'),
scan = getattr(self, 'scan', None))
@@ -614,7 +622,7 @@ def process_rule(self):
x.parent.mkdir() # if a node was given, create the required folders
tsk.outputs.append(x)
if getattr(self, 'install_path', None):
self.bld.install_files(self.install_path, tsk.outputs)
self.bld.install_files(self.install_path, tsk.outputs, chmod=getattr(self, 'chmod', Utils.O644))

if getattr(self, 'source', None):
tsk.inputs = self.to_nodes(self.source)
@@ -669,24 +677,34 @@ class subst_pc(Task.Task):
in the substitution changes.
"""

def force_permissions(self):
"Private for the time being, we will probably refactor this into run_str=[run1,chmod]"
if getattr(self.generator, 'chmod', None):
for x in self.outputs:
os.chmod(x.abspath(), self.generator.chmod)

def run(self):
"Substitutes variables in a .in file"

if getattr(self.generator, 'is_copy', None):
self.outputs[0].write(self.inputs[0].read('rb'), 'wb')
if getattr(self.generator, 'chmod', None):
os.chmod(self.outputs[0].abspath(), self.generator.chmod)
for i, x in enumerate(self.outputs):
x.write(self.inputs[i].read('rb'), 'wb')
self.force_permissions()
return None

if getattr(self.generator, 'fun', None):
return self.generator.fun(self)
ret = self.generator.fun(self)
if not ret:
self.force_permissions()
return ret

code = self.inputs[0].read(encoding=getattr(self.generator, 'encoding', 'ISO8859-1'))
if getattr(self.generator, 'subst_fun', None):
code = self.generator.subst_fun(self, code)
if code is not None:
self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'ISO8859-1'))
return
self.force_permissions()
return None

# replace all % by %% to prevent errors by % signs
code = code.replace('%', '%%')
@@ -722,8 +740,7 @@ class subst_pc(Task.Task):
try: delattr(self, 'cache_sig')
except AttributeError: pass

if getattr(self.generator, 'chmod', None):
os.chmod(self.outputs[0].abspath(), self.generator.chmod)
self.force_permissions()

def sig_vars(self):
"""
@@ -816,7 +833,7 @@ def process_subst(self):
b = y

if not a:
raise Errors.WafError('cound not find %r for %r' % (x, self))
raise Errors.WafError('could not find %r for %r' % (x, self))

has_constraints = False
tsk = self.create_task('subst', a, b)


+ 3
- 4
waflib/Tools/c_aliases.py View File

@@ -4,8 +4,7 @@

"base for all c/c++ programs and libraries"

import os, sys, re
from waflib import Utils, Build, Errors
from waflib import Utils, Errors
from waflib.Configure import conf

def get_extensions(lst):
@@ -49,7 +48,7 @@ def sniff_features(**kw):
feats.append('cxx')
break

if 'c' in exts or 'vala' in exts:
if 'c' in exts or 'vala' in exts or 'gs' in exts:
feats.append('c')

for x in 'f f90 F F90 for FOR'.split():
@@ -71,7 +70,7 @@ def sniff_features(**kw):
feats.append(x + type)
will_link = True
if not will_link and not kw.get('features', []):
raise Errors.WafError('Cannot link from %r, try passing eg: features="cprogram"?' % kw)
raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?' % kw)
return feats

def set_features(kw, _type):


+ 24
- 12
waflib/Tools/c_config.py View File

@@ -6,7 +6,7 @@
C/C++/D configuration helpers
"""

import os, re, shlex, sys
import os, re, shlex
from waflib import Build, Utils, Task, Options, Logs, Errors, Runner
from waflib.TaskGen import after_method, feature
from waflib.Configure import conf
@@ -288,11 +288,11 @@ def exec_cfg(self, kw):
"""

path = Utils.to_list(kw['path'])
env = self.env.env or None
def define_it():
pkgname = kw.get('uselib_store', kw['package'].upper())
if kw.get('global_define'):
# compatibility
# compatibility, replace by pkgname in WAF 1.9?
self.define(self.have_define(kw['package']), 1, False)
else:
self.env.append_unique('DEFINES_%s' % pkgname, "%s=1" % self.have_define(pkgname))
@@ -301,7 +301,7 @@ def exec_cfg(self, kw):
# pkg-config version
if 'atleast_pkgconfig_version' in kw:
cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']]
self.cmd_and_log(cmd)
self.cmd_and_log(cmd, env=env)
if not 'okmsg' in kw:
kw['okmsg'] = 'yes'
return
@@ -310,7 +310,7 @@ def exec_cfg(self, kw):
for x in cfg_ver:
y = x.replace('-', '_')
if y in kw:
self.cmd_and_log(path + ['--%s=%s' % (x, kw[y]), kw['package']])
self.cmd_and_log(path + ['--%s=%s' % (x, kw[y]), kw['package']], env=env)
if not 'okmsg' in kw:
kw['okmsg'] = 'yes'
define_it()
@@ -318,7 +318,7 @@ def exec_cfg(self, kw):

# retrieving the version of a module
if 'modversion' in kw:
version = self.cmd_and_log(path + ['--modversion', kw['modversion']]).strip()
version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip()
self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version)
return version

@@ -342,19 +342,19 @@ def exec_cfg(self, kw):

# retrieving variables of a module
if 'variables' in kw:
env = kw.get('env', self.env)
v = kw.get('env', self.env)
uselib = kw.get('uselib_store', kw['package'].upper())
vars = Utils.to_list(kw['variables'])
for v in vars:
val = self.cmd_and_log(lst + ['--variable=' + v]).strip()
val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip()
var = '%s_%s' % (uselib, v)
env[var] = val
v[var] = val
if not 'okmsg' in kw:
kw['okmsg'] = 'yes'
return

# so we assume the command-line will output flags to be parsed afterwards
ret = self.cmd_and_log(lst)
ret = self.cmd_and_log(lst, env=env)
if not 'okmsg' in kw:
kw['okmsg'] = 'yes'

@@ -482,7 +482,10 @@ def validate_c(self, kw):
kw['type'] = 'cprogram'

if not 'features' in kw:
kw['features'] = [kw['compile_mode'], kw['type']] # "cprogram c"
if not 'header_name' in kw or kw.get('link_header_test', True):
kw['features'] = [kw['compile_mode'], kw['type']] # "c ccprogram"
else:
kw['features'] = [kw['compile_mode']]
else:
kw['features'] = Utils.to_list(kw['features'])

@@ -604,6 +607,11 @@ def validate_c(self, kw):
if self.env[INCKEYS]:
kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code']

# in case defines lead to very long command-lines
if kw.get('merge_config_header', False) or env.merge_config_header:
kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code'])
env.DEFINES = [] # modify the copy

if not kw.get('success'): kw['success'] = None

if 'define_name' in kw:
@@ -626,7 +634,7 @@ def post_check(self, *k, **kw):
is_success = (kw['success'] == 0)

if 'define_name' in kw:
# TODO simplify?
# TODO simplify!
if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw:
if kw['execute'] and kw.get('define_ret', None) and isinstance(is_success, str):
self.define(kw['define_name'], is_success, quote=kw.get('quote', 1))
@@ -635,6 +643,10 @@ def post_check(self, *k, **kw):
else:
self.define_cond(kw['define_name'], is_success)

# consistency with check_cfg
if kw.get('global_define', None):
self.env[kw['define_name']] = is_success

if 'header_name' in kw:
if kw.get('auto_add_header_name', False):
self.env.append_value(INCKEYS, Utils.to_list(kw['header_name']))


+ 4
- 5
waflib/Tools/c_osx.py View File

@@ -6,8 +6,8 @@
MacOSX related tools
"""

import os, shutil, sys, platform
from waflib import TaskGen, Task, Build, Options, Utils, Errors
import os, shutil, platform
from waflib import Task, Utils, Errors
from waflib.TaskGen import taskgen_method, feature, after_method, before_method

app_info = '''
@@ -48,7 +48,6 @@ def create_bundle_dirs(self, name, out):
"""
Create bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp`
"""
bld = self.bld
dir = out.parent.find_or_declare(name)
dir.mkdir()
macos = dir.find_or_declare(['Contents', 'MacOS'])
@@ -102,7 +101,7 @@ def create_task_macapp(self):
inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name
for node in self.to_nodes(self.mac_files):
relpath = node.path_from(mac_files_root or node.parent)
tsk = self.create_task('macapp', node, res_dir.make_node(relpath))
self.create_task('macapp', node, res_dir.make_node(relpath))
self.bld.install_as(os.path.join(inst_to, relpath), node)

if getattr(self, 'mac_resources', None):
@@ -121,7 +120,7 @@ def create_task_macapp(self):
nodes = [node]
for node in nodes:
rel = node.path_from(parent)
tsk = self.create_task('macapp', node, res_dir.make_node(rel))
self.create_task('macapp', node, res_dir.make_node(rel))
self.bld.install_as(inst_to + '/%s' % rel, node)

if getattr(self.bld, 'is_install', None):


+ 0
- 1
waflib/Tools/c_tests.py View File

@@ -9,7 +9,6 @@ Various configuration tests.
from waflib import Task
from waflib.Configure import conf
from waflib.TaskGen import feature, before_method, after_method
import sys

LIB_CODE = '''
#ifdef _MSC_VER


+ 6
- 3
waflib/Tools/ccroot.py View File

@@ -25,8 +25,8 @@ USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS
USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS'])
USELIB_VARS['includes'] = set(['INCLUDES', 'FRAMEWORKPATH', 'ARCH'])

USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH'])
USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH'])
USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS'])
USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS'])
USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS'])

USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS'])
@@ -158,7 +158,10 @@ class link_task(Task.Task):
if len(nums) >= 2:
pattern += '.%s' % nums[1]

tmp = folder + os.sep + pattern % name
if folder:
tmp = folder + os.sep + pattern % name
else:
tmp = pattern % name
target = self.generator.path.find_or_declare(tmp)
self.set_outputs(target)



+ 0
- 1
waflib/Tools/clang.py View File

@@ -6,7 +6,6 @@
Detect the Clang C compiler
"""

import os, sys
from waflib.Tools import ccroot, ar, gcc
from waflib.Configure import conf



+ 0
- 1
waflib/Tools/clangxx.py View File

@@ -6,7 +6,6 @@
Detect the Clang++ C++ compiler
"""

import os, sys
from waflib.Tools import ccroot, ar, gxx
from waflib.Configure import conf



+ 2
- 2
waflib/Tools/compiler_c.py View File

@@ -30,9 +30,9 @@ Not all compilers need to have a specific tool. For example, the clang compilers
$ CC=clang waf configure
"""

import os, sys, imp, types, re
import re
from waflib.Tools import ccroot
from waflib import Utils, Configure
from waflib import Utils
from waflib.Logs import debug

c_compiler = {


+ 2
- 2
waflib/Tools/compiler_cxx.py View File

@@ -31,9 +31,9 @@ Not all compilers need to have a specific tool. For example, the clang compilers
"""


import os, sys, imp, types, re
import re
from waflib.Tools import ccroot
from waflib import Utils, Configure
from waflib import Utils
from waflib.Logs import debug

cxx_compiler = {


+ 4
- 1
waflib/Tools/errcheck.py View File

@@ -22,6 +22,7 @@ typos = {

meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects']

import sys
from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils
import waflib.Tools.ccroot

@@ -84,6 +85,9 @@ def check_invalid_constraints(self):

# the build scripts have been read, so we can check for invalid after/before attributes on task classes
for cls in list(Task.classes.values()):
if sys.hexversion > 0x3000000 and issubclass(cls, Task.Task) and isinstance(cls.hcode, str):
raise Errors.WafError('Class %r has hcode value %r of type <str>, expecting <bytes> (use Utils.h_cmd() ?)' % (cls, cls.hcode))

for x in ('before', 'after'):
for y in Utils.to_list(getattr(cls, x, [])):
if not Task.classes.get(y, None):
@@ -103,7 +107,6 @@ def replace(m):
if x in kw:
if x == 'iscopy' and 'subst' in getattr(self, 'features', ''):
continue
err = True
Logs.error('Fix the typo %r -> %r on %r' % (x, typos[x], ret))
return ret
setattr(Build.BuildContext, m, call)


+ 0
- 2
waflib/Tools/gcc.py View File

@@ -8,8 +8,6 @@
gcc/llvm detection.
"""

import os, sys
from waflib import Configure, Options, Utils
from waflib.Tools import ccroot, ar
from waflib.Configure import conf



+ 0
- 2
waflib/Tools/gxx.py View File

@@ -8,8 +8,6 @@
g++/llvm detection.
"""

import os, sys
from waflib import Configure, Options, Utils
from waflib.Tools import ccroot, ar
from waflib.Configure import conf



+ 1
- 1
waflib/Tools/icc.py View File

@@ -7,7 +7,7 @@
Detect the Intel C compiler
"""

import os, sys
import sys
from waflib.Tools import ccroot, ar, gcc
from waflib.Configure import conf



+ 1
- 1
waflib/Tools/icpc.py View File

@@ -6,7 +6,7 @@
Detect the Intel C++ compiler
"""

import os, sys
import sys
from waflib.Tools import ccroot, ar, gxx
from waflib.Configure import conf



+ 0
- 2
waflib/Tools/irixcc.py View File

@@ -6,8 +6,6 @@ compiler definition for irix/MIPSpro cc compiler
based on suncc.py from waf
"""

import os
from waflib import Utils
from waflib.Tools import ccroot, ar
from waflib.Configure import conf



+ 22
- 21
waflib/Tools/msvc.py View File

@@ -194,10 +194,14 @@ echo LIB=%%LIB%%;%%LIBPATH%%
try:
try:
conf.cmd_and_log(cxx + ['/help'], env=env)
except UnicodeError:
st = Utils.ex_stack()
if conf.logger:
conf.logger.error(st)
conf.fatal('msvc: Unicode error - check the code page?')
except Exception as e:
debug('msvc: get_msvc_version: %r %r %r -> failure' % (compiler, version, target))
debug(str(e))
conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
debug('msvc: get_msvc_version: %r %r %r -> failure %s' % (compiler, version, target, str(e)))
conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)')
else:
debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target)
finally:
@@ -235,7 +239,7 @@ def gather_wsdk_versions(conf, versions):
path,type = Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
except WindowsError:
continue
if os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')):
if path and os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')):
targets = []
for target,arch in all_msvc_platforms:
try:
@@ -328,8 +332,8 @@ def get_compiler_env(conf, compiler, version, bat_target, bat, select=None):
"""
Gets the compiler environment variables as a tuple. Evaluation is eager by default.
If set to lazy with ``--msvc_lazy_autodetect`` or ``env.MSVC_LAZY_AUTODETECT``
the environment is evaluated when the tuple is destructured or iterated. This means
destructuring can throw :py:class:`conf.errors.ConfigurationError`.
the environment is evaluated when the tuple is destructured or iterated. This means
destructuring can throw :py:class:`conf.errors.ConfigurationError`.

:param conf: configuration context to use to eventually get the version environment
:param compiler: compiler name
@@ -350,26 +354,26 @@ def get_compiler_env(conf, compiler, version, bat_target, bat, select=None):
class lazytup(object):
"""
A tuple that evaluates its elements from a function when iterated or destructured.
:param fn: thunk to evaluate the tuple on demand
:param lazy: whether to delay evaluation or evaluate in the constructor
:param default: optional default for :py:func:`repr` if it should not evaluate
"""
def __init__(self, fn, lazy=True, default=None):
def __init__(self, fn, lazy=True, default=None):
self.fn = fn
self.default = default
if not lazy:
self.evaluate()
def __len__(self):
def __len__(self):
self.evaluate()
return len(self.value)
def __iter__(self):
return len(self.value)
def __iter__(self):
self.evaluate()
for i, v in enumerate(self.value):
yield v
def __getitem__(self, i):
for i, v in enumerate(self.value):
yield v
def __getitem__(self, i):
self.evaluate()
return self.value[i]
return self.value[i]
def __repr__(self):
if hasattr(self, 'value'):
return repr(self.value)
@@ -594,9 +598,9 @@ def gather_intel_composer_versions(conf, versions):
if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and
not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)):
Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU '
'(VSWinExpress.exe) but it does not seem to be installed at %r. '
'The intel command line set up will fail to configure unless the file %r'
'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url))
'(VSWinExpress.exe) but it does not seem to be installed at %r. '
'The intel command line set up will fail to configure unless the file %r'
'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url))
except WindowsError:
pass
major = version[0:2]
@@ -833,9 +837,6 @@ def find_msvc(conf):
v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11)

# compiler
cxx = None
if v['CXX']: cxx = v['CXX']
elif 'CXX' in conf.environ: cxx = conf.environ['CXX']
cxx = conf.find_program(compiler_name, var='CXX', path_list=path)

# before setting anything, check if the compiler is really msvc


+ 46
- 1
waflib/Utils.py View File

@@ -409,10 +409,25 @@ def split_path_win32(path):
return ret
return re.split(re_sp, path)

msysroot = None
def split_path_msys(path):
if (path.startswith('/') or path.startswith('\\')) and not path.startswith('//') and not path.startswith('\\\\'):
# msys paths can be in the form /usr/bin
global msysroot
if not msysroot:
# msys has python 2.7 or 3, so we can use this
msysroot = subprocess.check_output(['cygpath', '-w', '/']).decode(sys.stdout.encoding or 'iso8859-1')
msysroot = msysroot.strip()
path = os.path.normpath(msysroot + os.sep + path)
return split_path_win32(path)

if sys.platform == 'cygwin':
split_path = split_path_cygwin
elif is_win32:
split_path = split_path_win32
if os.environ.get('MSYSTEM', None):
split_path = split_path_msys
else:
split_path = split_path_win32
else:
split_path = split_path_unix

@@ -441,6 +456,7 @@ def check_dir(path):
def check_exe(name, env=None):
"""
Ensure that a program exists

:type name: string
:param name: name or path to program
:return: path of the program or None
@@ -523,6 +539,25 @@ def h_fun(fun):
pass
return h

def h_cmd(ins):
"""
Task command hashes are calculated by calling this function. The inputs can be
strings, functions, tuples/lists containing strings/functions
"""
# this function is not meant to be particularly fast
if isinstance(ins, str):
# a command is either a string
ret = ins
elif isinstance(ins, list) or isinstance(ins, tuple):
# or a list of functions/strings
ret = str([h_cmd(x) for x in ins])
else:
# or just a python function
ret = str(h_fun(ins))
if sys.hexversion > 0x3000000:
ret = ret.encode('iso8859-1', 'xmlcharrefreplace')
return ret

reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
def subst_vars(expr, params):
"""
@@ -545,6 +580,8 @@ def subst_vars(expr, params):
return params.get_flat(m.group(3))
except AttributeError:
return params[m.group(3)]
# if you get a TypeError, it means that 'expr' is not a string...
# Utils.subst_vars(None, env) will not work
return reg_subst.sub(repl_var, expr)

def destos_to_binfmt(key):
@@ -595,6 +632,9 @@ def unversioned_sys_platform():
return 'darwin'
if s == 'win32' or s == 'os2':
return s
if s == 'cli' and os.name == 'nt':
# ironpython is only on windows as far as we know
return 'win32'
return re.split('\d+$', s)[0]

def nada(*k, **kw):
@@ -709,6 +749,7 @@ def run_once(fun):
cache[k] = ret
return ret
wrap.__cache__ = cache
wrap.__name__ = fun.__name__
return wrap

def get_registry_app_path(key, filename):
@@ -730,3 +771,7 @@ def lib64():
return '64'
return ''

def sane_path(p):
# private function for the time being!
return os.path.abspath(os.path.expanduser(p))


+ 7
- 3
waflib/extras/build_logs.py View File

@@ -10,7 +10,7 @@ A system for recording all outputs to a log file. Just add the following to your
"""

import atexit, sys, time, os, shutil, threading
from waflib import Logs, Context
from waflib import ansiterm, Logs, Context

# adding the logs under the build/ directory will clash with the clean/ command
try:
@@ -68,8 +68,12 @@ def init(ctx):
# sys.stdout has already been replaced, so __stdout__ will be faster
#sys.stdout = log_to_file(sys.stdout, fileobj, filename)
#sys.stderr = log_to_file(sys.stderr, fileobj, filename)
sys.stdout = log_to_file(sys.__stdout__, fileobj, filename)
sys.stderr = log_to_file(sys.__stderr__, fileobj, filename)
def wrap(stream):
if stream.isatty():
return ansiterm.AnsiTerm(stream)
return stream
sys.stdout = log_to_file(wrap(sys.__stdout__), fileobj, filename)
sys.stderr = log_to_file(wrap(sys.__stderr__), fileobj, filename)

# now mess with the logging module...
for x in Logs.log.handlers:


+ 0
- 1
waflib/extras/c_bgxlc.py View File

@@ -6,7 +6,6 @@
IBM XL Compiler for Blue Gene
"""

import os
from waflib.Tools import ccroot,ar
from waflib.Configure import conf



+ 0
- 1
waflib/extras/c_nec.py View File

@@ -6,7 +6,6 @@
NEC SX Compiler for SX vector systems
"""

import os
import re
from waflib import Utils
from waflib.Tools import ccroot,ar


Loading…
Cancel
Save