Skip to content

Commit

Permalink
Upgrade to upstream WAF 1.5.9 plus a bunch of 'waf tools' layered on …
Browse files Browse the repository at this point in the history
…top.
  • Loading branch information
Gustavo J. A. M. Carneiro committed Sep 21, 2009
1 parent 81fc7f1 commit 023fa2e
Show file tree
Hide file tree
Showing 6 changed files with 744 additions and 0 deletions.
Binary file modified waf
100755 → 100644
Binary file not shown.
192 changes: 192 additions & 0 deletions waf-tools/cflags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import Logs
import Options
import 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,
}

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 set_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 set in the environment. [Allowed Values: %s]"
% ", ".join([repr(p) for p in profiles.keys()])),
choices=profiles.keys(),
dest='build_profile')

def detect(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)
134 changes: 134 additions & 0 deletions waf-tools/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
from TaskGen import feature, taskgen, before, task_gen
import Node, Task, Utils, Build, pproc, Constants
import Options

import shellcmd
shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy

from Logs import debug, error
shellcmd.debug = debug

import Task

import re


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, normal=1, generator=generator)

def __str__(self):
"string to display to the user"
env = self.env
src_str = ' '.join([a.nice_path(env) for a in self.inputs])
tgt_str = ' '.join([a.nice_path(env) 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.bldpath(self.env)
elif var == 'SRC':
return result.srcpath(self.env)
else:
raise ValueError("Bad subst variable %r" % var)
elif result is self.inputs:
if len(self.inputs) == 1:
return result[0].srcpath(self.env)
else:
raise ValueError("${SRC} requested but have multiple sources; which one?")
elif result is self.outputs:
if len(self.outputs) == 1:
return result[0].bldpath(self.env)
else:
raise ValueError("${TGT} requested but have multiple targets; which one?")
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, basestring):
cmd.stdin = self._subst_arg(cmd.stdin, 'in', namespace)
if isinstance(cmd.stdout, basestring):
cmd.stdout = self._subst_arg(cmd.stdout, 'out', namespace)
if isinstance(cmd.stderr, basestring):
cmd.stderr = self._subst_arg(cmd.stderr, 'out', namespace)
for argI in xrange(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.iteritems():
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
@feature('command')
def init_command(self):
Utils.def_attrs(self,
# other variables that can be used in the command: ${VARIABLE}
variables = None)



@taskgen
@feature('command')
@before('apply_core')
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 src in self.to_list(self.source):
node = self.path.find_resource(src)
if node is None:
raise Utils.WafError("source %s not found" % src)
inputs.append(node)
task.set_inputs(inputs)
task.set_outputs([self.path.find_or_declare(tgt) for tgt in self.to_list(self.target)])
#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')
71 changes: 71 additions & 0 deletions waf-tools/pkgconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- mode: python; encoding: utf-8 -*-
# Gustavo Carneiro (gjamc) 2008

import Options
import Configure
import pproc as subprocess
import config_c

def detect(conf):
pkg_config = conf.find_program('pkg-config', var='PKG_CONFIG')
if not pkg_config: return

@Configure.conf
def pkg_check_modules(conf, uselib_name, expression, mandatory=True):
pkg_config = conf.env['PKG_CONFIG']
if not pkg_config:
if mandatory:
conf.fatal("pkg-config is not available")
else:
return False

argv = [pkg_config, '--cflags', '--libs', expression]
cmd = subprocess.Popen(argv, stdout=subprocess.PIPE)
out, dummy = cmd.communicate()
retval = cmd.wait()

msg_checking = ("pkg-config flags for %s" % (uselib_name,))
if Options.options.verbose:
if retval == 0:
conf.check_message_custom(msg_checking,
('(%s)' % expression), out)
else:
conf.check_message(msg_checking, ('(%s)' % expression), False)
else:
conf.check_message(msg_checking, '', (retval == 0), '')
conf.log.write('%r: %r (exit code %i)\n' % (argv, out, retval))

if retval == 0:

config_c.parse_flags(out, uselib_name, conf.env)
conf.env[uselib_name] = True
return True

else:

conf.env[uselib_name] = False
if mandatory:
raise Configure.ConfigurationError('pkg-config check failed')
else:
return False

@Configure.conf
def pkg_check_module_variable(conf, module, variable):
pkg_config = conf.env['PKG_CONFIG']
if not pkg_config:
conf.fatal("pkg-config is not available")

argv = [pkg_config, '--variable', variable, module]
cmd = subprocess.Popen(argv, stdout=subprocess.PIPE)
out, dummy = cmd.communicate()
retval = cmd.wait()
out = out.rstrip() # strip the trailing newline

msg_checking = ("pkg-config variable %r in %s" % (variable, module,))
conf.check_message_custom(msg_checking, '', out)
conf.log.write('%r: %r (exit code %i)\n' % (argv, out, retval))

if retval == 0:
return out
else:
raise Configure.ConfigurationError('pkg-config check failed')
Loading

0 comments on commit 023fa2e

Please sign in to comment.