source: swig/swig.py @ 020d80e

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 020d80e was 000b090, checked in by Paul Brossier <piem@piem.org>, 15 years ago

use waf as new build system

  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[000b090]1#! /usr/bin/env python
2# encoding: UTF-8
3# Petar Forai
4# Thomas Nagy 2008
5
6import re
7import Task, Utils, Logs
8from TaskGen import extension
9from Configure import conf
10import preproc
11
12SWIG_EXTS = ['.swig', '.i']
13
14swig_str = '${SWIG} ${SWIGFLAGS} ${SRC}'
15cls = Task.simple_task_type('swig', swig_str, color='BLUE', before='cc cxx')
16
17re_module = re.compile('%module(?:\s*\(.*\))?\s+(.+)', re.M)
18
19re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M)
20re_2 = re.compile('%include "(.*)"', re.M)
21re_3 = re.compile('#include "(.*)"', re.M)
22
23def scan(self):
24        "scan for swig dependencies, climb the .i files"
25        env = self.env
26
27        lst_src = []
28
29        seen = []
30        to_see = [self.inputs[0]]
31
32        while to_see:
33                node = to_see.pop(0)
34                if node.id in seen:
35                        continue
36                seen.append(node.id)
37                lst_src.append(node)
38
39                # read the file
40                code = node.read(env)
41                code = preproc.re_nl.sub('', code)
42                code = preproc.re_cpp.sub(preproc.repl, code)
43
44                # find .i files and project headers
45                names = re_2.findall(code) + re_3.findall(code)
46                for n in names:
47                        for d in self.generator.swig_dir_nodes + [node.parent]:
48                                u = d.find_resource(n)
49                                if u:
50                                        to_see.append(u)
51                                        break
52                        else:
53                                Logs.warn('could not find %r' % n)
54
55        # list of nodes this one depends on, and module name if present
56        if Logs.verbose:
57                Logs.debug('deps: deps for %s: %s' % (str(self), str(lst_src)))
58        return (lst_src, [])
59cls.scan = scan
60
61# provide additional language processing
62swig_langs = {}
63def swig(fun):
64        swig_langs[fun.__name__.replace('swig_', '')] = fun
65
66@swig
67def swig_python(tsk):
68        tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.py'))
69
70@swig
71def swig_ocaml(tsk):
72        tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.ml'))
73        tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.mli'))
74
75def add_swig_paths(self):
76        if getattr(self, 'add_swig_paths_done', None):
77                return
78        self.add_swig_paths_done = True
79
80        self.swig_dir_nodes = []
81        for x in self.to_list(self.includes):
82                node = self.path.find_dir(x)
83                if not node:
84                        Logs.warn('could not find the include %r' % x)
85                        continue
86                self.swig_dir_nodes.append(node)
87
88        # add the top-level, it is likely to be added
89        self.swig_dir_nodes.append(self.bld.srcnode)
90        for x in self.swig_dir_nodes:
91                self.env.append_unique('SWIGFLAGS', '-I%s' % x.abspath(self.env)) # build dir
92                self.env.append_unique('SWIGFLAGS', '-I%s' % x.abspath()) # source dir
93
94@extension(SWIG_EXTS)
95def i_file(self, node):
96        flags = self.to_list(getattr(self, 'swig_flags', []))
97
98        ext = '.swigwrap_%d.c' % self.idx
99        if '-c++' in flags:
100                ext += 'xx'
101
102        # the user might specify the module directly
103        module = getattr(self, 'swig_module', None)
104        if not module:
105                # else, open the files and search
106                txt = node.read(self.env)
107                m = re_module.search(txt)
108                if not m:
109                        raise "for now we are expecting a module name in the main swig file"
110                module = m.group(1)
111        out_node = node.parent.find_or_declare(module + ext)
112
113        # the task instance
114        tsk = self.create_task('swig')
115        tsk.set_inputs(node)
116        tsk.set_outputs(out_node)
117        tsk.module = module
118        tsk.env['SWIGFLAGS'] = flags
119
120        if not '-outdir' in flags:
121                flags.append('-outdir')
122                flags.append(node.parent.abspath(self.env))
123
124        if not '-o' in flags:
125                flags.append('-o')
126                flags.append(out_node.abspath(self.env))
127
128        # add the language-specific output files as nodes
129        # call funs in the dict swig_langs
130        for x in flags:
131                # obtain the language
132                x = x[1:]
133                try:
134                        fun = swig_langs[x]
135                except KeyError:
136                        pass
137                else:
138                        fun(tsk)
139
140        self.allnodes.append(out_node)
141
142        add_swig_paths(self)
143
144@conf
145def check_swig_version(conf, minver=None):
146        """Check for a minimum swig version  like conf.check_swig_version('1.3.28')
147        or conf.check_swig_version((1,3,28)) """
148        reg_swig = re.compile(r'SWIG Version\s(.*)', re.M)
149
150        swig_out = Utils.cmd_output('%s -version' % conf.env['SWIG'])
151
152        swigver = [int(s) for s in reg_swig.findall(swig_out)[0].split('.')]
153        if isinstance(minver, basestring):
154                minver = [int(s) for s in minver.split(".")]
155        if isinstance(minver, tuple):
156                minver = [int(s) for s in minver]
157        result = (minver is None) or (minver[:3] <= swigver[:3])
158        swigver_full = '.'.join(map(str, swigver))
159        if result:
160                conf.env['SWIG_VERSION'] = swigver_full
161        minver_str = '.'.join(map(str, minver))
162        if minver is None:
163                conf.check_message_custom('swig version', '', swigver_full)
164        else:
165                conf.check_message('swig version', '>= %s' % (minver_str,), result, option=swigver_full)
166        return result
167
168def detect(conf):
169        swig = conf.find_program('swig', var='SWIG', mandatory=True)
170
Note: See TracBrowser for help on using the repository browser.