mirror of https://github.com/lukechilds/node.git
Ryan Dahl
15 years ago
25 changed files with 749 additions and 75 deletions
@ -0,0 +1,128 @@ |
|||
#!/usr/bin/env python |
|||
# encoding: utf-8 |
|||
# Thomas Nagy, 2008-2010 (ita) |
|||
|
|||
""" |
|||
Execute the tasks with gcc -MD, read the dependencies from the .d file |
|||
and prepare the dependency calculation for the next run |
|||
""" |
|||
|
|||
import os, re, threading |
|||
import Task, Logs, Utils, preproc |
|||
from TaskGen import before, after, feature |
|||
|
|||
lock = threading.Lock() |
|||
|
|||
preprocessor_flag = '-MD' |
|||
|
|||
@feature('cc') |
|||
@before('apply_core') |
|||
def add_mmd_cc(self): |
|||
if self.env.get_flat('CCFLAGS').find(preprocessor_flag) < 0: |
|||
self.env.append_value('CCFLAGS', preprocessor_flag) |
|||
|
|||
@feature('cxx') |
|||
@before('apply_core') |
|||
def add_mmd_cxx(self): |
|||
if self.env.get_flat('CXXFLAGS').find(preprocessor_flag) < 0: |
|||
self.env.append_value('CXXFLAGS', preprocessor_flag) |
|||
|
|||
def scan(self): |
|||
"the scanner does not do anything initially" |
|||
nodes = self.generator.bld.node_deps.get(self.unique_id(), []) |
|||
names = [] |
|||
return (nodes, names) |
|||
|
|||
re_o = re.compile("\.o$") |
|||
re_src = re.compile("^(\.\.)[\\/](.*)$") |
|||
|
|||
def post_run(self): |
|||
# The following code is executed by threads, it is not safe, so a lock is needed... |
|||
|
|||
if getattr(self, 'cached', None): |
|||
return Task.Task.post_run(self) |
|||
|
|||
name = self.outputs[0].abspath(self.env) |
|||
name = re_o.sub('.d', name) |
|||
txt = Utils.readf(name) |
|||
#os.unlink(name) |
|||
|
|||
txt = txt.replace('\\\n', '') |
|||
|
|||
lst = txt.strip().split(':') |
|||
val = ":".join(lst[1:]) |
|||
val = val.split() |
|||
|
|||
nodes = [] |
|||
bld = self.generator.bld |
|||
|
|||
f = re.compile("^("+self.env.variant()+"|\.\.)[\\/](.*)$") |
|||
for x in val: |
|||
if os.path.isabs(x): |
|||
|
|||
if not preproc.go_absolute: |
|||
continue |
|||
|
|||
lock.acquire() |
|||
try: |
|||
node = bld.root.find_resource(x) |
|||
finally: |
|||
lock.release() |
|||
else: |
|||
g = re.search(re_src, x) |
|||
if g: |
|||
x = g.group(2) |
|||
lock.acquire() |
|||
try: |
|||
node = bld.bldnode.parent.find_resource(x) |
|||
finally: |
|||
lock.release() |
|||
else: |
|||
g = re.search(f, x) |
|||
if g: |
|||
x = g.group(2) |
|||
lock.acquire() |
|||
try: |
|||
node = bld.srcnode.find_resource(x) |
|||
finally: |
|||
lock.release() |
|||
|
|||
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 |
|||
continue |
|||
|
|||
if not node: |
|||
raise ValueError('could not find %r for %r' % (x, self)) |
|||
else: |
|||
nodes.append(node) |
|||
|
|||
Logs.debug('deps: real scanner for %s returned %s' % (str(self), str(nodes))) |
|||
|
|||
bld.node_deps[self.unique_id()] = nodes |
|||
bld.raw_deps[self.unique_id()] = [] |
|||
|
|||
try: |
|||
del self.cache_sig |
|||
except: |
|||
pass |
|||
|
|||
Task.Task.post_run(self) |
|||
|
|||
import Constants, Utils |
|||
def sig_implicit_deps(self): |
|||
try: |
|||
return Task.Task.sig_implicit_deps(self) |
|||
except Utils.WafError: |
|||
return Constants.SIG_NIL |
|||
|
|||
for name in 'cc cxx'.split(): |
|||
try: |
|||
cls = Task.TaskBase.classes[name] |
|||
except KeyError: |
|||
pass |
|||
else: |
|||
cls.post_run = post_run |
|||
cls.scan = scan |
|||
cls.sig_implicit_deps = sig_implicit_deps |
|||
|
@ -0,0 +1,97 @@ |
|||
#!/usr/bin/env python |
|||
# encoding: utf-8 |
|||
# go.py - Waf tool for the Go programming language |
|||
# By: Tom Wambold <tom5760@gmail.com> |
|||
|
|||
import platform |
|||
|
|||
import Task |
|||
import Utils |
|||
from TaskGen import feature, extension, after |
|||
|
|||
Task.simple_task_type('gocompile', '${GOC} ${GOCFLAGS} -o ${TGT} ${SRC}', shell=False) |
|||
Task.simple_task_type('gopack', '${GOP} grc ${TGT} ${SRC}', shell=False) |
|||
Task.simple_task_type('golink', '${GOL} ${GOLFLAGS} -o ${TGT} ${SRC}', shell=False) |
|||
|
|||
def detect(conf): |
|||
|
|||
def set_def(var, val): |
|||
if not conf.env[var]: |
|||
conf.env[var] = val |
|||
|
|||
set_def('GO_PLATFORM', platform.machine()) |
|||
|
|||
if conf.env.GO_PLATFORM == 'x86_64': |
|||
set_def('GO_COMPILER', '6g') |
|||
set_def('GO_LINKER', '6l') |
|||
set_def('GO_EXTENSION', '.6') |
|||
elif conf.env.GO_PLATFORM == 'i386': |
|||
set_def('GO_COMPILER', '8g') |
|||
set_def('GO_LINKER', '8l') |
|||
set_def('GO_EXTENSION', '.8') |
|||
|
|||
if not (conf.env.GO_COMPILER or conf.env.GO_LINKER or conf.env.GO_EXTENSION): |
|||
raise conf.fatal('Unsupported platform ' + platform.machine()) |
|||
|
|||
set_def('GO_PACK', 'gopack') |
|||
set_def('GO_PACK_EXTENSION', '.a') |
|||
|
|||
conf.find_program(conf.env.GO_COMPILER, var='GOC', mandatory=True) |
|||
conf.find_program(conf.env.GO_LINKER, var='GOL', mandatory=True) |
|||
conf.find_program(conf.env.GO_PACK, var='GOP', mandatory=True) |
|||
|
|||
@extension('.go') |
|||
def compile_go(self, node): |
|||
try: |
|||
self.go_nodes.append(node) |
|||
except AttributeError: |
|||
self.go_nodes = [node] |
|||
|
|||
@feature('go') |
|||
@after('apply_core') |
|||
def apply_compile_go(self): |
|||
try: |
|||
nodes = self.go_nodes |
|||
except AttributeError: |
|||
self.go_compile_task = None |
|||
else: |
|||
self.go_compile_task = self.create_task('gocompile', |
|||
nodes, |
|||
[self.path.find_or_declare(self.target + self.env.GO_EXTENSION)]) |
|||
|
|||
@feature('gopackage', 'goprogram') |
|||
@after('apply_compile_go') |
|||
def apply_goinc(self): |
|||
if not getattr(self, 'go_compile_task', None): |
|||
return |
|||
|
|||
names = self.to_list(getattr(self, 'uselib_local', [])) |
|||
for name in names: |
|||
obj = self.name_to_obj(name) |
|||
if not obj: |
|||
raise Utils.WafError('object %r was not found in uselib_local ' |
|||
'(required by %r)' % (lib_name, self.name)) |
|||
obj.post() |
|||
self.go_compile_task.set_run_after(obj.go_package_task) |
|||
self.go_compile_task.deps_nodes.extend(obj.go_package_task.outputs) |
|||
self.env.append_unique('GOCFLAGS', '-I' + obj.path.abspath(obj.env)) |
|||
self.env.append_unique('GOLFLAGS', '-L' + obj.path.abspath(obj.env)) |
|||
|
|||
@feature('gopackage') |
|||
@after('apply_goinc') |
|||
def apply_gopackage(self): |
|||
self.go_package_task = self.create_task('gopack', |
|||
self.go_compile_task.outputs[0], |
|||
self.path.find_or_declare(self.target + self.env.GO_PACK_EXTENSION)) |
|||
self.go_package_task.set_run_after(self.go_compile_task) |
|||
self.go_package_task.deps_nodes.extend(self.go_compile_task.outputs) |
|||
|
|||
@feature('goprogram') |
|||
@after('apply_goinc') |
|||
def apply_golink(self): |
|||
self.go_link_task = self.create_task('golink', |
|||
self.go_compile_task.outputs[0], |
|||
self.path.find_or_declare(self.target)) |
|||
self.go_link_task.set_run_after(self.go_compile_task) |
|||
self.go_link_task.deps_nodes.extend(self.go_compile_task.outputs) |
|||
|
@ -0,0 +1,199 @@ |
|||
#! /usr/bin/env python |
|||
# encoding: UTF-8 |
|||
# Petar Forai |
|||
# Thomas Nagy 2008 |
|||
|
|||
import re |
|||
import Task, Utils, Logs |
|||
from TaskGen import extension, taskgen, feature, after |
|||
from Configure import conf |
|||
import preproc |
|||
|
|||
""" |
|||
Welcome in the hell of adding tasks dynamically |
|||
|
|||
swig interface files may be created at runtime, the module name may be unknown in advance |
|||
|
|||
rev 5859 is much more simple |
|||
""" |
|||
|
|||
SWIG_EXTS = ['.swig', '.i'] |
|||
|
|||
swig_str = '${SWIG} ${SWIGFLAGS} ${SRC}' |
|||
cls = Task.simple_task_type('swig', swig_str, color='BLUE', ext_in='.i .h', ext_out='.o .c .cxx', shell=False) |
|||
|
|||
def runnable_status(self): |
|||
for t in self.run_after: |
|||
if not t.hasrun: |
|||
return ASK_LATER |
|||
|
|||
if not getattr(self, 'init_outputs', None): |
|||
self.init_outputs = True |
|||
if not getattr(self, 'module', None): |
|||
# search the module name |
|||
txt = self.inputs[0].read(self.env) |
|||
m = re_module.search(txt) |
|||
if not m: |
|||
raise ValueError("could not find the swig module name") |
|||
self.module = m.group(1) |
|||
|
|||
swig_c(self) |
|||
|
|||
# add the language-specific output files as nodes |
|||
# call funs in the dict swig_langs |
|||
for x in self.env['SWIGFLAGS']: |
|||
# obtain the language |
|||
x = x[1:] |
|||
try: |
|||
fun = swig_langs[x] |
|||
except KeyError: |
|||
pass |
|||
else: |
|||
fun(self) |
|||
|
|||
return Task.Task.runnable_status(self) |
|||
setattr(cls, 'runnable_status', runnable_status) |
|||
|
|||
re_module = re.compile('%module(?:\s*\(.*\))?\s+(.+)', re.M) |
|||
|
|||
re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M) |
|||
re_2 = re.compile('%include "(.*)"', re.M) |
|||
re_3 = re.compile('#include "(.*)"', re.M) |
|||
|
|||
def scan(self): |
|||
"scan for swig dependencies, climb the .i files" |
|||
env = self.env |
|||
|
|||
lst_src = [] |
|||
|
|||
seen = [] |
|||
to_see = [self.inputs[0]] |
|||
|
|||
while to_see: |
|||
node = to_see.pop(0) |
|||
if node.id in seen: |
|||
continue |
|||
seen.append(node.id) |
|||
lst_src.append(node) |
|||
|
|||
# read the file |
|||
code = node.read(env) |
|||
code = preproc.re_nl.sub('', code) |
|||
code = preproc.re_cpp.sub(preproc.repl, code) |
|||
|
|||
# find .i files and project headers |
|||
names = re_2.findall(code) + re_3.findall(code) |
|||
for n in names: |
|||
for d in self.generator.swig_dir_nodes + [node.parent]: |
|||
u = d.find_resource(n) |
|||
if u: |
|||
to_see.append(u) |
|||
break |
|||
else: |
|||
Logs.warn('could not find %r' % n) |
|||
|
|||
# list of nodes this one depends on, and module name if present |
|||
if Logs.verbose: |
|||
Logs.debug('deps: deps for %s: %s' % (str(self), str(lst_src))) |
|||
return (lst_src, []) |
|||
cls.scan = scan |
|||
|
|||
# provide additional language processing |
|||
swig_langs = {} |
|||
def swig(fun): |
|||
swig_langs[fun.__name__.replace('swig_', '')] = fun |
|||
|
|||
def swig_c(self): |
|||
ext = '.swigwrap_%d.c' % self.generator.idx |
|||
flags = self.env['SWIGFLAGS'] |
|||
if '-c++' in flags: |
|||
ext += 'xx' |
|||
out_node = self.inputs[0].parent.find_or_declare(self.module + ext) |
|||
|
|||
if '-c++' in flags: |
|||
task = self.generator.cxx_hook(out_node) |
|||
else: |
|||
task = self.generator.cc_hook(out_node) |
|||
|
|||
task.set_run_after(self) |
|||
|
|||
ge = self.generator.bld.generator |
|||
ge.outstanding.insert(0, task) |
|||
ge.total += 1 |
|||
|
|||
try: |
|||
ltask = self.generator.link_task |
|||
except AttributeError: |
|||
pass |
|||
else: |
|||
ltask.inputs.append(task.outputs[0]) |
|||
|
|||
self.outputs.append(out_node) |
|||
|
|||
if not '-o' in self.env['SWIGFLAGS']: |
|||
self.env.append_value('SWIGFLAGS', '-o') |
|||
self.env.append_value('SWIGFLAGS', self.outputs[0].abspath(self.env)) |
|||
|
|||
@swig |
|||
def swig_python(tsk): |
|||
tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.py')) |
|||
|
|||
@swig |
|||
def swig_ocaml(tsk): |
|||
tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.ml')) |
|||
tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.mli')) |
|||
|
|||
@taskgen |
|||
@feature('swig') |
|||
@after('apply_incpaths') |
|||
def add_swig_paths(self): |
|||
"""the attribute 'after' is not used here, the method is added directly at the end""" |
|||
|
|||
self.swig_dir_nodes = self.env['INC_PATHS'] |
|||
include_flags = self.env['_CXXINCFLAGS'] or self.env['_CCINCFLAGS'] |
|||
self.env.append_unique('SWIGFLAGS', [f.replace("/I", "-I") for f in include_flags]) |
|||
|
|||
@extension(SWIG_EXTS) |
|||
def i_file(self, node): |
|||
if not 'add_swig_paths' in self.meths: |
|||
self.meths.append('add_swig_paths') |
|||
|
|||
# the task instance |
|||
tsk = self.create_task('swig') |
|||
tsk.set_inputs(node) |
|||
tsk.module = getattr(self, 'swig_module', None) |
|||
|
|||
flags = self.to_list(getattr(self, 'swig_flags', [])) |
|||
tsk.env['SWIGFLAGS'] = flags |
|||
|
|||
if not '-outdir' in flags: |
|||
flags.append('-outdir') |
|||
flags.append(node.parent.abspath(self.env)) |
|||
|
|||
@conf |
|||
def check_swig_version(conf, minver=None): |
|||
"""Check for a minimum swig version like conf.check_swig_version('1.3.28') |
|||
or conf.check_swig_version((1,3,28)) """ |
|||
reg_swig = re.compile(r'SWIG Version\s(.*)', re.M) |
|||
|
|||
swig_out = Utils.cmd_output('%s -version' % conf.env['SWIG']) |
|||
|
|||
swigver = [int(s) for s in reg_swig.findall(swig_out)[0].split('.')] |
|||
if isinstance(minver, basestring): |
|||
minver = [int(s) for s in minver.split(".")] |
|||
if isinstance(minver, tuple): |
|||
minver = [int(s) for s in minver] |
|||
result = (minver is None) or (minver[:3] <= swigver[:3]) |
|||
swigver_full = '.'.join(map(str, swigver)) |
|||
if result: |
|||
conf.env['SWIG_VERSION'] = swigver_full |
|||
minver_str = '.'.join(map(str, minver)) |
|||
if minver is None: |
|||
conf.check_message_custom('swig version', '', swigver_full) |
|||
else: |
|||
conf.check_message('swig version', '>= %s' % (minver_str,), result, option=swigver_full) |
|||
return result |
|||
|
|||
def detect(conf): |
|||
swig = conf.find_program('swig', var='SWIG', mandatory=True) |
|||
|
@ -0,0 +1,113 @@ |
|||
#! /usr/bin/env python |
|||
# encoding: UTF-8 |
|||
# Nicolas Joseph 2009 |
|||
|
|||
from fnmatch import fnmatchcase |
|||
import os, os.path, re, stat |
|||
import Task, Utils, Node, Constants |
|||
from TaskGen import feature, extension, after |
|||
from Logs import debug, warn, error |
|||
|
|||
VALADOC_STR = '${VALADOC}' |
|||
|
|||
class valadoc_task(Task.Task): |
|||
|
|||
vars = ['VALADOC', 'VALADOCFLAGS'] |
|||
color = 'BLUE' |
|||
after = 'cxx_link cc_link' |
|||
quiet = True |
|||
|
|||
output_dir = '' |
|||
doclet = '' |
|||
package_name = '' |
|||
package_version = '' |
|||
files = [] |
|||
protected = False |
|||
private = False |
|||
inherit = False |
|||
deps = False |
|||
enable_non_null_experimental = False |
|||
force = False |
|||
|
|||
def runnable_status(self): |
|||
return True |
|||
|
|||
def run(self): |
|||
if self.env['VALADOC']: |
|||
if not self.env['VALADOCFLAGS']: |
|||
self.env['VALADOCFLAGS'] = '' |
|||
cmd = [Utils.subst_vars(VALADOC_STR, self.env)] |
|||
cmd.append ('-o %s' % self.output_dir) |
|||
if getattr(self, 'doclet', None): |
|||
cmd.append ('--doclet %s' % self.doclet) |
|||
cmd.append ('--package-name %s' % self.package_name) |
|||
if getattr(self, 'version', None): |
|||
cmd.append ('--package-version %s' % self.package_version) |
|||
if getattr(self, 'packages', None): |
|||
for package in self.packages: |
|||
cmd.append ('--pkg %s' % package) |
|||
if getattr(self, 'vapi_dirs', None): |
|||
for vapi_dir in self.vapi_dirs: |
|||
cmd.append ('--vapidir %s' % vapi_dir) |
|||
if getattr(self, 'protected', None): |
|||
cmd.append ('--protected') |
|||
if getattr(self, 'private', None): |
|||
cmd.append ('--private') |
|||
if getattr(self, 'inherit', None): |
|||
cmd.append ('--inherit') |
|||
if getattr(self, 'deps', None): |
|||
cmd.append ('--deps') |
|||
if getattr(self, 'enable_non_null_experimental', None): |
|||
cmd.append ('--enable-non-null-experimental') |
|||
if getattr(self, 'force', None): |
|||
cmd.append ('--force') |
|||
cmd.append (' '.join ([x.relpath_gen (self.generator.bld.bldnode) for x in self.files])) |
|||
return self.generator.bld.exec_command(' '.join(cmd)) |
|||
else: |
|||
error ('You must install valadoc <http://live.gnome.org/Valadoc> for generate the API documentation') |
|||
return -1 |
|||
|
|||
@feature('valadoc') |
|||
def process_valadoc(self): |
|||
task = getattr(self, 'task', None) |
|||
if not task: |
|||
task = self.create_task('valadoc') |
|||
self.task = task |
|||
if getattr(self, 'output_dir', None): |
|||
task.output_dir = self.output_dir |
|||
else: |
|||
Utils.WafError('no output directory') |
|||
if getattr(self, 'doclet', None): |
|||
task.doclet = self.doclet |
|||
else: |
|||
Utils.WafError('no doclet directory') |
|||
if getattr(self, 'package_name', None): |
|||
task.package_name = self.package_name |
|||
else: |
|||
Utils.WafError('no package name') |
|||
if getattr(self, 'package_version', None): |
|||
task.package_version = self.package_version |
|||
if getattr(self, 'packages', None): |
|||
task.packages = Utils.to_list(self.packages) |
|||
if getattr(self, 'vapi_dirs', None): |
|||
task.vapi_dirs = Utils.to_list(self.vapi_dirs) |
|||
if getattr(self, 'files', None): |
|||
task.files = self.files |
|||
else: |
|||
Utils.WafError('no input file') |
|||
if getattr(self, 'protected', None): |
|||
task.protected = self.protected |
|||
if getattr(self, 'private', None): |
|||
task.private = self.private |
|||
if getattr(self, 'inherit', None): |
|||
task.inherit = self.inherit |
|||
if getattr(self, 'deps', None): |
|||
task.deps = self.deps |
|||
if getattr(self, 'enable_non_null_experimental', None): |
|||
task.enable_non_null_experimental = self.enable_non_null_experimental |
|||
if getattr(self, 'force', None): |
|||
task.force = self.force |
|||
|
|||
def detect(conf): |
|||
conf.find_program('valadoc', var='VALADOC', mandatory=False) |
|||
|
@ -0,0 +1,35 @@ |
|||
#!/usr/bin/env python |
|||
# encoding: utf-8 |
|||
# ita 2010 |
|||
|
|||
import Logs, Utils, Build, Task |
|||
|
|||
def say(txt): |
|||
Logs.warn("^o^: %s" % txt) |
|||
|
|||
try: |
|||
ret = Utils.cmd_output('which cowsay 2> /dev/null').strip() |
|||
except Exception, e: |
|||
pass |
|||
else: |
|||
def say(txt): |
|||
f = Utils.cmd_output([ret, txt]) |
|||
Utils.pprint('PINK', f) |
|||
|
|||
say('you make the errors, we detect them') |
|||
|
|||
def check_task_classes(self): |
|||
for x in Task.TaskBase.classes: |
|||
if isinstance(x, Task.Task): |
|||
if not getattr(cls, 'ext_in', None) or getattr(cls, 'before', None): |
|||
say('class %s has no precedence constraints (ext_in/before)') |
|||
if not getattr(cls, 'ext_out', None) or getattr(cls, 'after', None): |
|||
say('class %s has no precedence constraints (ext_out/after)') |
|||
|
|||
comp = Build.BuildContext.compile |
|||
def compile(self): |
|||
if not getattr(self, 'magic', None): |
|||
check_task_classes(self) |
|||
return comp(self) |
|||
Build.BuildContext.compile = compile |
|||
|
Loading…
Reference in new issue