~ubuntu-branches/ubuntu/quantal/ns3/quantal

« back to all changes in this revision

Viewing changes to ns-3.13/waf-tools/boost.py

  • Committer: Package Import Robot
  • Author(s): YunQiang Su, Aron Xu, YunQiang Su, Upstream
  • Date: 2012-01-06 00:35:42 UTC
  • mfrom: (10.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20120106003542-vcn5g03mhapm991h
Tags: 3.13+dfsg-1
[ Aron Xu ]:
        add tag binary and binary-indep, 
  for not build doc when --binary-arch (Closes: #654493).
[ YunQiang Su ]
        add waf 1.5/1.6 source to debian directory, 
  and build waf from there (Closes: #642217).
[ Upstream ]
  Successfully link with --as-needed option (Closes: #642225).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# encoding: utf-8
 
3
#
 
4
# partially based on boost.py written by Gernot Vormayr
 
5
# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
 
6
# modified by Bjoern Michaelsen, 2008
 
7
# modified by Luca Fossati, 2008
 
8
# rewritten for waf 1.5.1, Thomas Nagy, 2008
 
9
# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
 
10
 
 
11
'''
 
12
To add the boost tool to the waf file:
 
13
$ ./waf-light --tools=compat15,boost
 
14
        or, if you have waf >= 1.6.2
 
15
$ ./waf update --files=boost
 
16
 
 
17
The wscript will look like:
 
18
 
 
19
def options(opt):
 
20
        opt.load('compiler_cxx boost')
 
21
 
 
22
def configure(conf):
 
23
        conf.load('compiler_cxx boost')
 
24
        conf.check_boost(lib='system filesystem', mt=True, static=True)
 
25
 
 
26
def build(bld):
 
27
        bld(source='main.cpp', target='app', use='BOOST')
 
28
'''
 
29
 
 
30
import sys
 
31
import re
 
32
from waflib import Utils, Logs
 
33
from waflib.Configure import conf
 
34
from waflib.Errors import WafError
 
35
 
 
36
BOOST_LIBS = ('/usr/lib', '/usr/local/lib',
 
37
                          '/opt/local/lib', '/sw/lib', '/lib')
 
38
BOOST_INCLUDES = ('/usr/include', '/usr/local/include',
 
39
                                  '/opt/local/include', '/sw/include')
 
40
BOOST_VERSION_FILE = 'boost/version.hpp'
 
41
BOOST_VERSION_CODE = '''
 
42
#include <iostream>
 
43
#include <boost/version.hpp>
 
44
int main() { std::cout << BOOST_LIB_VERSION << std::endl; }
 
45
'''
 
46
 
 
47
# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
 
48
PLATFORM = Utils.unversioned_sys_platform()
 
49
detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
 
50
detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
 
51
detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
 
52
BOOST_TOOLSETS = {
 
53
        'borland':  'bcb',
 
54
        'clang':        detect_clang,
 
55
        'como':  'como',
 
56
        'cw':      'cw',
 
57
        'darwin':   'xgcc',
 
58
        'edg':    'edg',
 
59
        'g++':    detect_mingw,
 
60
        'gcc':    detect_mingw,
 
61
        'icpc':  detect_intel,
 
62
        'intel':        detect_intel,
 
63
        'kcc':    'kcc',
 
64
        'kylix':        'bck',
 
65
        'mipspro':  'mp',
 
66
        'mingw':        'mgw',
 
67
        'msvc':  'vc',
 
68
        'qcc':    'qcc',
 
69
        'sun':    'sw',
 
70
        'sunc++':   'sw',
 
71
        'tru64cxx': 'tru',
 
72
        'vacpp':        'xlc'
 
73
}
 
74
 
 
75
 
 
76
def options(opt):
 
77
        opt.add_option('--boost-includes', type='string',
 
78
                                   default='', dest='boost_includes',
 
79
                                   help='''path to the boost directory where the includes are
 
80
                                   e.g. /boost_1_45_0/include''')
 
81
        opt.add_option('--boost-libs', type='string',
 
82
                                   default='', dest='boost_libs',
 
83
                                   help='''path to the directory where the boost libs are
 
84
                                   e.g. /boost_1_45_0/stage/lib''')
 
85
        opt.add_option('--boost-static', action='store_true',
 
86
                                   default=False, dest='boost_static',
 
87
                                   help='link static libraries')
 
88
        opt.add_option('--boost-mt', action='store_true',
 
89
                                   default=False, dest='boost_mt',
 
90
                                   help='select multi-threaded libraries')
 
91
        opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
 
92
                                   help='''select libraries with tags (dgsyp, d for debug),
 
93
                                   see doc Boost, Getting Started, chapter 6.1''')
 
94
        opt.add_option('--boost-toolset', type='string',
 
95
                                   default='', dest='boost_toolset',
 
96
                                   help='force a toolset e.g. msvc, vc90, \
 
97
                                                gcc, mingw, mgw45 (default: auto)')
 
98
        py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
 
99
        opt.add_option('--boost-python', type='string',
 
100
                                   default=py_version, dest='boost_python',
 
101
                                   help='select the lib python with this version \
 
102
                                                (default: %s)' % py_version)
 
103
 
 
104
 
 
105
@conf
 
106
def __boost_get_version_file(self, dir):
 
107
        try:
 
108
                return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE)
 
109
        except:
 
110
                return None
 
111
 
 
112
 
 
113
@conf
 
114
def boost_get_version(self, dir):
 
115
        """silently retrieve the boost version number"""
 
116
        re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M)
 
117
        try:
 
118
                val = re_but.search(self.__boost_get_version_file(dir).read()).group(1)
 
119
        except:
 
120
                val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir],
 
121
                                                         execute=True, define_ret=True)
 
122
        return val
 
123
 
 
124
 
 
125
@conf
 
126
def boost_get_includes(self, *k, **kw):
 
127
        includes = k and k[0] or kw.get('includes', None)
 
128
        if includes and self.__boost_get_version_file(includes):
 
129
                return includes
 
130
        for dir in BOOST_INCLUDES:
 
131
                if self.__boost_get_version_file(dir):
 
132
                        return dir
 
133
        if includes:
 
134
                self.fatal('headers not found in %s' % includes)
 
135
        else:
 
136
                self.fatal('headers not found, use --boost-includes=/path/to/boost')
 
137
 
 
138
 
 
139
@conf
 
140
def boost_get_toolset(self, cc):
 
141
        toolset = cc
 
142
        if not cc:
 
143
                build_platform = Utils.unversioned_sys_platform()
 
144
                if build_platform in BOOST_TOOLSETS:
 
145
                        cc = build_platform
 
146
                else:
 
147
                        cc = self.env.CXX_NAME
 
148
        if cc in BOOST_TOOLSETS:
 
149
                toolset = BOOST_TOOLSETS[cc]
 
150
        return isinstance(toolset, str) and toolset or toolset(self.env)
 
151
 
 
152
 
 
153
@conf
 
154
def __boost_get_libs_path(self, *k, **kw):
 
155
        ''' return the lib path and all the files in it '''
 
156
        if 'files' in kw:
 
157
                return self.root.find_dir('.'), Utils.to_list(kw['files'])
 
158
        libs = k and k[0] or kw.get('libs', None)
 
159
        if libs:
 
160
                path = self.root.find_dir(libs)
 
161
                files = path.ant_glob('*boost_*')
 
162
        if not libs or not files:
 
163
                for dir in BOOST_LIBS:
 
164
                        try:
 
165
                                path = self.root.find_dir(dir)
 
166
                                files = path.ant_glob('*boost_*')
 
167
                                if files:
 
168
                                        break
 
169
                                path = self.root.find_dir(dir + '64')
 
170
                                files = path.ant_glob('*boost_*')
 
171
                                if files:
 
172
                                        break
 
173
                        except:
 
174
                                path = None
 
175
        if not path:
 
176
                if libs:
 
177
                        self.fatal('libs not found in %s' % libs)
 
178
                else:
 
179
                        self.fatal('libs not found, \
 
180
                                           use --boost-includes=/path/to/boost/lib')
 
181
        return path, files
 
182
 
 
183
 
 
184
@conf
 
185
def boost_get_libs(self, *k, **kw):
 
186
        '''
 
187
        return the lib path and the required libs
 
188
        according to the parameters
 
189
        '''
 
190
        path, files = self.__boost_get_libs_path(**kw)
 
191
        t = []
 
192
        if kw.get('mt', False):
 
193
                t.append('mt')
 
194
        if kw.get('abi', None):
 
195
                t.append(kw['abi'])
 
196
        tags = t and '(-%s)+' % '-'.join(t) or ''
 
197
        toolset = '(-%s[0-9]{0,3})+' % self.boost_get_toolset(kw.get('toolset', ''))
 
198
        version = '(-%s)+' % self.env.BOOST_VERSION
 
199
 
 
200
        def find_lib(re_lib, files):
 
201
                for file in files:
 
202
                        if re_lib.search(file.name):
 
203
                                return file
 
204
                return None
 
205
 
 
206
        def format_lib_name(name):
 
207
                if name.startswith('lib'):
 
208
                        name = name[3:]
 
209
                return name.split('.')[0]
 
210
 
 
211
        libs = []
 
212
        for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
 
213
                py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
 
214
                # Trying libraries, from most strict match to least one
 
215
                for pattern in ['boost_%s%s%s%s%s' % (lib, toolset, tags, py, version),
 
216
                                                'boost_%s%s%s%s' % (lib, tags, py, version),
 
217
                                                'boost_%s%s%s' % (lib, tags, version),
 
218
                                                # Give up trying to find the right version
 
219
                                                'boost_%s%s%s%s' % (lib, toolset, tags, py),
 
220
                                                'boost_%s%s%s' % (lib, tags, py),
 
221
                                                'boost_%s%s' % (lib, tags)]:
 
222
                        file = find_lib(re.compile(pattern), files)
 
223
                        if file:
 
224
                                libs.append(format_lib_name(file.name))
 
225
                                break
 
226
                else:
 
227
                        self.fatal('lib %s not found in %s' % (lib, path))
 
228
 
 
229
        return path.abspath(), libs
 
230
 
 
231
 
 
232
@conf
 
233
def check_boost(self, *k, **kw):
 
234
        """
 
235
        initialize boost
 
236
 
 
237
        You can pass the same parameters as the command line (without "--boost-"),
 
238
        but the command line has the priority.
 
239
        """
 
240
        if not self.env['CXX']:
 
241
                self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
 
242
 
 
243
        params = {'lib': k and k[0] or kw.get('lib', None)}
 
244
        for key, value in self.options.__dict__.items():
 
245
                if not key.startswith('boost_'):
 
246
                        continue
 
247
                key = key[len('boost_'):]
 
248
                params[key] = value and value or kw.get(key, '')
 
249
 
 
250
        var = kw.get('uselib_store', 'BOOST')
 
251
 
 
252
        self.start_msg('Checking boost includes')
 
253
        try:
 
254
                self.env['INCLUDES_%s' % var] = self.boost_get_includes(**params)
 
255
                self.env.BOOST_VERSION = self.boost_get_version(self.env['INCLUDES_%s' % var])
 
256
        except WafError:
 
257
                self.end_msg("not found", 'YELLOW')
 
258
                raise
 
259
        self.end_msg(self.env.BOOST_VERSION)
 
260
        if Logs.verbose:
 
261
                Logs.pprint('CYAN', '   path : %s' % self.env['INCLUDES_%s' % var])
 
262
 
 
263
        if not params['lib']:
 
264
                return
 
265
        self.start_msg('Checking boost libs')
 
266
        try:
 
267
                suffix = params.get('static', 'ST') or ''
 
268
                path, libs = self.boost_get_libs(**params)
 
269
        except WafError:
 
270
                self.end_msg("not found", 'YELLOW')
 
271
                raise
 
272
        self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
 
273
        self.env['%sLIB_%s' % (suffix, var)] = libs
 
274
        self.end_msg('ok')
 
275
        if Logs.verbose:
 
276
                Logs.pprint('CYAN', '   path : %s' % path)
 
277
                Logs.pprint('CYAN', '   libs : %s' % libs)
 
278