--- a/RELEASE_NOTES Wed Nov 09 16:11:47 2016 +0100
+++ b/RELEASE_NOTES Mon Nov 21 14:57:08 2016 +0900
@@ -38,7 +38,6 @@
----------
- Bug 2516 - Test dce-tcp-ns3-nsc-comparison fails
-
Release dce-1.8
===============
Availability
--- a/myscripts/dce-mpi-udp/wscript Wed Nov 09 16:11:47 2016 +0100
+++ b/myscripts/dce-mpi-udp/wscript Mon Nov 21 14:57:08 2016 +0900
@@ -1,7 +1,6 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
import ns3waf
-import Options
def configure(conf):
ns3waf.check_modules(conf, ['core', 'internet', 'point-to-point', 'mpi'], mandatory = True)
--- a/ns3waf/__init__.py Wed Nov 09 16:11:47 2016 +0100
+++ b/ns3waf/__init__.py Mon Nov 21 14:57:08 2016 +0900
@@ -5,9 +5,9 @@
import os
import re
+from waflib import Utils, Scripting, Configure, Build, Options, TaskGen, Context, Task, Logs, Errors
+
def options(opt):
- opt.tool_options('compiler_cc')
- opt.tool_options('compiler_cxx')
opt.add_option('--enable-static',
help=('Compile module statically: works only on linux, without python'),
dest='enable_static', action='store_true',
@@ -70,10 +70,9 @@
status = 'enabled'
else:
status = 'not enabled (%s)' % reason_not_enabled
- print "%-30s: %s" % (caption, status)
+ print("%-30s: %s" % (caption, status))
def _check_static(conf):
- import Options
import sys
import re
import os
@@ -121,7 +120,6 @@
def _check_win32(conf):
- import Options
import sys
import subprocess
import os
@@ -149,6 +147,7 @@
def _check_dependencies(conf, required, mandatory):
found = []
match_pkg = None
+
for module in required:
if module in conf.env['NS3_MODULES_FOUND']:
continue
@@ -206,13 +205,10 @@
return bld.env['cshlib_PATTERN'] % libname
def check_modules(conf, modules, mandatory = True):
- import Options
import os
if not 'NS3_CHECK_MODULE_ONCE' in conf.env:
conf.env['NS3_CHECK_MODULE_ONCE'] = ''
- conf.check_tool('compiler_cc')
- conf.check_tool('compiler_cxx')
conf.check_cfg(atleast_pkgconfig_version='0.0.0')
_check_win32(conf)
_check_static(conf)
@@ -297,7 +293,7 @@
ccdefines = ['NS3_MODULE_COMPILATION']
cxxdefines = ['NS3_MODULE_COMPILATION']
includes = _dirs(source)
- out_relpath = os.path.relpath(bld.out_dir, str(bld.out_dir) + "/" + bld.path.relpath_gen(bld.srcnode))
+ out_relpath = os.path.relpath(bld.out_dir, str(bld.out_dir) + "/" + bld.path.path_from(bld.srcnode))
target = os.path.join(out_relpath, 'lib', 'ns3-%s' % name)
if not bld.env['NS3_ENABLE_STATIC']:
if bld.env['CXX_NAME'] in ['gcc', 'icc'] and bld.env['WL_SONAME_SUPPORTED']:
@@ -343,14 +339,16 @@
outfile = file(task.outputs[0].abspath(), "w")
- print >> outfile, """
+ guard = """
#ifdef NS3_MODULE_COMPILATION
# error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts."
#endif
-#ifndef NS3_MODULE_%s
- """ % (name.upper().replace('-', '_'),)
+#ifndef NS3_MODULE_{module}
+ """.format(module=name.upper().replace('-', '_'))
+ print >> outfile, guard
+ # this is not python3 compatible but doesn't seem to be called so leave it likethis
print >> outfile
print >> outfile, "// Module headers:"
for header in [src.abspath() for src in task.inputs]:
@@ -359,7 +357,7 @@
print >> outfile, "#endif"
outfile.close()
- out_relpath = os.path.relpath(bld.out_dir, str(bld.out_dir) + "/" + bld.path.relpath_gen(bld.srcnode))
+ out_relpath = os.path.relpath(bld.out_dir, str(bld.out_dir) + "/" + bld.path.path_from(bld.srcnode))
target = os.path.join(out_relpath, 'include', 'ns3', '%s-module.h' % name)
bld(rule=run, source=headers, target=target)
bld(use=[target], target='NS3_HEADERS_%s' % name.upper(),
@@ -500,7 +498,7 @@
kw['use'] = kw.get('use', []) + modules_uselib(self._bld, needed)
_build_library(self._bld, target, **kw)
- out_relpath = os.path.relpath(self._bld.out_dir, str(self._bld.out_dir) + "/" + self._bld.path.relpath_gen(self._bld.srcnode))
+ out_relpath = os.path.relpath(self._bld.out_dir, str(self._bld.out_dir) + "/" + self._bld.path.path_from(self._bld.srcnode))
self._bld.env.append_value('NS3_ENABLED_MODULE_TEST_LIBRARIES', out_relpath + "/lib/ns3-"+target)
if kw['target'].find("bin_dce") == -1:
@@ -523,7 +521,7 @@
kw['includes'] = kw.get('includes', []) + self._source_dirs
- tmp = self._bld.path.relpath_gen(self._bld.srcnode)
+ tmp = self._bld.path.path_from(self._bld.srcnode)
objects = []
for src in kw['source'][0:-1]:
src_target = '%s_object' % src
Binary file waf has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/waf-tools/cflags.py Mon Nov 21 14:57:08 2016 +0900
@@ -0,0 +1,194 @@
+from waflib import Logs, Options, Utils
+
+
+class CompilerTraits(object):
+ def get_warnings_flags(self, level):
+ """get_warnings_flags(level) -> list of cflags"""
+ raise NotImplementedError
+
+ def get_optimization_flags(self, level):
+ """get_optimization_flags(level) -> list of cflags"""
+ raise NotImplementedError
+
+ def get_debug_flags(self, level):
+ """get_debug_flags(level) -> (list of cflags, list of cppdefines)"""
+ raise NotImplementedError
+
+
+class GccTraits(CompilerTraits):
+ def __init__(self):
+ super(GccTraits, self).__init__()
+ # cumulative list of warnings per level
+ self.warnings_flags = [['-Wall'], ['-Werror'], ['-Wextra']]
+
+ def get_warnings_flags(self, level):
+ warnings = []
+ for l in range(level):
+ if l < len(self.warnings_flags):
+ warnings.extend(self.warnings_flags[l])
+ else:
+ break
+ return warnings
+
+ def get_optimization_flags(self, level):
+ if level == 0:
+ return ['-O0']
+ elif level == 1:
+ return ['-O']
+ elif level == 2:
+ return ['-O2']
+ elif level == 3:
+ return ['-O3']
+
+ def get_debug_flags(self, level):
+ if level == 0:
+ return (['-g0'], ['NDEBUG'])
+ elif level == 1:
+ return (['-g'], [])
+ elif level >= 2:
+ return (['-ggdb', '-g3'], ['_DEBUG'])
+
+
+class IccTraits(CompilerTraits):
+ def __init__(self):
+ super(IccTraits, self).__init__()
+ # cumulative list of warnings per level
+ # icc is _very_ verbose with -Wall, -Werror is barely achievable
+ self.warnings_flags = [[], [], ['-Wall']]
+
+ def get_warnings_flags(self, level):
+ warnings = []
+ for l in range(level):
+ if l < len(self.warnings_flags):
+ warnings.extend(self.warnings_flags[l])
+ else:
+ break
+ return warnings
+
+ def get_optimization_flags(self, level):
+ if level == 0:
+ return ['-O0']
+ elif level == 1:
+ return ['-O']
+ elif level == 2:
+ return ['-O2']
+ elif level == 3:
+ return ['-O3']
+
+ def get_debug_flags(self, level):
+ if level == 0:
+ return (['-g0'], ['NDEBUG'])
+ elif level == 1:
+ return (['-g'], [])
+ elif level >= 2:
+ return (['-ggdb', '-g3'], ['_DEBUG'])
+
+
+
+class MsvcTraits(CompilerTraits):
+ def __init__(self):
+ super(MsvcTraits, self).__init__()
+ # cumulative list of warnings per level
+ self.warnings_flags = [['/W2'], ['/WX'], ['/Wall']]
+
+ def get_warnings_flags(self, level):
+ warnings = []
+ for l in range(level):
+ if l < len(self.warnings_flags):
+ warnings.extend(self.warnings_flags[l])
+ else:
+ break
+ return warnings
+
+ def get_optimization_flags(self, level):
+ if level == 0:
+ return ['/Od']
+ elif level == 1:
+ return []
+ elif level == 2:
+ return ['/O2']
+ elif level == 3:
+ return ['/Ox']
+
+ def get_debug_flags(self, level):
+ if level == 0:
+ return ([], ['NDEBUG'])
+ elif level == 1:
+ return (['/ZI', '/RTC1'], [])
+ elif level >= 2:
+ return (['/ZI', '/RTC1'], ['_DEBUG'])
+
+
+
+gcc = GccTraits()
+icc = IccTraits()
+msvc = MsvcTraits()
+
+# how to map env['COMPILER_CC'] or env['COMPILER_CXX'] into a traits object
+compiler_mapping = {
+ 'gcc': gcc,
+ 'g++': gcc,
+ 'msvc': msvc,
+ 'icc': icc,
+ 'icpc': icc,
+ 'clang': gcc,
+ 'clang++': gcc,
+}
+
+profiles = {
+ # profile name: [optimization_level, warnings_level, debug_level]
+ 'default': [2, 1, 1],
+ 'debug': [0, 2, 3],
+ 'release': [3, 1, 0],
+ }
+
+default_profile = 'default'
+
+def options(opt):
+ assert default_profile in profiles
+ opt.add_option('-d', '--build-profile',
+ action='store',
+ default=default_profile,
+ help=("Specify the build profile. "
+ "Build profiles control the default compilation flags"
+ " used for C/C++ programs, if CCFLAGS/CXXFLAGS are not"
+ " set in the environment. [Allowed Values: %s]"
+ % ", ".join([repr(p) for p in list(profiles.keys())])),
+ choices=list(profiles.keys()),
+ dest='build_profile')
+ opt.add_option('--check-profile',
+ help=('print out current build profile'),
+ default=False, dest='check_profile', action="store_true")
+def configure(conf):
+ cc = conf.env['COMPILER_CC'] or None
+ cxx = conf.env['COMPILER_CXX'] or None
+ if not (cc or cxx):
+ raise Utils.WafError("neither COMPILER_CC nor COMPILER_CXX are defined; "
+ "maybe the compiler_cc or compiler_cxx tool has not been configured yet?")
+
+ try:
+ compiler = compiler_mapping[cc]
+ except KeyError:
+ try:
+ compiler = compiler_mapping[cxx]
+ except KeyError:
+ Logs.warn("No compiler flags support for compiler %r or %r"
+ % (cc, cxx))
+ return
+
+ opt_level, warn_level, dbg_level = profiles[Options.options.build_profile]
+
+ optimizations = compiler.get_optimization_flags(opt_level)
+ debug, debug_defs = compiler.get_debug_flags(dbg_level)
+ warnings = compiler.get_warnings_flags(warn_level)
+
+ if cc and not conf.env['CCFLAGS']:
+ conf.env.append_value('CCFLAGS', optimizations)
+ conf.env.append_value('CCFLAGS', debug)
+ conf.env.append_value('CCFLAGS', warnings)
+ conf.env.append_value('CCDEFINES', debug_defs)
+ if cxx and not conf.env['CXXFLAGS']:
+ conf.env.append_value('CXXFLAGS', optimizations)
+ conf.env.append_value('CXXFLAGS', debug)
+ conf.env.append_value('CXXFLAGS', warnings)
+ conf.env.append_value('CXXDEFINES', debug_defs)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/waf-tools/clang_compilation_database.py Mon Nov 21 14:57:08 2016 +0900
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Christoph Koke, 2013
+
+"""
+Writes the c and cpp compile commands into build/compile_commands.json
+see http://clang.llvm.org/docs/JSONCompilationDatabase.html
+
+Usage:
+
+ def configure(conf):
+ conf.load('compiler_cxx')
+ ...
+ conf.load('clang_compilation_database')
+"""
+
+import sys, os, json, shlex, pipes
+from waflib import Logs, TaskGen
+from waflib.Tools import c, cxx
+
+if sys.hexversion >= 0x3030000:
+ quote = shlex.quote
+else:
+ quote = pipes.quote
+
+@TaskGen.feature('*')
+@TaskGen.after_method('process_use')
+def collect_compilation_db_tasks(self):
+ "Add a compilation database entry for compiled tasks"
+ try:
+ clang_db = self.bld.clang_compilation_database_tasks
+ except AttributeError:
+ clang_db = self.bld.clang_compilation_database_tasks = []
+ self.bld.add_post_fun(write_compilation_database)
+
+ for task in getattr(self, 'compiled_tasks', []):
+ if isinstance(task, (c.c, cxx.cxx)):
+ clang_db.append(task)
+
+def write_compilation_database(ctx):
+ "Write the clang compilation database as JSON"
+ database_file = ctx.bldnode.make_node('compile_commands.json')
+ Logs.info("Build commands will be stored in %s" % database_file.path_from(ctx.path))
+ try:
+ root = json.load(database_file)
+ except IOError:
+ root = []
+ clang_db = dict((x["file"], x) for x in root)
+ for task in getattr(ctx, 'clang_compilation_database_tasks', []):
+ try:
+ cmd = task.last_cmd
+ except AttributeError:
+ continue
+ directory = getattr(task, 'cwd', ctx.variant_dir)
+ f_node = task.inputs[0]
+ filename = os.path.relpath(f_node.abspath(), directory)
+ cmd = " ".join(map(quote, cmd))
+ entry = {
+ "directory": directory,
+ "command": cmd,
+ "file": filename,
+ }
+ clang_db[filename] = entry
+ root = list(clang_db.values())
+ database_file.write(json.dumps(root, indent=2))
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/waf-tools/command.py Mon Nov 21 14:57:08 2016 +0900
@@ -0,0 +1,131 @@
+import re
+import subprocess
+
+# import feature, taskgen_method, before_method, task_gen
+from waflib import TaskGen, Node, Task, Utils, Build, Options, Logs, Task
+debug = Logs.debug
+error = Logs.error
+
+import shellcmd
+#shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy
+shellcmd.debug = debug
+
+
+arg_rx = re.compile(r"(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})", re.M)
+
+class command_task(Task.Task):
+ color = "BLUE"
+ def __init__(self, env, generator):
+ Task.Task.__init__(self, env=env, normal=1, generator=generator)
+
+ def __str__(self):
+ "string to display to the user"
+ env = self.env
+ src_str = ' '.join([a.bldpath() for a in self.inputs])
+ tgt_str = ' '.join([a.bldpath() for a in self.outputs])
+ if self.outputs:
+ sep = ' -> '
+ else:
+ sep = ''
+
+ pipeline = shellcmd.Pipeline()
+ pipeline.parse(self.generator.command)
+ cmd = pipeline.get_abbreviated_command()
+ return 'command (%s): %s%s%s\n' % (cmd, src_str, sep, tgt_str)
+
+ def _subst_arg(self, arg, direction, namespace):
+ """
+ @param arg: the command argument (or stdin/stdout/stderr) to substitute
+ @param direction: direction of the argument: 'in', 'out', or None
+ """
+ def repl(match):
+ if match.group('dollar'):
+ return "$"
+ elif match.group('subst'):
+ var = match.group('var')
+ code = match.group('code')
+ result = eval(var+code, namespace)
+ if isinstance(result, Node.Node):
+ if var == 'TGT':
+ return result.get_bld().abspath()
+ elif var == 'SRC':
+ return result.srcpath()
+ else:
+ raise ValueError("Bad subst variable %r" % var)
+ elif result is self.inputs:
+ if len(self.inputs) == 1:
+ return result[0].srcpath()
+ else:
+ raise ValueError("${SRC} requested but have multiple sources; which one?")
+ elif result is self.outputs:
+ if len(self.outputs) == 1:
+ return result[0].get_bld().abspath()
+ else:
+ raise ValueError("${TGT} requested but have multiple targets; which one?")
+ elif isinstance(result, list):
+ assert len(result) == 1
+ return result[0]
+ else:
+ return result
+ return None
+
+ return arg_rx.sub(repl, arg)
+
+ def run(self):
+ pipeline = shellcmd.Pipeline()
+ pipeline.parse(self.generator.command)
+ namespace = self.env.get_merged_dict()
+ if self.generator.variables is not None:
+ namespace.update(self.generator.variables)
+ namespace.update(env=self.env, SRC=self.inputs, TGT=self.outputs)
+ for cmd in pipeline.pipeline:
+ if isinstance(cmd, shellcmd.Command):
+ if isinstance(cmd.stdin, str):
+ cmd.stdin = self._subst_arg(cmd.stdin, 'in', namespace)
+ if isinstance(cmd.stdout, str):
+ cmd.stdout = self._subst_arg(cmd.stdout, 'out', namespace)
+ if isinstance(cmd.stderr, str):
+ cmd.stderr = self._subst_arg(cmd.stderr, 'out', namespace)
+ for argI in range(len(cmd.argv)):
+ cmd.argv[argI] = self._subst_arg(cmd.argv[argI], None, namespace)
+ if cmd.env_vars is not None:
+ env_vars = dict()
+ for name, value in cmd.env_vars.items():
+ env_vars[name] = self._subst_arg(value, None, namespace)
+ cmd.env_vars = env_vars
+ elif isinstance(cmd, shellcmd.Chdir):
+ cmd.dir = self._subst_arg(cmd.dir, None, namespace)
+ return pipeline.run(verbose=(Options.options.verbose > 0))
+
+@TaskGen.taskgen_method
+@TaskGen.feature('command')
+def init_command(self):
+ Utils.def_attrs(self,
+ # other variables that can be used in the command: ${VARIABLE}
+ variables = None,
+ rule='')
+
+
+
+@TaskGen.feature('command')
+@TaskGen.after_method('process_rule')
+def apply_command(self):
+ #self.meths.remove('apply_core')
+ # create the task
+ task = self.create_task('command')
+ setattr(task, "dep_vars", getattr(self, "dep_vars", None))
+ # process the sources
+ inputs = []
+ for node in self.source:
+ inputs.append(node)
+ task.set_inputs(inputs)
+ task.set_outputs([self.path.find_or_declare(tgt) for tgt in self.to_list(self.target)])
+ self.source = ''
+ #Task.file_deps = Task.extract_deps
+
+
+
+# class command_taskgen(task_gen):
+# def __init__(self, *k, **kw):
+# task_gen.__init__(self, *k, **kw)
+# self.features.append('command')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/waf-tools/misc.py Mon Nov 21 14:57:08 2016 +0900
@@ -0,0 +1,413 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2006-2010 (ita)
+
+"""
+This tool is totally deprecated
+
+Try using:
+ .pc.in files for .pc files
+ the feature intltool_in - see demos/intltool
+ make-like rules
+"""
+
+import shutil, re, os
+from waflib import TaskGen, Node, Task, Utils, Build, Errors
+from waflib.TaskGen import feature, after_method, before_method
+from waflib.Logs import debug
+
+def copy_attrs(orig, dest, names, only_if_set=False):
+ """
+ copy class attributes from an object to another
+ """
+ for a in Utils.to_list(names):
+ u = getattr(orig, a, ())
+ if u or not only_if_set:
+ setattr(dest, a, u)
+
+def copy_func(tsk):
+ "Make a file copy. This might be used to make other kinds of file processing (even calling a compiler is possible)"
+ env = tsk.env
+ infile = tsk.inputs[0].abspath()
+ outfile = tsk.outputs[0].abspath()
+ try:
+ shutil.copy2(infile, outfile)
+ except EnvironmentError:
+ return 1
+ else:
+ if tsk.chmod: os.chmod(outfile, tsk.chmod)
+ return 0
+
+def action_process_file_func(tsk):
+ "Ask the function attached to the task to process it"
+ if not tsk.fun: raise Errors.WafError('task must have a function attached to it for copy_func to work!')
+ return tsk.fun(tsk)
+
+@feature('cmd')
+def apply_cmd(self):
+ "call a command everytime"
+ if not self.fun: raise Errors.WafError('cmdobj needs a function!')
+ tsk = Task.TaskBase()
+ tsk.fun = self.fun
+ tsk.env = self.env
+ self.tasks.append(tsk)
+ tsk.install_path = self.install_path
+
+@feature('copy')
+@before_method('process_source')
+def apply_copy(self):
+ Utils.def_attrs(self, fun=copy_func)
+ self.default_install_path = 0
+
+ lst = self.to_list(self.source)
+ self.meths.remove('process_source')
+
+ for filename in lst:
+ node = self.path.find_resource(filename)
+ if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
+
+ target = self.target
+ if not target or len(lst)>1: target = node.name
+
+ # TODO the file path may be incorrect
+ newnode = self.path.find_or_declare(target)
+
+ tsk = self.create_task('copy', node, newnode)
+ tsk.fun = self.fun
+ tsk.chmod = getattr(self, 'chmod', Utils.O644)
+
+ if not tsk.env:
+ tsk.debug()
+ raise Errors.WafError('task without an environment')
+
+def subst_func(tsk):
+ "Substitutes variables in a .in file"
+
+ m4_re = re.compile('@(\w+)@', re.M)
+
+ code = tsk.inputs[0].read() #Utils.readf(infile)
+
+ # replace all % by %% to prevent errors by % signs in the input file while string formatting
+ code = code.replace('%', '%%')
+
+ s = m4_re.sub(r'%(\1)s', code)
+
+ env = tsk.env
+ di = getattr(tsk, 'dict', {}) or getattr(tsk.generator, 'dict', {})
+ if not di:
+ names = m4_re.findall(code)
+ for i in names:
+ di[i] = env.get_flat(i) or env.get_flat(i.upper())
+
+ tsk.outputs[0].write(s % di)
+
+@feature('subst')
+@before_method('process_source')
+def apply_subst(self):
+ Utils.def_attrs(self, fun=subst_func)
+ lst = self.to_list(self.source)
+ self.meths.remove('process_source')
+
+ self.dict = getattr(self, 'dict', {})
+
+ for filename in lst:
+ node = self.path.find_resource(filename)
+ if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
+
+ if self.target:
+ newnode = self.path.find_or_declare(self.target)
+ else:
+ newnode = node.change_ext('')
+
+ try:
+ self.dict = self.dict.get_merged_dict()
+ except AttributeError:
+ pass
+
+ if self.dict and not self.env['DICT_HASH']:
+ self.env = self.env.derive()
+ keys = list(self.dict.keys())
+ keys.sort()
+ lst = [self.dict[x] for x in keys]
+ self.env['DICT_HASH'] = str(Utils.h_list(lst))
+
+ tsk = self.create_task('copy', node, newnode)
+ tsk.fun = self.fun
+ tsk.dict = self.dict
+ tsk.dep_vars = ['DICT_HASH']
+ tsk.chmod = getattr(self, 'chmod', Utils.O644)
+
+ if not tsk.env:
+ tsk.debug()
+ raise Errors.WafError('task without an environment')
+
+####################
+## command-output ####
+####################
+
+class cmd_arg(object):
+ """command-output arguments for representing files or folders"""
+ def __init__(self, name, template='%s'):
+ self.name = name
+ self.template = template
+ self.node = None
+
+class input_file(cmd_arg):
+ def find_node(self, base_path):
+ assert isinstance(base_path, Node.Node)
+ self.node = base_path.find_resource(self.name)
+ if self.node is None:
+ raise Errors.WafError("Input file %s not found in " % (self.name, base_path))
+
+ def get_path(self, env, absolute):
+ if absolute:
+ return self.template % self.node.abspath()
+ else:
+ return self.template % self.node.srcpath()
+
+class output_file(cmd_arg):
+ def find_node(self, base_path):
+ assert isinstance(base_path, Node.Node)
+ self.node = base_path.find_or_declare(self.name)
+ if self.node is None:
+ raise Errors.WafError("Output file %s not found in " % (self.name, base_path))
+
+ def get_path(self, env, absolute):
+ if absolute:
+ return self.template % self.node.abspath()
+ else:
+ return self.template % self.node.bldpath()
+
+class cmd_dir_arg(cmd_arg):
+ def find_node(self, base_path):
+ assert isinstance(base_path, Node.Node)
+ self.node = base_path.find_dir(self.name)
+ if self.node is None:
+ raise Errors.WafError("Directory %s not found in " % (self.name, base_path))
+
+class input_dir(cmd_dir_arg):
+ def get_path(self, dummy_env, dummy_absolute):
+ return self.template % self.node.abspath()
+
+class output_dir(cmd_dir_arg):
+ def get_path(self, env, dummy_absolute):
+ return self.template % self.node.abspath()
+
+
+class command_output(Task.Task):
+ color = "BLUE"
+ def __init__(self, env, command, command_node, command_args, stdin, stdout, cwd, os_env, stderr):
+ Task.Task.__init__(self, env=env)
+ assert isinstance(command, (str, Node.Node))
+ self.command = command
+ self.command_args = command_args
+ self.stdin = stdin
+ self.stdout = stdout
+ self.cwd = cwd
+ self.os_env = os_env
+ self.stderr = stderr
+
+ if command_node is not None: self.dep_nodes = [command_node]
+ self.dep_vars = [] # additional environment variables to look
+
+ def run(self):
+ task = self
+ #assert len(task.inputs) > 0
+
+ def input_path(node, template):
+ if task.cwd is None:
+ return template % node.bldpath()
+ else:
+ return template % node.abspath()
+ def output_path(node, template):
+ fun = node.abspath
+ if task.cwd is None: fun = node.bldpath
+ return template % fun()
+
+ if isinstance(task.command, Node.Node):
+ argv = [input_path(task.command, '%s')]
+ else:
+ argv = [task.command]
+
+ for arg in task.command_args:
+ if isinstance(arg, str):
+ argv.append(arg)
+ else:
+ assert isinstance(arg, cmd_arg)
+ argv.append(arg.get_path(task.env, (task.cwd is not None)))
+
+ if task.stdin:
+ stdin = open(input_path(task.stdin, '%s'))
+ else:
+ stdin = None
+
+ if task.stdout:
+ stdout = open(output_path(task.stdout, '%s'), "w")
+ else:
+ stdout = None
+
+ if task.stderr:
+ stderr = open(output_path(task.stderr, '%s'), "w")
+ else:
+ stderr = None
+
+ if task.cwd is None:
+ cwd = ('None (actually %r)' % os.getcwd())
+ else:
+ cwd = repr(task.cwd)
+ debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r" %
+ (cwd, stdin, stdout, argv))
+
+ if task.os_env is None:
+ os_env = os.environ
+ else:
+ os_env = task.os_env
+ command = Utils.subprocess.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, cwd=task.cwd, env=os_env)
+ return command.wait()
+
+@feature('command-output')
+def init_cmd_output(self):
+ Utils.def_attrs(self,
+ stdin = None,
+ stdout = None,
+ stderr = None,
+ # the command to execute
+ command = None,
+
+ # whether it is an external command; otherwise it is assumed
+ # to be an executable binary or script that lives in the
+ # source or build tree.
+ command_is_external = False,
+
+ # extra parameters (argv) to pass to the command (excluding
+ # the command itself)
+ argv = [],
+
+ # dependencies to other objects -> this is probably not what you want (ita)
+ # values must be 'task_gen' instances (not names!)
+ dependencies = [],
+
+ # dependencies on env variable contents
+ dep_vars = [],
+
+ # input files that are implicit, i.e. they are not
+ # stdin, nor are they mentioned explicitly in argv
+ hidden_inputs = [],
+
+ # output files that are implicit, i.e. they are not
+ # stdout, nor are they mentioned explicitly in argv
+ hidden_outputs = [],
+
+ # change the subprocess to this cwd (must use obj.input_dir() or output_dir() here)
+ cwd = None,
+
+ # OS environment variables to pass to the subprocess
+ # if None, use the default environment variables unchanged
+ os_env = None)
+
+@feature('command-output')
+@after_method('init_cmd_output')
+def apply_cmd_output(self):
+ if self.command is None:
+ raise Errors.WafError("command-output missing command")
+ if self.command_is_external:
+ cmd = self.command
+ cmd_node = None
+ else:
+ cmd_node = self.path.find_resource(self.command)
+ assert cmd_node is not None, ('''Could not find command '%s' in source tree.
+Hint: if this is an external command,
+use command_is_external=True''') % (self.command,)
+ cmd = cmd_node
+
+ if self.cwd is None:
+ cwd = None
+
+ args = []
+ inputs = []
+ outputs = []
+
+ for arg in self.argv:
+ if isinstance(arg, cmd_arg):
+ arg.find_node(self.path)
+ if isinstance(arg, input_file):
+ inputs.append(arg.node)
+ if isinstance(arg, output_file):
+ outputs.append(arg.node)
+
+ if self.stdout is None:
+ stdout = None
+ else:
+ assert isinstance(self.stdout, str)
+ stdout = self.path.find_or_declare(self.stdout)
+ if stdout is None:
+ raise Errors.WafError("File %s not found" % (self.stdout,))
+ outputs.append(stdout)
+
+ if self.stderr is None:
+ stderr = None
+ else:
+ assert isinstance(self.stderr, str)
+ stderr = self.path.find_or_declare(self.stderr)
+ if stderr is None:
+ raise Errors.WafError("File %s not found" % (self.stderr,))
+ outputs.append(stderr)
+
+ if self.stdin is None:
+ stdin = None
+ else:
+ assert isinstance(self.stdin, str)
+ stdin = self.path.find_resource(self.stdin)
+ if stdin is None:
+ raise Errors.WafError("File %s not found" % (self.stdin,))
+ inputs.append(stdin)
+
+ for hidden_input in self.to_list(self.hidden_inputs):
+ node = self.path.find_resource(hidden_input)
+ if node is None:
+ raise Errors.WafError("File %s not found in dir %s" % (hidden_input, self.path))
+ inputs.append(node)
+
+ for hidden_output in self.to_list(self.hidden_outputs):
+ node = self.path.find_or_declare(hidden_output)
+ if node is None:
+ raise Errors.WafError("File %s not found in dir %s" % (hidden_output, self.path))
+ outputs.append(node)
+
+ if not (inputs or getattr(self, 'no_inputs', None)):
+ raise Errors.WafError('command-output objects must have at least one input file or give self.no_inputs')
+ if not (outputs or getattr(self, 'no_outputs', None)):
+ raise Errors.WafError('command-output objects must have at least one output file or give self.no_outputs')
+
+ cwd = self.bld.variant_dir
+ task = command_output(self.env, cmd, cmd_node, self.argv, stdin, stdout, cwd, self.os_env, stderr)
+ task.generator = self
+ copy_attrs(self, task, 'before after ext_in ext_out', only_if_set=True)
+ self.tasks.append(task)
+
+ task.inputs = inputs
+ task.outputs = outputs
+ task.dep_vars = self.to_list(self.dep_vars)
+
+ for dep in self.dependencies:
+ assert dep is not self
+ dep.post()
+ for dep_task in dep.tasks:
+ task.set_run_after(dep_task)
+
+ if not task.inputs:
+ # the case for svnversion, always run, and update the output nodes
+ task.runnable_status = type(Task.TaskBase.run)(runnable_status, task, task.__class__) # always run
+ task.post_run = type(Task.TaskBase.run)(post_run, task, task.__class__)
+
+ # TODO the case with no outputs?
+
+def post_run(self):
+ for x in self.outputs:
+ x.sig = Utils.h_file(x.abspath())
+
+def runnable_status(self):
+ return self.RUN_ME
+
+Task.task_factory('copy', vars=[], func=action_process_file_func)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/waf-tools/relocation.py Mon Nov 21 14:57:08 2016 +0900
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+"""
+Waf 1.6
+
+Try to detect if the project directory was relocated, and if it was,
+change the node representing the project directory. Just call:
+
+ waf configure build
+
+Note that if the project directory name changes, the signatures for the tasks using
+files in that directory will change, causing a partial build.
+"""
+from __future__ import print_function
+import os
+from waflib import Build, ConfigSet, Task, Utils, Errors
+from waflib.TaskGen import feature, before_method, after_method
+
+EXTRA_LOCK = '.old_srcdir'
+
+old1 = Build.BuildContext.store
+def store(self):
+ old1(self)
+ db = os.path.join(self.variant_dir, EXTRA_LOCK)
+ env = ConfigSet.ConfigSet()
+ env.SRCDIR = self.srcnode.abspath()
+ env.store(db)
+Build.BuildContext.store = store
+
+old2 = Build.BuildContext.init_dirs
+def init_dirs(self):
+
+ if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)):
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+
+ srcdir = None
+ db = os.path.join(self.variant_dir, EXTRA_LOCK)
+ env = ConfigSet.ConfigSet()
+ try:
+ env.load(db)
+ srcdir = env.SRCDIR
+ except:
+ pass
+
+ if srcdir:
+ d = self.root.find_node(srcdir)
+ if d and srcdir != self.top_dir and getattr(d, 'children', ''):
+ srcnode = self.root.make_node(self.top_dir)
+ print(("relocating the source directory %r -> %r" % (srcdir, self.top_dir)))
+ srcnode.children = {}
+
+ for (k, v) in list(d.children.items()):
+ srcnode.children[k] = v
+ v.parent = srcnode
+ d.children = {}
+
+ old2(self)
+
+Build.BuildContext.init_dirs = init_dirs
+
+
+def uid(self):
+ try:
+ return self.uid_
+ except AttributeError:
+ # this is not a real hot zone, but we want to avoid surprises here
+ m = Utils.md5()
+ up = m.update
+ up(self.__class__.__name__.encode())
+ for x in self.inputs + self.outputs:
+ up(x.path_from(x.ctx.srcnode).encode())
+ self.uid_ = m.digest()
+ return self.uid_
+Task.Task.uid = uid
+
+@feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes')
+@after_method('propagate_uselib_vars', 'process_source')
+def apply_incpaths(self):
+ lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'])
+ self.includes_nodes = lst
+ bld = self.bld
+ self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst]
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/waf-tools/shellcmd.py Mon Nov 21 14:57:08 2016 +0900
@@ -0,0 +1,357 @@
+# Copyright (C) 2008 Gustavo J. A. M. Carneiro <gjcarneiro@gmail.com>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from __future__ import print_function
+import shlex
+import subprocess
+import sys
+import re
+import os
+
+env_var_rx = re.compile(r"^([a-zA-Z0-9_]+)=(\S+)$")
+
+def debug(message):
+ print(message, file=sys.stderr)
+
+
+if sys.platform == 'win32':
+ dev_null = open("NUL:", "w")
+else:
+ dev_null = open("/dev/null", "w")
+
+fcntl = fd = fl = None
+try:
+ import fcntl
+except ImportError:
+ pass
+else:
+ fd = dev_null.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFD)
+ fcntl.fcntl(fd, fcntl.F_SETFD, fl | fcntl.FD_CLOEXEC)
+del fcntl, fd, fl
+
+def _open_out_file(filename):
+ if filename in ['NUL:', '/dev/null']:
+ return dev_null
+ else:
+ return open(filename, 'wb')
+
+
+class Node(object):
+ pass
+
+class Op(Node):
+ pass
+
+class Pipe(Op):
+ pass
+
+class And(Op):
+ pass
+
+class Or(Op):
+ pass
+
+class Command(Node):
+ class PIPE(object):
+ pass # PIPE is a constant
+ class STDOUT(object):
+ pass # PIPE is a constant
+
+ def __init__(self, name):
+ super(Command, self).__init__()
+ self.name = name # command name
+ self.argv = [name] # command argv
+ self.stdin = None
+ self.stdout = None
+ self.stderr = None
+ self.env_vars = None
+
+ def __repr__(self):
+ return "Command(%r, argv=%r, stdin=%r, stdout=%r, stderr=%r)" \
+ % (self.name, self.argv, self.stdin, self.stdout, self.stderr)
+
+class Chdir(Node):
+ def __init__(self):
+ super(Chdir, self).__init__()
+ self.dir = None
+
+ def __repr__(self):
+ return "Chdir(%r)" \
+ % (self.dir)
+
+class Pipeline(object):
+ def __init__(self):
+ self.current_command = None
+ self.pipeline = []
+
+ def _commit_command(self):
+ assert self.current_command is not None
+ self.pipeline.append(self.current_command)
+ self.current_command = None
+
+ def get_abbreviated_command(self):
+ l = []
+ for node in self.pipeline:
+ if isinstance(node, Command):
+ l.append(node.name)
+ if isinstance(node, Chdir):
+ l.append('cd %s' % node.dir)
+ elif isinstance(node, Pipe):
+ l.append('|')
+ elif isinstance(node, And):
+ l.append('&&')
+ elif isinstance(node, And):
+ l.append('||')
+ return ' '.join(l)
+
+ def parse(self, command):
+ self.current_command = None
+ self.pipeline = []
+
+ if isinstance(command, list):
+ tokens = list(command)
+ else:
+ tokens = shlex.split(command)
+ debug("command: shlex: %r" % (tokens,))
+
+ BEGIN, COMMAND, CHDIR, STDERR, STDOUT, STDIN = list(range(6))
+ state = BEGIN
+ self.current_command = None
+ env_vars = dict()
+
+ while tokens:
+ token = tokens.pop(0)
+ if state == BEGIN:
+ env_var_match = env_var_rx.match(token)
+ if env_var_match is not None:
+ env_vars[env_var_match.group(1)] = env_var_match.group(2)
+ else:
+ assert self.current_command is None
+ if token == 'cd':
+ self.current_command = Chdir()
+ assert not env_vars
+ state = CHDIR
+ else:
+ self.current_command = Command(token)
+ if env_vars:
+ self.current_command.env_vars = env_vars
+ env_vars = dict()
+ state = COMMAND
+ elif state == COMMAND:
+ if token == '>':
+ state = STDOUT
+ elif token == '2>':
+ state = STDERR
+ elif token == '2>&1':
+ assert self.current_command.stderr is None
+ self.current_command.stderr = Command.STDOUT
+ elif token == '<':
+ state = STDIN
+ elif token == '|':
+ assert self.current_command.stdout is None
+ self.current_command.stdout = Command.PIPE
+ self._commit_command()
+ self.pipeline.append(Pipe())
+ state = BEGIN
+ elif token == '&&':
+ self._commit_command()
+ self.pipeline.append(And())
+ state = BEGIN
+ elif token == '||':
+ self._commit_command()
+ self.pipeline.append(Or())
+ state = BEGIN
+ else:
+ self.current_command.argv.append(token)
+ elif state == CHDIR:
+ if token == '&&':
+ self._commit_command()
+ self.pipeline.append(And())
+ state = BEGIN
+ else:
+ assert self.current_command.dir is None
+ self.current_command.dir = token
+ elif state == STDOUT:
+ assert self.current_command.stdout is None
+ self.current_command.stdout = token
+ state = COMMAND
+ elif state == STDERR:
+ assert self.current_command.stderr is None
+ self.current_command.stderr = token
+ state = COMMAND
+ elif state == STDIN:
+ assert self.current_command.stdin is None
+ self.current_command.stdin = token
+ state = COMMAND
+ self._commit_command()
+ return self.pipeline
+
+ def _exec_piped_commands(self, commands):
+ retvals = []
+ for cmd in commands:
+ retvals.append(cmd.wait())
+ retval = 0
+ for r in retvals:
+ if r:
+ retval = retvals[-1]
+ break
+ return retval
+
+ def run(self, verbose=False):
+ pipeline = list(self.pipeline)
+ files_to_close = []
+ piped_commands = []
+ piped_commands_display = []
+ BEGIN, PIPE = list(range(2))
+ state = BEGIN
+ cwd = '.'
+ while pipeline:
+ node = pipeline.pop(0)
+
+ if isinstance(node, Chdir):
+ next_op = pipeline.pop(0)
+ assert isinstance(next_op, And)
+ cwd = os.path.join(cwd, node.dir)
+ if verbose:
+ piped_commands_display.append("cd %s &&" % node.dir)
+ continue
+
+ assert isinstance(node, (Command, Chdir))
+ cmd = node
+ if verbose:
+ if cmd.env_vars:
+ env_vars_str = ' '.join(['%s=%s' % (key, val) for key, val in cmd.env_vars.items()])
+ piped_commands_display.append("%s %s" % (env_vars_str, ' '.join(cmd.argv)))
+ else:
+ piped_commands_display.append(' '.join(cmd.argv))
+
+ if state == PIPE:
+ stdin = piped_commands[-1].stdout
+ elif cmd.stdin is not None:
+ stdin = open(cmd.stdin, "r")
+ if verbose:
+ piped_commands_display.append('< %s' % cmd.stdin)
+ files_to_close.append(stdin)
+ else:
+ stdin = None
+
+ if cmd.stdout is None:
+ stdout = None
+ elif cmd.stdout is Command.PIPE:
+ stdout = subprocess.PIPE
+ else:
+ stdout = _open_out_file(cmd.stdout)
+ files_to_close.append(stdout)
+ if verbose:
+ piped_commands_display.append('> %s' % cmd.stdout)
+
+ if cmd.stderr is None:
+ stderr = None
+ elif cmd.stderr is Command.PIPE:
+ stderr = subprocess.PIPE
+ elif cmd.stderr is Command.STDOUT:
+ stderr = subprocess.STDOUT
+ if verbose:
+ piped_commands_display.append('2>&1')
+ else:
+ stderr = _open_out_file(cmd.stderr)
+ files_to_close.append(stderr)
+ if verbose:
+ piped_commands_display.append('2> %s' % cmd.stderr)
+
+ if cmd.env_vars:
+ env = dict(os.environ)
+ env.update(cmd.env_vars)
+ else:
+ env = None
+
+ if cwd == '.':
+ proc_cwd = None
+ else:
+ proc_cwd = cwd
+
+ debug("command: subprocess.Popen(argv=%r, stdin=%r, stdout=%r, stderr=%r, env_vars=%r, cwd=%r)"
+ % (cmd.argv, stdin, stdout, stderr, cmd.env_vars, proc_cwd))
+ proc = subprocess.Popen(cmd.argv, stdin=stdin, stdout=stdout, stderr=stderr, env=env, cwd=proc_cwd)
+ del stdin, stdout, stderr
+ piped_commands.append(proc)
+
+ try:
+ next_node = pipeline.pop(0)
+ except IndexError:
+ try:
+ retval = self._exec_piped_commands(piped_commands)
+ if verbose:
+ print("%s: exit code %i" % (' '.join(piped_commands_display), retval))
+ finally:
+ for f in files_to_close:
+ if f is not dev_null:
+ f.close()
+ files_to_close = []
+ return retval
+ else:
+
+ if isinstance(next_node, Pipe):
+ state = PIPE
+ piped_commands_display.append('|')
+
+ elif isinstance(next_node, Or):
+ try:
+ this_retval = self._exec_piped_commands(piped_commands)
+ finally:
+ for f in files_to_close:
+ if f is not dev_null:
+ f.close()
+ files_to_close = []
+ if this_retval == 0:
+ if verbose:
+ print("%s: exit code %i (|| is short-circuited)" % (' '.join(piped_commands_display), retval))
+ return this_retval
+ if verbose:
+ print("%s: exit code %i (|| proceeds)" % (' '.join(piped_commands_display), retval))
+ state = BEGIN
+ piped_commands = []
+ piped_commands_display = []
+
+ elif isinstance(next_node, And):
+ try:
+ this_retval = self._exec_piped_commands(piped_commands)
+ finally:
+ for f in files_to_close:
+ if f is not dev_null:
+ f.close()
+ files_to_close = []
+ if this_retval != 0:
+ if verbose:
+ print("%s: exit code %i (&& is short-circuited)" % (' '.join(piped_commands_display), retval))
+ return this_retval
+ if verbose:
+ print("%s: exit code %i (&& proceeds)" % (' '.join(piped_commands_display), retval))
+ state = BEGIN
+ piped_commands = []
+ piped_commands_display = []
+
+
+
+def _main():
+ pipeline = Pipeline()
+ pipeline.parse('./foo.py 2>&1 < xxx | cat && ls')
+ print(pipeline.run())
+
+if __name__ == '__main__':
+ _main()
+
--- a/wscript Wed Nov 09 16:11:47 2016 +0100
+++ b/wscript Mon Nov 21 14:57:08 2016 +0900
@@ -1,7 +1,6 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
import os
-import Options
import os.path
import ns3waf
import sys
@@ -9,11 +8,12 @@
# local modules
import wutils
import subprocess
-import Logs
+from waflib import Utils, Scripting, Configure, Build, Options, TaskGen, Context, Task, Logs, Errors
from waflib.Errors import WafError
def options(opt):
- opt.tool_options('compiler_cc')
+ opt.load('compiler_c')
+ opt.load('compiler_cxx')
ns3waf.options(opt)
opt.add_option('--enable-kernel-stack',
help=('Path to the prefix where the kernel wrapper headers are installed'),
@@ -77,6 +77,15 @@
return None
def configure(conf):
+
+ conf.load('relocation', tooldir=['waf-tools'])
+ conf.load('compiler_c')
+ cc_string = '.'.join(conf.env['CC_VERSION'])
+ conf.msg('Checking for cc version',cc_string,'GREEN')
+ conf.load('compiler_cxx')
+
+ conf.load('clang_compilation_database', tooldir=['waf-tools'])
+
if Options.options.with_ns3 is not None and os.path.isdir(Options.options.with_ns3):
conf.env['NS3_DIR']= os.path.abspath(Options.options.with_ns3)
if not 'PKG_CONFIG_PATH' in os.environ:
@@ -96,7 +105,6 @@
ns3waf.check_modules(conf, ['visualizer'], mandatory = False)
ns3waf.check_modules(conf, ['applications'], mandatory = False)
ns3waf.check_modules(conf, ['fd-net-device'], mandatory = False)
- conf.check_tool('compiler_cc')
conf.check(header_name='stdint.h', define_name='HAVE_STDINT_H', mandatory=False)
conf.check(header_name='inttypes.h', define_name='HAVE_INTTYPES_H', mandatory=False)
conf.check(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H', mandatory=False)
@@ -544,11 +552,11 @@
scratches.append(dir)
for dir in submodules:
- bld.add_subdirs(os.path.join('myscripts', dir))
+ bld.recurse(os.path.join('myscripts', dir))
for dir in scratches:
if os.path.isdir(os.path.join('myscripts', dir)):
- bld.add_subdirs(os.path.join('myscripts', dir))
+ bld.recurse(os.path.join('myscripts', dir))
elif dir.endswith(".cc"):
bld.build_a_script('dce',
needed = bld.env['NS3_MODULES_FOUND'] + ['dce'],
@@ -834,7 +842,7 @@
'-Wl,--version-script=' + os.path.join('model', 'libdl.version'),
'-Wl,-soname=libdl.so.2'])
- bld.add_subdirs(['utils'])
+ bld.recurse(['utils'])
bld.recurse('bindings/python')
# Write the build status file.
--- a/wutils.py Wed Nov 09 16:11:47 2016 +0100
+++ b/wutils.py Mon Nov 21 14:57:08 2016 +0900
@@ -3,15 +3,11 @@
import sys
import subprocess
import shlex
+import re
# WAF modules
-import Options
-import Utils
-import Logs
-import TaskGen
-import Build
-import re
from waflib.Errors import WafError
+from waflib import Utils, Scripting, Configure, Build, Options, TaskGen, Context, Task, Logs, Errors
# these are set from the main wscript file
APPNAME=None