diff options
Diffstat (limited to 'waflib/extras/stracedeps.py')
m--------- | waflib | 0 | ||||
-rw-r--r-- | waflib/extras/stracedeps.py | 174 |
2 files changed, 0 insertions, 174 deletions
diff --git a/waflib b/waflib new file mode 160000 +Subproject 2314e236ca6e7d94a26c3c17091da0f25f5867f diff --git a/waflib/extras/stracedeps.py b/waflib/extras/stracedeps.py deleted file mode 100644 index 37d82cb..0000000 --- a/waflib/extras/stracedeps.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2015 (ita) - -""" -Execute tasks through strace to obtain dependencies after the process is run. This -scheme is similar to that of the Fabricate script. - -To use:: - - def configure(conf): - conf.load('strace') - -WARNING: -* This will not work when advanced scanners are needed (qt4/qt5) -* The overhead of running 'strace' is significant (56s -> 1m29s) -* It will not work on Windows :-) -""" - -import os, re, threading -from waflib import Task, Logs, Utils - -#TRACECALLS = 'trace=access,chdir,clone,creat,execve,exit_group,fork,lstat,lstat64,mkdir,open,rename,stat,stat64,symlink,vfork' -TRACECALLS = 'trace=process,file' - -BANNED = ('/tmp', '/proc', '/sys', '/dev') - -s_process = r'(?:clone|fork|vfork)\(.*?(?P<npid>\d+)' -s_file = r'(?P<call>\w+)\("(?P<path>([^"\\]|\\.)*)"(.*)' -re_lines = re.compile(r'^(?P<pid>\d+)\s+(?:(?:%s)|(?:%s))\r*$' % (s_file, s_process), re.IGNORECASE | re.MULTILINE) -strace_lock = threading.Lock() - -def configure(conf): - conf.find_program('strace') - -def task_method(func): - # Decorator function to bind/replace methods on the base Task class - # - # The methods Task.exec_command and Task.sig_implicit_deps already exists and are rarely overridden - # we thus expect that we are the only ones doing this - try: - setattr(Task.Task, 'nostrace_%s' % func.__name__, getattr(Task.Task, func.__name__)) - except AttributeError: - pass - setattr(Task.Task, func.__name__, func) - return func - -@task_method -def get_strace_file(self): - try: - return self.strace_file - except AttributeError: - pass - - if self.outputs: - ret = self.outputs[0].abspath() + '.strace' - else: - ret = '%s%s%d%s' % (self.generator.bld.bldnode.abspath(), os.sep, id(self), '.strace') - self.strace_file = ret - return ret - -@task_method -def get_strace_args(self): - return (self.env.STRACE or ['strace']) + ['-e', TRACECALLS, '-f', '-o', self.get_strace_file()] - -@task_method -def exec_command(self, cmd, **kw): - bld = self.generator.bld - if not 'cwd' in kw: - kw['cwd'] = self.get_cwd() - - args = self.get_strace_args() - fname = self.get_strace_file() - if isinstance(cmd, list): - cmd = args + cmd - else: - cmd = '%s %s' % (' '.join(args), cmd) - - try: - ret = bld.exec_command(cmd, **kw) - finally: - if not ret: - self.parse_strace_deps(fname, kw['cwd']) - return ret - -@task_method -def sig_implicit_deps(self): - # bypass the scanner functions - return - -@task_method -def parse_strace_deps(self, path, cwd): - # uncomment the following line to disable the dependencies and force a file scan - # return - try: - cnt = Utils.readf(path) - finally: - try: - os.remove(path) - except OSError: - pass - - if not isinstance(cwd, str): - cwd = cwd.abspath() - - nodes = [] - bld = self.generator.bld - try: - cache = bld.strace_cache - except AttributeError: - cache = bld.strace_cache = {} - - # chdir and relative paths - pid_to_cwd = {} - - global BANNED - done = set() - for m in re.finditer(re_lines, cnt): - # scraping the output of strace - pid = m.group('pid') - if m.group('npid'): - npid = m.group('npid') - pid_to_cwd[npid] = pid_to_cwd.get(pid, cwd) - continue - - p = m.group('path').replace('\\"', '"') - - if p == '.' or m.group().find('= -1 ENOENT') > -1: - # just to speed it up a bit - continue - - if not os.path.isabs(p): - p = os.path.join(pid_to_cwd.get(pid, cwd), p) - - call = m.group('call') - if call == 'chdir': - pid_to_cwd[pid] = p - continue - - if p in done: - continue - done.add(p) - - for x in BANNED: - if p.startswith(x): - break - else: - if p.endswith('/') or os.path.isdir(p): - continue - - try: - node = cache[p] - except KeyError: - strace_lock.acquire() - try: - cache[p] = node = bld.root.find_node(p) - if not node: - continue - finally: - strace_lock.release() - nodes.append(node) - - # record the dependencies then force the task signature recalculation for next time - if Logs.verbose: - Logs.debug('deps: real scanner for %r returned %r', self, nodes) - bld = self.generator.bld - bld.node_deps[self.uid()] = nodes - bld.raw_deps[self.uid()] = [] - try: - del self.cache_sig - except AttributeError: - pass - self.signature() - |