~jtaylor/ubuntu/precise/python-numpy/multiarch-fix-818867

« back to all changes in this revision

Viewing changes to .pc/changeset_r8510.diff/numpy/core/setup.py

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-10-07 10:19:13 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101007101913-8b1kmt8ho4upcl9s
Tags: 1:1.4.1-5
* debian/patches/10_use_local_python.org_object.inv_sphinx.diff
  - fixed small typo in description
* debian/patches/changeset_r8364.diff
  - fix memory corruption (double free); thanks to Joseph Barillari for the
    report and to Michael Gilbert for pushing resolution; Closes: #581058

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import imp
 
2
import os
 
3
import sys
 
4
import shutil
 
5
from os.path import join
 
6
from numpy.distutils import log
 
7
from distutils.dep_util import newer
 
8
from distutils.sysconfig import get_config_var
 
9
import warnings
 
10
import re
 
11
 
 
12
from setup_common import *
 
13
 
 
14
# Set to True to enable multiple file compilations (experimental)
 
15
try:
 
16
    os.environ['NPY_SEPARATE_COMPILATION']
 
17
    ENABLE_SEPARATE_COMPILATION = True
 
18
except KeyError:
 
19
    ENABLE_SEPARATE_COMPILATION = False
 
20
 
 
21
# XXX: ugly, we use a class to avoid calling twice some expensive functions in
 
22
# config.h/numpyconfig.h. I don't see a better way because distutils force
 
23
# config.h generation inside an Extension class, and as such sharing
 
24
# configuration informations between extensions is not easy.
 
25
# Using a pickled-based memoize does not work because config_cmd is an instance
 
26
# method, which cPickle does not like.
 
27
try:
 
28
    import cPickle as _pik
 
29
except ImportError:
 
30
    import pickle as _pik
 
31
import copy
 
32
 
 
33
class CallOnceOnly(object):
 
34
    def __init__(self):
 
35
        self._check_types = None
 
36
        self._check_ieee_macros = None
 
37
        self._check_complex = None
 
38
 
 
39
    def check_types(self, *a, **kw):
 
40
        if self._check_types is None:
 
41
            out = check_types(*a, **kw)
 
42
            self._check_types = _pik.dumps(out)
 
43
        else:
 
44
            out = copy.deepcopy(_pik.loads(self._check_types))
 
45
        return out
 
46
 
 
47
    def check_ieee_macros(self, *a, **kw):
 
48
        if self._check_ieee_macros is None:
 
49
            out = check_ieee_macros(*a, **kw)
 
50
            self._check_ieee_macros = _pik.dumps(out)
 
51
        else:
 
52
            out = copy.deepcopy(_pik.loads(self._check_ieee_macros))
 
53
        return out
 
54
 
 
55
    def check_complex(self, *a, **kw):
 
56
        if self._check_complex is None:
 
57
            out = check_complex(*a, **kw)
 
58
            self._check_complex = _pik.dumps(out)
 
59
        else:
 
60
            out = copy.deepcopy(_pik.loads(self._check_complex))
 
61
        return out
 
62
 
 
63
PYTHON_HAS_UNICODE_WIDE = True
 
64
 
 
65
def pythonlib_dir():
 
66
    """return path where libpython* is."""
 
67
    if sys.platform == 'win32':
 
68
        return os.path.join(sys.prefix, "libs")
 
69
    else:
 
70
        return get_config_var('LIBDIR')
 
71
 
 
72
def is_npy_no_signal():
 
73
    """Return True if the NPY_NO_SIGNAL symbol must be defined in configuration
 
74
    header."""
 
75
    return sys.platform == 'win32'
 
76
 
 
77
def is_npy_no_smp():
 
78
    """Return True if the NPY_NO_SMP symbol must be defined in public
 
79
    header (when SMP support cannot be reliably enabled)."""
 
80
    # Python 2.3 causes a segfault when
 
81
    #  trying to re-acquire the thread-state
 
82
    #  which is done in error-handling
 
83
    #  ufunc code.  NPY_ALLOW_C_API and friends
 
84
    #  cause the segfault. So, we disable threading
 
85
    #  for now.
 
86
    if sys.version[:5] < '2.4.2':
 
87
        nosmp = 1
 
88
    else:
 
89
        # Perhaps a fancier check is in order here.
 
90
        #  so that threads are only enabled if there
 
91
        #  are actually multiple CPUS? -- but
 
92
        #  threaded code can be nice even on a single
 
93
        #  CPU so that long-calculating code doesn't
 
94
        #  block.
 
95
        try:
 
96
            nosmp = os.environ['NPY_NOSMP']
 
97
            nosmp = 1
 
98
        except KeyError:
 
99
            nosmp = 0
 
100
    return nosmp == 1
 
101
 
 
102
def win32_checks(deflist):
 
103
    from numpy.distutils.misc_util import get_build_architecture
 
104
    a = get_build_architecture()
 
105
 
 
106
    # Distutils hack on AMD64 on windows
 
107
    print 'BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' % \
 
108
          (a, os.name, sys.platform)
 
109
    if a == 'AMD64':
 
110
        deflist.append('DISTUTILS_USE_SDK')
 
111
 
 
112
    # On win32, force long double format string to be 'g', not
 
113
    # 'Lg', since the MS runtime does not support long double whose
 
114
    # size is > sizeof(double)
 
115
    if a == "Intel" or a == "AMD64":
 
116
        deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
 
117
 
 
118
def check_math_capabilities(config, moredefs, mathlibs):
 
119
    def check_func(func_name):
 
120
        return config.check_func(func_name, libraries=mathlibs,
 
121
                                 decl=True, call=True)
 
122
 
 
123
    def check_funcs_once(funcs_name):
 
124
        decl = dict([(f, True) for f in funcs_name])
 
125
        st = config.check_funcs_once(funcs_name, libraries=mathlibs,
 
126
                                     decl=decl, call=decl)
 
127
        if st:
 
128
            moredefs.extend([fname2def(f) for f in funcs_name])
 
129
        return st
 
130
 
 
131
    def check_funcs(funcs_name):
 
132
        # Use check_funcs_once first, and if it does not work, test func per
 
133
        # func. Return success only if all the functions are available
 
134
        if not check_funcs_once(funcs_name):
 
135
            # Global check failed, check func per func
 
136
            for f in funcs_name:
 
137
                if check_func(f):
 
138
                    moredefs.append(fname2def(f))
 
139
            return 0
 
140
        else:
 
141
            return 1
 
142
 
 
143
    #use_msvc = config.check_decl("_MSC_VER")
 
144
 
 
145
    if not check_funcs_once(MANDATORY_FUNCS):
 
146
        raise SystemError("One of the required function to build numpy is not"
 
147
                " available (the list is %s)." % str(MANDATORY_FUNCS))
 
148
 
 
149
    # Standard functions which may not be available and for which we have a
 
150
    # replacement implementation. Note that some of these are C99 functions.
 
151
 
 
152
    # XXX: hack to circumvent cpp pollution from python: python put its
 
153
    # config.h in the public namespace, so we have a clash for the common
 
154
    # functions we test. We remove every function tested by python's
 
155
    # autoconf, hoping their own test are correct
 
156
    if sys.version_info[:2] >= (2, 5):
 
157
        for f in OPTIONAL_STDFUNCS_MAYBE:
 
158
            if config.check_decl(fname2def(f),
 
159
                        headers=["Python.h", "math.h"]):
 
160
                OPTIONAL_STDFUNCS.remove(f)
 
161
 
 
162
    check_funcs(OPTIONAL_STDFUNCS)
 
163
 
 
164
    # C99 functions: float and long double versions
 
165
    check_funcs(C99_FUNCS_SINGLE)
 
166
    check_funcs(C99_FUNCS_EXTENDED)
 
167
 
 
168
def check_complex(config, mathlibs):
 
169
    priv = []
 
170
    pub = []
 
171
 
 
172
    # Check for complex support
 
173
    st = config.check_header('complex.h')
 
174
    if st:
 
175
        priv.append('HAVE_COMPLEX_H')
 
176
        pub.append('NPY_USE_C99_COMPLEX')
 
177
 
 
178
        for t in C99_COMPLEX_TYPES:
 
179
            st = config.check_type(t, headers=["complex.h"])
 
180
            if st:
 
181
                pub.append(('NPY_HAVE_%s' % type2def(t), 1))
 
182
 
 
183
        def check_prec(prec):
 
184
            flist = [f + prec for f in C99_COMPLEX_TYPES]
 
185
            if not config.check_funcs_once(flist):
 
186
                for f in flist:
 
187
                    if config.check_func(f):
 
188
                        priv.append(fname2def(f))
 
189
 
 
190
    return priv, pub
 
191
 
 
192
def check_ieee_macros(config):
 
193
    priv = []
 
194
    pub = []
 
195
 
 
196
    macros = []
 
197
 
 
198
    # XXX: hack to circumvent cpp pollution from python: python put its
 
199
    # config.h in the public namespace, so we have a clash for the common
 
200
    # functions we test. We remove every function tested by python's
 
201
    # autoconf, hoping their own test are correct
 
202
    _macros = ["isnan", "isinf", "signbit", "isfinite"]
 
203
    if sys.version_info[:2] >= (2, 6):
 
204
        for f in _macros:
 
205
            st = config.check_decl(fname2def("decl_%s" % f),
 
206
                    headers=["Python.h", "math.h"])
 
207
            if not st:
 
208
                macros.append(f)
 
209
    else:
 
210
        macros = _macros[:]
 
211
    # Normally, isnan and isinf are macro (C99), but some platforms only have
 
212
    # func, or both func and macro version. Check for macro only, and define
 
213
    # replacement ones if not found.
 
214
    # Note: including Python.h is necessary because it modifies some math.h
 
215
    # definitions
 
216
    for f in macros:
 
217
        st = config.check_decl(f, headers = ["Python.h", "math.h"])
 
218
        if st:
 
219
            priv.append(fname2def("decl_%s" % f))
 
220
            pub.append('NPY_%s' % fname2def("decl_%s" % f))
 
221
 
 
222
    return priv, pub
 
223
 
 
224
def check_types(config_cmd, ext, build_dir):
 
225
    private_defines = []
 
226
    public_defines = []
 
227
 
 
228
    # Expected size (in number of bytes) for each type. This is an
 
229
    # optimization: those are only hints, and an exhaustive search for the size
 
230
    # is done if the hints are wrong.
 
231
    expected = {}
 
232
    expected['short'] = [2]
 
233
    expected['int'] = [4]
 
234
    expected['long'] = [8, 4]
 
235
    expected['float'] = [4]
 
236
    expected['double'] = [8]
 
237
    expected['long double'] = [8, 12, 16]
 
238
    expected['Py_intptr_t'] = [4, 8]
 
239
    expected['PY_LONG_LONG'] = [8]
 
240
    expected['long long'] = [8]
 
241
 
 
242
    # Check we have the python header (-dev* packages on Linux)
 
243
    result = config_cmd.check_header('Python.h')
 
244
    if not result:
 
245
        raise SystemError(
 
246
                "Cannot compiler 'Python.h'. Perhaps you need to "\
 
247
                "install python-dev|python-devel.")
 
248
 
 
249
    # Check basic types sizes
 
250
    for type in ('short', 'int', 'long'):
 
251
        res = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), headers = ["Python.h"])
 
252
        if res:
 
253
            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), "SIZEOF_%s" % sym2def(type)))
 
254
        else:
 
255
            res = config_cmd.check_type_size(type, expected=expected[type])
 
256
            if res >= 0:
 
257
                public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
 
258
            else:
 
259
                raise SystemError("Checking sizeof (%s) failed !" % type)
 
260
 
 
261
    for type in ('float', 'double', 'long double'):
 
262
        already_declared = config_cmd.check_decl("SIZEOF_%s" % sym2def(type),
 
263
                                                 headers = ["Python.h"])
 
264
        res = config_cmd.check_type_size(type, expected=expected[type])
 
265
        if res >= 0:
 
266
            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
 
267
            if not already_declared and not type == 'long double':
 
268
                private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
 
269
        else:
 
270
            raise SystemError("Checking sizeof (%s) failed !" % type)
 
271
 
 
272
        # Compute size of corresponding complex type: used to check that our
 
273
        # definition is binary compatible with C99 complex type (check done at
 
274
        # build time in npy_common.h)
 
275
        complex_def = "struct {%s __x; %s __y;}" % (type, type)
 
276
        res = config_cmd.check_type_size(complex_def, expected=2*expected[type])
 
277
        if res >= 0:
 
278
            public_defines.append(('NPY_SIZEOF_COMPLEX_%s' % sym2def(type), '%d' % res))
 
279
        else:
 
280
            raise SystemError("Checking sizeof (%s) failed !" % complex_def)
 
281
 
 
282
 
 
283
    for type in ('Py_intptr_t',):
 
284
        res = config_cmd.check_type_size(type, headers=["Python.h"],
 
285
                library_dirs=[pythonlib_dir()],
 
286
                expected=expected[type])
 
287
 
 
288
        if res >= 0:
 
289
            private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
 
290
            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
 
291
        else:
 
292
            raise SystemError("Checking sizeof (%s) failed !" % type)
 
293
 
 
294
    # We check declaration AND type because that's how distutils does it.
 
295
    if config_cmd.check_decl('PY_LONG_LONG', headers=['Python.h']):
 
296
        res = config_cmd.check_type_size('PY_LONG_LONG',  headers=['Python.h'],
 
297
                library_dirs=[pythonlib_dir()],
 
298
                expected=expected['PY_LONG_LONG'])
 
299
        if res >= 0:
 
300
            private_defines.append(('SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
 
301
            public_defines.append(('NPY_SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
 
302
        else:
 
303
            raise SystemError("Checking sizeof (%s) failed !" % 'PY_LONG_LONG')
 
304
 
 
305
        res = config_cmd.check_type_size('long long',
 
306
                expected=expected['long long'])
 
307
        if res >= 0:
 
308
            #private_defines.append(('SIZEOF_%s' % sym2def('long long'), '%d' % res))
 
309
            public_defines.append(('NPY_SIZEOF_%s' % sym2def('long long'), '%d' % res))
 
310
        else:
 
311
            raise SystemError("Checking sizeof (%s) failed !" % 'long long')
 
312
 
 
313
    if not config_cmd.check_decl('CHAR_BIT', headers=['Python.h']):
 
314
        raise RuntimeError(
 
315
            "Config wo CHAR_BIT is not supported"\
 
316
            ", please contact the maintainers")
 
317
 
 
318
    return private_defines, public_defines
 
319
 
 
320
def check_mathlib(config_cmd):
 
321
    # Testing the C math library
 
322
    mathlibs = []
 
323
    mathlibs_choices = [[],['m'],['cpml']]
 
324
    mathlib = os.environ.get('MATHLIB')
 
325
    if mathlib:
 
326
        mathlibs_choices.insert(0,mathlib.split(','))
 
327
    for libs in mathlibs_choices:
 
328
        if config_cmd.check_func("exp", libraries=libs, decl=True, call=True):
 
329
            mathlibs = libs
 
330
            break
 
331
    else:
 
332
        raise EnvironmentError("math library missing; rerun "
 
333
                               "setup.py after setting the "
 
334
                               "MATHLIB env variable")
 
335
    return mathlibs
 
336
 
 
337
def visibility_define(config):
 
338
    """Return the define value to use for NPY_VISIBILITY_HIDDEN (may be empty
 
339
    string)."""
 
340
    if config.check_compiler_gcc4():
 
341
        return '__attribute__((visibility("hidden")))'
 
342
    else:
 
343
        return ''
 
344
 
 
345
def configuration(parent_package='',top_path=None):
 
346
    from numpy.distutils.misc_util import Configuration,dot_join
 
347
    from numpy.distutils.system_info import get_info, default_lib_dirs
 
348
 
 
349
    config = Configuration('core',parent_package,top_path)
 
350
    local_dir = config.local_path
 
351
    codegen_dir = join(local_dir,'code_generators')
 
352
 
 
353
    if is_released(config):
 
354
        warnings.simplefilter('error', MismatchCAPIWarning)
 
355
 
 
356
    # Check whether we have a mismatch between the set C API VERSION and the
 
357
    # actual C API VERSION
 
358
    check_api_version(C_API_VERSION, codegen_dir)
 
359
 
 
360
    generate_umath_py = join(codegen_dir,'generate_umath.py')
 
361
    n = dot_join(config.name,'generate_umath')
 
362
    generate_umath = imp.load_module('_'.join(n.split('.')),
 
363
                                     open(generate_umath_py,'U'),generate_umath_py,
 
364
                                     ('.py','U',1))
 
365
 
 
366
    header_dir = 'include/numpy' # this is relative to config.path_in_package
 
367
 
 
368
    cocache = CallOnceOnly()
 
369
 
 
370
    def generate_config_h(ext, build_dir):
 
371
        target = join(build_dir,header_dir,'config.h')
 
372
        d = os.path.dirname(target)
 
373
        if not os.path.exists(d):
 
374
            os.makedirs(d)
 
375
 
 
376
        if newer(__file__,target):
 
377
            config_cmd = config.get_config_cmd()
 
378
            log.info('Generating %s',target)
 
379
 
 
380
            # Check sizeof
 
381
            moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir)
 
382
 
 
383
            # Check math library and C99 math funcs availability
 
384
            mathlibs = check_mathlib(config_cmd)
 
385
            moredefs.append(('MATHLIB',','.join(mathlibs)))
 
386
 
 
387
            check_math_capabilities(config_cmd, moredefs, mathlibs)
 
388
            moredefs.extend(cocache.check_ieee_macros(config_cmd)[0])
 
389
            moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0])
 
390
 
 
391
            # Signal check
 
392
            if is_npy_no_signal():
 
393
                moredefs.append('__NPY_PRIVATE_NO_SIGNAL')
 
394
 
 
395
            # Windows checks
 
396
            if sys.platform=='win32' or os.name=='nt':
 
397
                win32_checks(moredefs)
 
398
 
 
399
            # Inline check
 
400
            inline = config_cmd.check_inline()
 
401
 
 
402
            # Check whether we need our own wide character support
 
403
            if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']):
 
404
                PYTHON_HAS_UNICODE_WIDE = True
 
405
            else:
 
406
                PYTHON_HAS_UNICODE_WIDE = False
 
407
                
 
408
            if ENABLE_SEPARATE_COMPILATION:
 
409
                moredefs.append(('ENABLE_SEPARATE_COMPILATION', 1))
 
410
 
 
411
            # Get long double representation
 
412
            if sys.platform != 'darwin':
 
413
                rep = check_long_double_representation(config_cmd)
 
414
                if rep in ['INTEL_EXTENDED_12_BYTES_LE',
 
415
                           'INTEL_EXTENDED_16_BYTES_LE',
 
416
                           'IEEE_QUAD_LE', 'IEEE_QUAD_BE',
 
417
                           'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE']:
 
418
                    moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1))
 
419
                else:
 
420
                    raise ValueError("Unrecognized long double format: %s" % rep)
 
421
 
 
422
            # Generate the config.h file from moredefs
 
423
            target_f = open(target, 'w')
 
424
            for d in moredefs:
 
425
                if isinstance(d,str):
 
426
                    target_f.write('#define %s\n' % (d))
 
427
                else:
 
428
                    target_f.write('#define %s %s\n' % (d[0],d[1]))
 
429
 
 
430
            # define inline to our keyword, or nothing
 
431
            target_f.write('#ifndef __cplusplus\n')
 
432
            if inline == 'inline':
 
433
                target_f.write('/* #undef inline */\n')
 
434
            else:
 
435
                target_f.write('#define inline %s\n' % inline)
 
436
            target_f.write('#endif\n')
 
437
 
 
438
            # add the guard to make sure config.h is never included directly,
 
439
            # but always through npy_config.h
 
440
            target_f.write("""
 
441
#ifndef _NPY_NPY_CONFIG_H_
 
442
#error config.h should never be included directly, include npy_config.h instead
 
443
#endif
 
444
""")
 
445
 
 
446
            target_f.close()
 
447
            print 'File:',target
 
448
            target_f = open(target)
 
449
            print target_f.read()
 
450
            target_f.close()
 
451
            print 'EOF'
 
452
        else:
 
453
            mathlibs = []
 
454
            target_f = open(target)
 
455
            for line in target_f.readlines():
 
456
                s = '#define MATHLIB'
 
457
                if line.startswith(s):
 
458
                    value = line[len(s):].strip()
 
459
                    if value:
 
460
                        mathlibs.extend(value.split(','))
 
461
            target_f.close()
 
462
 
 
463
        # Ugly: this can be called within a library and not an extension,
 
464
        # in which case there is no libraries attributes (and none is
 
465
        # needed).
 
466
        if hasattr(ext, 'libraries'):
 
467
            ext.libraries.extend(mathlibs)
 
468
 
 
469
        incl_dir = os.path.dirname(target)
 
470
        if incl_dir not in config.numpy_include_dirs:
 
471
            config.numpy_include_dirs.append(incl_dir)
 
472
 
 
473
        return target
 
474
 
 
475
    def generate_numpyconfig_h(ext, build_dir):
 
476
        """Depends on config.h: generate_config_h has to be called before !"""
 
477
        target = join(build_dir,header_dir,'_numpyconfig.h')
 
478
        d = os.path.dirname(target)
 
479
        if not os.path.exists(d):
 
480
            os.makedirs(d)
 
481
        if newer(__file__,target):
 
482
            config_cmd = config.get_config_cmd()
 
483
            log.info('Generating %s',target)
 
484
 
 
485
            # Check sizeof
 
486
            ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir)
 
487
 
 
488
            if is_npy_no_signal():
 
489
                moredefs.append(('NPY_NO_SIGNAL', 1))
 
490
 
 
491
            if is_npy_no_smp():
 
492
                moredefs.append(('NPY_NO_SMP', 1))
 
493
            else:
 
494
                moredefs.append(('NPY_NO_SMP', 0))
 
495
 
 
496
            mathlibs = check_mathlib(config_cmd)
 
497
            moredefs.extend(cocache.check_ieee_macros(config_cmd)[1])
 
498
            moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1])
 
499
 
 
500
            if ENABLE_SEPARATE_COMPILATION:
 
501
                moredefs.append(('NPY_ENABLE_SEPARATE_COMPILATION', 1))
 
502
 
 
503
            # Check wether we can use inttypes (C99) formats
 
504
            if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']):
 
505
                moredefs.append(('NPY_USE_C99_FORMATS', 1))
 
506
 
 
507
            # visibility check
 
508
            hidden_visibility = visibility_define(config_cmd)
 
509
            moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility))
 
510
 
 
511
            # Add the C API/ABI versions
 
512
            moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION))
 
513
            moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION))
 
514
 
 
515
            # Add moredefs to header
 
516
            target_f = open(target, 'w')
 
517
            for d in moredefs:
 
518
                if isinstance(d,str):
 
519
                    target_f.write('#define %s\n' % (d))
 
520
                else:
 
521
                    target_f.write('#define %s %s\n' % (d[0],d[1]))
 
522
 
 
523
            # Define __STDC_FORMAT_MACROS
 
524
            target_f.write("""
 
525
#ifndef __STDC_FORMAT_MACROS
 
526
#define __STDC_FORMAT_MACROS 1
 
527
#endif
 
528
""")
 
529
            target_f.close()
 
530
 
 
531
            # Dump the numpyconfig.h header to stdout
 
532
            print 'File: %s' % target
 
533
            target_f = open(target)
 
534
            print target_f.read()
 
535
            target_f.close()
 
536
            print 'EOF'
 
537
        config.add_data_files((header_dir, target))
 
538
        return target
 
539
 
 
540
    def generate_api_func(module_name):
 
541
        def generate_api(ext, build_dir):
 
542
            script = join(codegen_dir, module_name + '.py')
 
543
            sys.path.insert(0, codegen_dir)
 
544
            try:
 
545
                m = __import__(module_name)
 
546
                log.info('executing %s', script)
 
547
                h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir))
 
548
            finally:
 
549
                del sys.path[0]
 
550
            config.add_data_files((header_dir, h_file),
 
551
                                  (header_dir, doc_file))
 
552
            return (h_file,)
 
553
        return generate_api
 
554
 
 
555
    generate_numpy_api = generate_api_func('generate_numpy_api')
 
556
    generate_ufunc_api = generate_api_func('generate_ufunc_api')
 
557
 
 
558
    config.add_include_dirs(join(local_dir, "src", "private"))
 
559
    config.add_include_dirs(join(local_dir, "src"))
 
560
    config.add_include_dirs(join(local_dir))
 
561
    # Multiarray version: this function is needed to build foo.c from foo.c.src
 
562
    # when foo.c is included in another file and as such not in the src
 
563
    # argument of build_ext command
 
564
    def generate_multiarray_templated_sources(ext, build_dir):
 
565
        from numpy.distutils.misc_util import get_cmd
 
566
 
 
567
        subpath = join('src', 'multiarray')
 
568
        sources = [join(local_dir, subpath, 'scalartypes.c.src'),
 
569
                   join(local_dir, subpath, 'arraytypes.c.src')]
 
570
 
 
571
        # numpy.distutils generate .c from .c.src in weird directories, we have
 
572
        # to add them there as they depend on the build_dir
 
573
        config.add_include_dirs(join(build_dir, subpath))
 
574
 
 
575
        cmd = get_cmd('build_src')
 
576
        cmd.ensure_finalized()
 
577
 
 
578
        cmd.template_sources(sources, ext)
 
579
 
 
580
    # umath version: this function is needed to build foo.c from foo.c.src
 
581
    # when foo.c is included in another file and as such not in the src
 
582
    # argument of build_ext command
 
583
    def generate_umath_templated_sources(ext, build_dir):
 
584
        from numpy.distutils.misc_util import get_cmd
 
585
 
 
586
        subpath = join('src', 'umath')
 
587
        sources = [join(local_dir, subpath, 'loops.c.src'),
 
588
                   join(local_dir, subpath, 'umathmodule.c.src')]
 
589
 
 
590
        # numpy.distutils generate .c from .c.src in weird directories, we have
 
591
        # to add them there as they depend on the build_dir
 
592
        config.add_include_dirs(join(build_dir, subpath))
 
593
 
 
594
        cmd = get_cmd('build_src')
 
595
        cmd.ensure_finalized()
 
596
 
 
597
        cmd.template_sources(sources, ext)
 
598
 
 
599
 
 
600
    def generate_umath_c(ext,build_dir):
 
601
        target = join(build_dir,header_dir,'__umath_generated.c')
 
602
        dir = os.path.dirname(target)
 
603
        if not os.path.exists(dir):
 
604
            os.makedirs(dir)
 
605
        script = generate_umath_py
 
606
        if newer(script,target):
 
607
            f = open(target,'w')
 
608
            f.write(generate_umath.make_code(generate_umath.defdict,
 
609
                                             generate_umath.__file__))
 
610
            f.close()
 
611
        return []
 
612
 
 
613
    config.add_data_files('include/numpy/*.h')
 
614
    config.add_include_dirs(join('src', 'npymath'))
 
615
    config.add_include_dirs(join('src', 'multiarray'))
 
616
    config.add_include_dirs(join('src', 'umath'))
 
617
 
 
618
    config.numpy_include_dirs.extend(config.paths('include'))
 
619
 
 
620
    deps = [join('src','npymath','_signbit.c'),
 
621
            join('include','numpy','*object.h'),
 
622
            'include/numpy/fenv/fenv.c',
 
623
            'include/numpy/fenv/fenv.h',
 
624
            join(codegen_dir,'genapi.py'),
 
625
            ]
 
626
 
 
627
    # Don't install fenv unless we need them.
 
628
    if sys.platform == 'cygwin':
 
629
        config.add_data_dir('include/numpy/fenv')
 
630
 
 
631
    config.add_extension('_sort',
 
632
                         sources=[join('src','_sortmodule.c.src'),
 
633
                                  generate_config_h,
 
634
                                  generate_numpyconfig_h,
 
635
                                  generate_numpy_api,
 
636
                                  ],
 
637
                         )
 
638
 
 
639
    # npymath needs the config.h and numpyconfig.h files to be generated, but
 
640
    # build_clib cannot handle generate_config_h and generate_numpyconfig_h
 
641
    # (don't ask). Because clib are generated before extensions, we have to
 
642
    # explicitly add an extension which has generate_config_h and
 
643
    # generate_numpyconfig_h as sources *before* adding npymath.
 
644
 
 
645
    subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")])
 
646
    def get_mathlib_info(*args):
 
647
        # Another ugly hack: the mathlib info is known once build_src is run,
 
648
        # but we cannot use add_installed_pkg_config here either, so we only
 
649
        # updated the substition dictionary during npymath build
 
650
        config_cmd = config.get_config_cmd()
 
651
 
 
652
        # Check that the toolchain works, to fail early if it doesn't
 
653
        # (avoid late errors with MATHLIB which are confusing if the
 
654
        # compiler does not work).
 
655
        st = config_cmd.try_link('int main(void) { return 0;}')
 
656
        if not st:
 
657
            raise RuntimeError("Broken toolchain: cannot link a simple C program")
 
658
        mlibs = check_mathlib(config_cmd)
 
659
 
 
660
        posix_mlib = ' '.join(['-l%s' % l for l in mlibs])
 
661
        msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs])
 
662
        subst_dict["posix_mathlib"] = posix_mlib
 
663
        subst_dict["msvc_mathlib"] = msvc_mlib
 
664
 
 
665
    config.add_installed_library('npymath',
 
666
            sources=[join('src', 'npymath', 'npy_math.c.src'),
 
667
                     join('src', 'npymath', 'ieee754.c.src'),
 
668
                     join('src', 'npymath', 'npy_math_complex.c.src'),
 
669
                     get_mathlib_info],
 
670
            install_dir='lib')
 
671
    config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config",
 
672
            subst_dict)
 
673
    config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config",
 
674
            subst_dict)
 
675
   
 
676
    multiarray_deps = [
 
677
            join('src', 'multiarray', 'arrayobject.h'),
 
678
            join('src', 'multiarray', 'arraytypes.h'),
 
679
            join('src', 'multiarray', 'buffer.h'),
 
680
            join('src', 'multiarray', 'calculation.h'),
 
681
            join('src', 'multiarray', 'common.h'),
 
682
            join('src', 'multiarray', 'convert_datatype.h'),
 
683
            join('src', 'multiarray', 'convert.h'),
 
684
            join('src', 'multiarray', 'conversion_utils.h'),
 
685
            join('src', 'multiarray', 'ctors.h'),
 
686
            join('src', 'multiarray', 'descriptor.h'),
 
687
            join('src', 'multiarray', 'getset.h'),
 
688
            join('src', 'multiarray', 'hashdescr.h'),
 
689
            join('src', 'multiarray', 'iterators.h'),
 
690
            join('src', 'multiarray', 'mapping.h'),
 
691
            join('src', 'multiarray', 'methods.h'),
 
692
            join('src', 'multiarray', 'multiarraymodule.h'),
 
693
            join('src', 'multiarray', 'number.h'),
 
694
            join('src', 'multiarray', 'numpyos.h'),
 
695
            join('src', 'multiarray', 'refcount.h'),
 
696
            join('src', 'multiarray', 'scalartypes.h'),
 
697
            join('src', 'multiarray', 'sequence.h'),
 
698
            join('src', 'multiarray', 'shape.h'),
 
699
            join('src', 'multiarray', 'ucsnarrow.h'),
 
700
            join('src', 'multiarray', 'usertypes.h')]
 
701
 
 
702
    multiarray_src = [join('src', 'multiarray', 'multiarraymodule.c'),
 
703
        join('src', 'multiarray', 'hashdescr.c'),
 
704
        join('src', 'multiarray', 'arrayobject.c'),
 
705
        join('src', 'multiarray', 'buffer.c'),
 
706
        join('src', 'multiarray', 'numpyos.c'),
 
707
        join('src', 'multiarray', 'conversion_utils.c'),
 
708
        join('src', 'multiarray', 'flagsobject.c'),
 
709
        join('src', 'multiarray', 'descriptor.c'),
 
710
        join('src', 'multiarray', 'iterators.c'),
 
711
        join('src', 'multiarray', 'mapping.c'),
 
712
        join('src', 'multiarray', 'number.c'),
 
713
        join('src', 'multiarray', 'getset.c'),
 
714
        join('src', 'multiarray', 'sequence.c'),
 
715
        join('src', 'multiarray', 'methods.c'),
 
716
        join('src', 'multiarray', 'ctors.c'),
 
717
        join('src', 'multiarray', 'convert_datatype.c'),
 
718
        join('src', 'multiarray', 'convert.c'),
 
719
        join('src', 'multiarray', 'shape.c'),
 
720
        join('src', 'multiarray', 'item_selection.c'),
 
721
        join('src', 'multiarray', 'calculation.c'),
 
722
        join('src', 'multiarray', 'common.c'),
 
723
        join('src', 'multiarray', 'usertypes.c'),
 
724
        join('src', 'multiarray', 'scalarapi.c'),
 
725
        join('src', 'multiarray', 'refcount.c'),
 
726
        join('src', 'multiarray', 'arraytypes.c.src'),
 
727
        join('src', 'multiarray', 'scalartypes.c.src')]
 
728
 
 
729
    if PYTHON_HAS_UNICODE_WIDE:
 
730
        multiarray_src.append(join('src', 'multiarray', 'ucsnarrow.c'))
 
731
 
 
732
    umath_src = [join('src', 'umath', 'umathmodule.c.src'),
 
733
            join('src', 'umath', 'funcs.inc.src'),
 
734
            join('src', 'umath', 'loops.c.src'),
 
735
            join('src', 'umath', 'ufunc_object.c')]
 
736
 
 
737
    umath_deps = [generate_umath_py,
 
738
            join(codegen_dir,'generate_ufunc_api.py')]
 
739
 
 
740
    if not ENABLE_SEPARATE_COMPILATION:
 
741
        multiarray_deps.extend(multiarray_src)
 
742
        multiarray_src = [join('src', 'multiarray', 'multiarraymodule_onefile.c')]
 
743
        multiarray_src.append(generate_multiarray_templated_sources)
 
744
 
 
745
        umath_deps.extend(umath_src)
 
746
        umath_src = [join('src', 'umath', 'umathmodule_onefile.c')]
 
747
        umath_src.append(generate_umath_templated_sources)
 
748
        umath_src.append(join('src', 'umath', 'funcs.inc.src'))
 
749
 
 
750
    config.add_extension('multiarray',
 
751
                         sources = multiarray_src +
 
752
                                [generate_config_h,
 
753
                                 generate_numpyconfig_h,
 
754
                                 generate_numpy_api,
 
755
                                 join(codegen_dir,'generate_numpy_api.py'),
 
756
                                 join('*.py')],
 
757
                         depends = deps + multiarray_deps,
 
758
                         libraries=['npymath'])
 
759
 
 
760
    config.add_extension('umath',
 
761
                         sources = [generate_config_h,
 
762
                                    generate_numpyconfig_h,
 
763
                                    generate_umath_c,
 
764
                                    generate_ufunc_api,
 
765
                                    ] + umath_src,
 
766
                         depends = deps + umath_deps,
 
767
                         libraries=['npymath'],
 
768
                         )
 
769
 
 
770
    config.add_extension('scalarmath',
 
771
                         sources=[join('src','scalarmathmodule.c.src'),
 
772
                                  generate_config_h,
 
773
                                  generate_numpyconfig_h,
 
774
                                  generate_numpy_api,
 
775
                                  generate_ufunc_api],
 
776
                         )
 
777
 
 
778
    # Configure blasdot
 
779
    blas_info = get_info('blas_opt',0)
 
780
    #blas_info = {}
 
781
    def get_dotblas_sources(ext, build_dir):
 
782
        if blas_info:
 
783
            #if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]):
 
784
            #    return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient.
 
785
            return ext.depends[:1]
 
786
        return None # no extension module will be built
 
787
 
 
788
    config.add_extension('_dotblas',
 
789
                         sources = [get_dotblas_sources],
 
790
                         depends=[join('blasdot','_dotblas.c'),
 
791
                                  join('blasdot','cblas.h'),
 
792
                                  ],
 
793
                         include_dirs = ['blasdot'],
 
794
                         extra_info = blas_info
 
795
                         )
 
796
 
 
797
    config.add_extension('umath_tests',
 
798
                    sources = [join('src','umath', 'umath_tests.c.src')])
 
799
 
 
800
    config.add_extension('multiarray_tests',
 
801
                    sources = [join('src', 'multiarray', 'multiarray_tests.c.src')])
 
802
 
 
803
    config.add_data_dir('tests')
 
804
    config.add_data_dir('tests/data')
 
805
 
 
806
    config.make_svn_version_py()
 
807
 
 
808
    return config
 
809
 
 
810
if __name__=='__main__':
 
811
    from numpy.distutils.core import setup
 
812
    setup(configuration=configuration)