|
from __future__ import division, print_function |
|
|
|
import imp |
|
import os |
|
import sys |
|
import shutil |
|
import pickle |
|
import copy |
|
import warnings |
|
import re |
|
from os.path import join |
|
from numpy.distutils import log |
|
from distutils.dep_util import newer |
|
from distutils.sysconfig import get_config_var |
|
|
|
from setup_common import * |
|
|
|
|
|
ENABLE_SEPARATE_COMPILATION = (os.environ.get('NPY_SEPARATE_COMPILATION', "1") != "0") |
|
|
|
|
|
NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "0") != "0") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CallOnceOnly(object): |
|
def __init__(self): |
|
self._check_types = None |
|
self._check_ieee_macros = None |
|
self._check_complex = None |
|
|
|
def check_types(self, *a, **kw): |
|
if self._check_types is None: |
|
out = check_types(*a, **kw) |
|
self._check_types = pickle.dumps(out) |
|
else: |
|
out = copy.deepcopy(pickle.loads(self._check_types)) |
|
return out |
|
|
|
def check_ieee_macros(self, *a, **kw): |
|
if self._check_ieee_macros is None: |
|
out = check_ieee_macros(*a, **kw) |
|
self._check_ieee_macros = pickle.dumps(out) |
|
else: |
|
out = copy.deepcopy(pickle.loads(self._check_ieee_macros)) |
|
return out |
|
|
|
def check_complex(self, *a, **kw): |
|
if self._check_complex is None: |
|
out = check_complex(*a, **kw) |
|
self._check_complex = pickle.dumps(out) |
|
else: |
|
out = copy.deepcopy(pickle.loads(self._check_complex)) |
|
return out |
|
|
|
PYTHON_HAS_UNICODE_WIDE = True |
|
|
|
def pythonlib_dir(): |
|
"""return path where libpython* is.""" |
|
if sys.platform == 'win32': |
|
return os.path.join(sys.prefix, "libs") |
|
else: |
|
return get_config_var('LIBDIR') |
|
|
|
def is_npy_no_signal(): |
|
"""Return True if the NPY_NO_SIGNAL symbol must be defined in configuration |
|
header.""" |
|
return sys.platform == 'win32' |
|
|
|
def is_npy_no_smp(): |
|
"""Return True if the NPY_NO_SMP symbol must be defined in public |
|
header (when SMP support cannot be reliably enabled).""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
if sys.version[:5] < '2.4.2': |
|
nosmp = 1 |
|
else: |
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
nosmp = os.environ['NPY_NOSMP'] |
|
nosmp = 1 |
|
except KeyError: |
|
nosmp = 0 |
|
return nosmp == 1 |
|
|
|
def win32_checks(deflist): |
|
from numpy.distutils.misc_util import get_build_architecture |
|
a = get_build_architecture() |
|
|
|
|
|
print('BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' % |
|
(a, os.name, sys.platform)) |
|
if a == 'AMD64': |
|
deflist.append('DISTUTILS_USE_SDK') |
|
|
|
|
|
|
|
|
|
if a == "Intel" or a == "AMD64": |
|
deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING') |
|
|
|
def check_math_capabilities(config, moredefs, mathlibs): |
|
def check_func(func_name): |
|
return config.check_func(func_name, libraries=mathlibs, |
|
decl=True, call=True) |
|
|
|
def check_funcs_once(funcs_name): |
|
decl = dict([(f, True) for f in funcs_name]) |
|
st = config.check_funcs_once(funcs_name, libraries=mathlibs, |
|
decl=decl, call=decl) |
|
if st: |
|
moredefs.extend([(fname2def(f), 1) for f in funcs_name]) |
|
return st |
|
|
|
def check_funcs(funcs_name): |
|
|
|
|
|
if not check_funcs_once(funcs_name): |
|
|
|
for f in funcs_name: |
|
if check_func(f): |
|
moredefs.append((fname2def(f), 1)) |
|
return 0 |
|
else: |
|
return 1 |
|
|
|
|
|
|
|
if not check_funcs_once(MANDATORY_FUNCS): |
|
raise SystemError("One of the required function to build numpy is not" |
|
" available (the list is %s)." % str(MANDATORY_FUNCS)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for f in OPTIONAL_STDFUNCS_MAYBE: |
|
if config.check_decl(fname2def(f), |
|
headers=["Python.h", "math.h"]): |
|
OPTIONAL_STDFUNCS.remove(f) |
|
|
|
check_funcs(OPTIONAL_STDFUNCS) |
|
|
|
for h in OPTIONAL_HEADERS: |
|
if config.check_func("", decl=False, call=False, headers=[h]): |
|
moredefs.append((fname2def(h).replace(".", "_"), 1)) |
|
|
|
for tup in OPTIONAL_INTRINSICS: |
|
headers = None |
|
if len(tup) == 2: |
|
f, args = tup |
|
else: |
|
f, args, headers = tup[0], tup[1], [tup[2]] |
|
if config.check_func(f, decl=False, call=True, call_args=args, |
|
headers=headers): |
|
moredefs.append((fname2def(f), 1)) |
|
|
|
for dec, fn in OPTIONAL_FUNCTION_ATTRIBUTES: |
|
if config.check_func(fn, decl='int %s %s(void *);' % (dec, fn), |
|
call=False): |
|
moredefs.append((fname2def(fn), 1)) |
|
|
|
for fn in OPTIONAL_VARIABLE_ATTRIBUTES: |
|
if config.check_func(fn, decl='int %s a;' % (fn), call=False): |
|
m = fn.replace("(", "_").replace(")", "_") |
|
moredefs.append((fname2def(m), 1)) |
|
|
|
|
|
check_funcs(C99_FUNCS_SINGLE) |
|
check_funcs(C99_FUNCS_EXTENDED) |
|
|
|
def check_complex(config, mathlibs): |
|
priv = [] |
|
pub = [] |
|
|
|
try: |
|
if os.uname()[0] == "Interix": |
|
warnings.warn("Disabling broken complex support. See #1365") |
|
return priv, pub |
|
except: |
|
|
|
pass |
|
|
|
|
|
st = config.check_header('complex.h') |
|
if st: |
|
priv.append(('HAVE_COMPLEX_H', 1)) |
|
pub.append(('NPY_USE_C99_COMPLEX', 1)) |
|
|
|
for t in C99_COMPLEX_TYPES: |
|
st = config.check_type(t, headers=["complex.h"]) |
|
if st: |
|
pub.append(('NPY_HAVE_%s' % type2def(t), 1)) |
|
|
|
def check_prec(prec): |
|
flist = [f + prec for f in C99_COMPLEX_FUNCS] |
|
decl = dict([(f, True) for f in flist]) |
|
if not config.check_funcs_once(flist, call=decl, decl=decl, |
|
libraries=mathlibs): |
|
for f in flist: |
|
if config.check_func(f, call=True, decl=True, |
|
libraries=mathlibs): |
|
priv.append((fname2def(f), 1)) |
|
else: |
|
priv.extend([(fname2def(f), 1) for f in flist]) |
|
|
|
check_prec('') |
|
check_prec('f') |
|
check_prec('l') |
|
|
|
return priv, pub |
|
|
|
def check_ieee_macros(config): |
|
priv = [] |
|
pub = [] |
|
|
|
macros = [] |
|
|
|
def _add_decl(f): |
|
priv.append(fname2def("decl_%s" % f)) |
|
pub.append('NPY_%s' % fname2def("decl_%s" % f)) |
|
|
|
|
|
|
|
|
|
|
|
_macros = ["isnan", "isinf", "signbit", "isfinite"] |
|
for f in _macros: |
|
py_symbol = fname2def("decl_%s" % f) |
|
already_declared = config.check_decl(py_symbol, |
|
headers=["Python.h", "math.h"]) |
|
if already_declared: |
|
if config.check_macro_true(py_symbol, |
|
headers=["Python.h", "math.h"]): |
|
pub.append('NPY_%s' % fname2def("decl_%s" % f)) |
|
else: |
|
macros.append(f) |
|
|
|
|
|
|
|
|
|
|
|
for f in macros: |
|
st = config.check_decl(f, headers = ["Python.h", "math.h"]) |
|
if st: |
|
_add_decl(f) |
|
|
|
return priv, pub |
|
|
|
def check_types(config_cmd, ext, build_dir): |
|
private_defines = [] |
|
public_defines = [] |
|
|
|
|
|
|
|
|
|
expected = {} |
|
expected['short'] = [2] |
|
expected['int'] = [4] |
|
expected['long'] = [8, 4] |
|
expected['float'] = [4] |
|
expected['double'] = [8] |
|
expected['long double'] = [8, 12, 16] |
|
expected['Py_intptr_t'] = [4, 8] |
|
expected['PY_LONG_LONG'] = [8] |
|
expected['long long'] = [8] |
|
expected['off_t'] = [4, 8] |
|
|
|
|
|
result = config_cmd.check_header('Python.h') |
|
if not result: |
|
raise SystemError( |
|
"Cannot compile 'Python.h'. Perhaps you need to "\ |
|
"install python-dev|python-devel.") |
|
res = config_cmd.check_header("endian.h") |
|
if res: |
|
private_defines.append(('HAVE_ENDIAN_H', 1)) |
|
public_defines.append(('NPY_HAVE_ENDIAN_H', 1)) |
|
|
|
|
|
for type in ('short', 'int', 'long'): |
|
res = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), headers = ["Python.h"]) |
|
if res: |
|
public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), "SIZEOF_%s" % sym2def(type))) |
|
else: |
|
res = config_cmd.check_type_size(type, expected=expected[type]) |
|
if res >= 0: |
|
public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res)) |
|
else: |
|
raise SystemError("Checking sizeof (%s) failed !" % type) |
|
|
|
for type in ('float', 'double', 'long double'): |
|
already_declared = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), |
|
headers = ["Python.h"]) |
|
res = config_cmd.check_type_size(type, expected=expected[type]) |
|
if res >= 0: |
|
public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res)) |
|
if not already_declared and not type == 'long double': |
|
private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res)) |
|
else: |
|
raise SystemError("Checking sizeof (%s) failed !" % type) |
|
|
|
|
|
|
|
|
|
complex_def = "struct {%s __x; %s __y;}" % (type, type) |
|
res = config_cmd.check_type_size(complex_def, expected=2*expected[type]) |
|
if res >= 0: |
|
public_defines.append(('NPY_SIZEOF_COMPLEX_%s' % sym2def(type), '%d' % res)) |
|
else: |
|
raise SystemError("Checking sizeof (%s) failed !" % complex_def) |
|
|
|
|
|
for type in ('Py_intptr_t', 'off_t'): |
|
res = config_cmd.check_type_size(type, headers=["Python.h"], |
|
library_dirs=[pythonlib_dir()], |
|
expected=expected[type]) |
|
|
|
if res >= 0: |
|
private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res)) |
|
public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res)) |
|
else: |
|
raise SystemError("Checking sizeof (%s) failed !" % type) |
|
|
|
|
|
if config_cmd.check_decl('PY_LONG_LONG', headers=['Python.h']): |
|
res = config_cmd.check_type_size('PY_LONG_LONG', headers=['Python.h'], |
|
library_dirs=[pythonlib_dir()], |
|
expected=expected['PY_LONG_LONG']) |
|
if res >= 0: |
|
private_defines.append(('SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res)) |
|
public_defines.append(('NPY_SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res)) |
|
else: |
|
raise SystemError("Checking sizeof (%s) failed !" % 'PY_LONG_LONG') |
|
|
|
res = config_cmd.check_type_size('long long', |
|
expected=expected['long long']) |
|
if res >= 0: |
|
|
|
public_defines.append(('NPY_SIZEOF_%s' % sym2def('long long'), '%d' % res)) |
|
else: |
|
raise SystemError("Checking sizeof (%s) failed !" % 'long long') |
|
|
|
if not config_cmd.check_decl('CHAR_BIT', headers=['Python.h']): |
|
raise RuntimeError( |
|
"Config wo CHAR_BIT is not supported"\ |
|
", please contact the maintainers") |
|
|
|
return private_defines, public_defines |
|
|
|
def check_mathlib(config_cmd): |
|
|
|
mathlibs = [] |
|
mathlibs_choices = [[], ['m'], ['cpml']] |
|
mathlib = os.environ.get('MATHLIB') |
|
if mathlib: |
|
mathlibs_choices.insert(0, mathlib.split(',')) |
|
for libs in mathlibs_choices: |
|
if config_cmd.check_func("exp", libraries=libs, decl=True, call=True): |
|
mathlibs = libs |
|
break |
|
else: |
|
raise EnvironmentError("math library missing; rerun " |
|
"setup.py after setting the " |
|
"MATHLIB env variable") |
|
return mathlibs |
|
|
|
def visibility_define(config): |
|
"""Return the define value to use for NPY_VISIBILITY_HIDDEN (may be empty |
|
string).""" |
|
if config.check_compiler_gcc4(): |
|
return '__attribute__((visibility("hidden")))' |
|
else: |
|
return '' |
|
|
|
def configuration(parent_package='',top_path=None): |
|
from numpy.distutils.misc_util import Configuration, dot_join |
|
from numpy.distutils.system_info import get_info, default_lib_dirs |
|
|
|
config = Configuration('core', parent_package, top_path) |
|
local_dir = config.local_path |
|
codegen_dir = join(local_dir, 'code_generators') |
|
|
|
if is_released(config): |
|
warnings.simplefilter('error', MismatchCAPIWarning) |
|
|
|
|
|
|
|
check_api_version(C_API_VERSION, codegen_dir) |
|
|
|
generate_umath_py = join(codegen_dir, 'generate_umath.py') |
|
n = dot_join(config.name, 'generate_umath') |
|
generate_umath = imp.load_module('_'.join(n.split('.')), |
|
open(generate_umath_py, 'U'), generate_umath_py, |
|
('.py', 'U', 1)) |
|
|
|
header_dir = 'include/numpy' |
|
|
|
cocache = CallOnceOnly() |
|
|
|
def generate_config_h(ext, build_dir): |
|
target = join(build_dir, header_dir, 'config.h') |
|
d = os.path.dirname(target) |
|
if not os.path.exists(d): |
|
os.makedirs(d) |
|
|
|
if newer(__file__, target): |
|
config_cmd = config.get_config_cmd() |
|
log.info('Generating %s', target) |
|
|
|
|
|
moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) |
|
|
|
|
|
mathlibs = check_mathlib(config_cmd) |
|
moredefs.append(('MATHLIB', ','.join(mathlibs))) |
|
|
|
check_math_capabilities(config_cmd, moredefs, mathlibs) |
|
moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) |
|
moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) |
|
|
|
|
|
if is_npy_no_signal(): |
|
moredefs.append('__NPY_PRIVATE_NO_SIGNAL') |
|
|
|
|
|
if sys.platform=='win32' or os.name=='nt': |
|
win32_checks(moredefs) |
|
|
|
|
|
inline = config_cmd.check_inline() |
|
|
|
|
|
if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']): |
|
PYTHON_HAS_UNICODE_WIDE = True |
|
else: |
|
PYTHON_HAS_UNICODE_WIDE = False |
|
|
|
if ENABLE_SEPARATE_COMPILATION: |
|
moredefs.append(('ENABLE_SEPARATE_COMPILATION', 1)) |
|
|
|
if NPY_RELAXED_STRIDES_CHECKING: |
|
moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) |
|
|
|
|
|
if sys.platform != 'darwin': |
|
rep = check_long_double_representation(config_cmd) |
|
if rep in ['INTEL_EXTENDED_12_BYTES_LE', |
|
'INTEL_EXTENDED_16_BYTES_LE', |
|
'MOTOROLA_EXTENDED_12_BYTES_BE', |
|
'IEEE_QUAD_LE', 'IEEE_QUAD_BE', |
|
'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE', |
|
'DOUBLE_DOUBLE_BE', 'DOUBLE_DOUBLE_LE']: |
|
moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) |
|
else: |
|
raise ValueError("Unrecognized long double format: %s" % rep) |
|
|
|
|
|
if sys.version_info[0] == 3: |
|
moredefs.append(('NPY_PY3K', 1)) |
|
|
|
|
|
target_f = open(target, 'w') |
|
for d in moredefs: |
|
if isinstance(d, str): |
|
target_f.write('#define %s\n' % (d)) |
|
else: |
|
target_f.write('#define %s %s\n' % (d[0], d[1])) |
|
|
|
|
|
target_f.write('#ifndef __cplusplus\n') |
|
if inline == 'inline': |
|
target_f.write('/* #undef inline */\n') |
|
else: |
|
target_f.write('#define inline %s\n' % inline) |
|
target_f.write('#endif\n') |
|
|
|
|
|
|
|
target_f.write(""" |
|
#ifndef _NPY_NPY_CONFIG_H_ |
|
#error config.h should never be included directly, include npy_config.h instead |
|
#endif |
|
""") |
|
|
|
target_f.close() |
|
print('File:', target) |
|
target_f = open(target) |
|
print(target_f.read()) |
|
target_f.close() |
|
print('EOF') |
|
else: |
|
mathlibs = [] |
|
target_f = open(target) |
|
for line in target_f: |
|
s = '#define MATHLIB' |
|
if line.startswith(s): |
|
value = line[len(s):].strip() |
|
if value: |
|
mathlibs.extend(value.split(',')) |
|
target_f.close() |
|
|
|
|
|
|
|
|
|
if hasattr(ext, 'libraries'): |
|
ext.libraries.extend(mathlibs) |
|
|
|
incl_dir = os.path.dirname(target) |
|
if incl_dir not in config.numpy_include_dirs: |
|
config.numpy_include_dirs.append(incl_dir) |
|
|
|
return target |
|
|
|
def generate_numpyconfig_h(ext, build_dir): |
|
"""Depends on config.h: generate_config_h has to be called before !""" |
|
|
|
|
|
config.add_include_dirs(join(build_dir, "src", "private")) |
|
|
|
target = join(build_dir, header_dir, '_numpyconfig.h') |
|
d = os.path.dirname(target) |
|
if not os.path.exists(d): |
|
os.makedirs(d) |
|
if newer(__file__, target): |
|
config_cmd = config.get_config_cmd() |
|
log.info('Generating %s', target) |
|
|
|
|
|
ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) |
|
|
|
if is_npy_no_signal(): |
|
moredefs.append(('NPY_NO_SIGNAL', 1)) |
|
|
|
if is_npy_no_smp(): |
|
moredefs.append(('NPY_NO_SMP', 1)) |
|
else: |
|
moredefs.append(('NPY_NO_SMP', 0)) |
|
|
|
mathlibs = check_mathlib(config_cmd) |
|
moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) |
|
moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) |
|
|
|
if ENABLE_SEPARATE_COMPILATION: |
|
moredefs.append(('NPY_ENABLE_SEPARATE_COMPILATION', 1)) |
|
|
|
if NPY_RELAXED_STRIDES_CHECKING: |
|
moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) |
|
|
|
|
|
if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']): |
|
moredefs.append(('NPY_USE_C99_FORMATS', 1)) |
|
|
|
|
|
hidden_visibility = visibility_define(config_cmd) |
|
moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) |
|
|
|
|
|
moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) |
|
moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) |
|
|
|
|
|
target_f = open(target, 'w') |
|
for d in moredefs: |
|
if isinstance(d, str): |
|
target_f.write('#define %s\n' % (d)) |
|
else: |
|
target_f.write('#define %s %s\n' % (d[0], d[1])) |
|
|
|
|
|
target_f.write(""" |
|
#ifndef __STDC_FORMAT_MACROS |
|
#define __STDC_FORMAT_MACROS 1 |
|
#endif |
|
""") |
|
target_f.close() |
|
|
|
|
|
print('File: %s' % target) |
|
target_f = open(target) |
|
print(target_f.read()) |
|
target_f.close() |
|
print('EOF') |
|
config.add_data_files((header_dir, target)) |
|
return target |
|
|
|
def generate_api_func(module_name): |
|
def generate_api(ext, build_dir): |
|
script = join(codegen_dir, module_name + '.py') |
|
sys.path.insert(0, codegen_dir) |
|
try: |
|
m = __import__(module_name) |
|
log.info('executing %s', script) |
|
h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) |
|
finally: |
|
del sys.path[0] |
|
config.add_data_files((header_dir, h_file), |
|
(header_dir, doc_file)) |
|
return (h_file,) |
|
return generate_api |
|
|
|
generate_numpy_api = generate_api_func('generate_numpy_api') |
|
generate_ufunc_api = generate_api_func('generate_ufunc_api') |
|
|
|
config.add_include_dirs(join(local_dir, "src", "private")) |
|
config.add_include_dirs(join(local_dir, "src")) |
|
config.add_include_dirs(join(local_dir)) |
|
|
|
config.add_data_files('include/numpy/*.h') |
|
config.add_include_dirs(join('src', 'npymath')) |
|
config.add_include_dirs(join('src', 'multiarray')) |
|
config.add_include_dirs(join('src', 'umath')) |
|
config.add_include_dirs(join('src', 'npysort')) |
|
|
|
config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) |
|
config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) |
|
config.add_define_macros([('_LARGEFILE_SOURCE', '1')]) |
|
config.add_define_macros([('_LARGEFILE64_SOURCE', '1')]) |
|
|
|
config.numpy_include_dirs.extend(config.paths('include')) |
|
|
|
deps = [join('src', 'npymath', '_signbit.c'), |
|
join('include', 'numpy', '*object.h'), |
|
'include/numpy/fenv/fenv.c', |
|
'include/numpy/fenv/fenv.h', |
|
join(codegen_dir, 'genapi.py'), |
|
] |
|
|
|
|
|
if sys.platform == 'cygwin': |
|
config.add_data_dir('include/numpy/fenv') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('_dummy', |
|
sources = [join('src', 'dummymodule.c'), |
|
generate_config_h, |
|
generate_numpyconfig_h, |
|
generate_numpy_api] |
|
) |
|
|
|
|
|
|
|
|
|
|
|
subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) |
|
def get_mathlib_info(*args): |
|
|
|
|
|
|
|
config_cmd = config.get_config_cmd() |
|
|
|
|
|
|
|
|
|
st = config_cmd.try_link('int main(void) { return 0;}') |
|
if not st: |
|
raise RuntimeError("Broken toolchain: cannot link a simple C program") |
|
mlibs = check_mathlib(config_cmd) |
|
|
|
posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) |
|
msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) |
|
subst_dict["posix_mathlib"] = posix_mlib |
|
subst_dict["msvc_mathlib"] = msvc_mlib |
|
|
|
npymath_sources = [join('src', 'npymath', 'npy_math.c.src'), |
|
join('src', 'npymath', 'ieee754.c.src'), |
|
join('src', 'npymath', 'npy_math_complex.c.src'), |
|
join('src', 'npymath', 'halffloat.c')] |
|
config.add_installed_library('npymath', |
|
sources=npymath_sources + [get_mathlib_info], |
|
install_dir='lib') |
|
config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", |
|
subst_dict) |
|
config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", |
|
subst_dict) |
|
|
|
|
|
|
|
|
|
|
|
|
|
npysort_sources=[join('src', 'npysort', 'quicksort.c.src'), |
|
join('src', 'npysort', 'mergesort.c.src'), |
|
join('src', 'npysort', 'heapsort.c.src'), |
|
join('src', 'private', 'npy_partition.h.src'), |
|
join('src', 'npysort', 'selection.c.src'), |
|
join('src', 'private', 'npy_binsearch.h.src'), |
|
join('src', 'npysort', 'binsearch.c.src'), |
|
] |
|
config.add_library('npysort', |
|
sources=npysort_sources, |
|
include_dirs=[]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_multiarray_templated_sources(ext, build_dir): |
|
from numpy.distutils.misc_util import get_cmd |
|
|
|
subpath = join('src', 'multiarray') |
|
sources = [join(local_dir, subpath, 'scalartypes.c.src'), |
|
join(local_dir, subpath, 'arraytypes.c.src'), |
|
join(local_dir, subpath, 'nditer_templ.c.src'), |
|
join(local_dir, subpath, 'lowlevel_strided_loops.c.src'), |
|
join(local_dir, subpath, 'einsum.c.src')] |
|
|
|
|
|
|
|
config.add_include_dirs(join(build_dir, subpath)) |
|
cmd = get_cmd('build_src') |
|
cmd.ensure_finalized() |
|
cmd.template_sources(sources, ext) |
|
|
|
multiarray_deps = [ |
|
join('src', 'multiarray', 'arrayobject.h'), |
|
join('src', 'multiarray', 'arraytypes.h'), |
|
join('src', 'multiarray', 'array_assign.h'), |
|
join('src', 'multiarray', 'buffer.h'), |
|
join('src', 'multiarray', 'calculation.h'), |
|
join('src', 'multiarray', 'common.h'), |
|
join('src', 'multiarray', 'convert_datatype.h'), |
|
join('src', 'multiarray', 'convert.h'), |
|
join('src', 'multiarray', 'conversion_utils.h'), |
|
join('src', 'multiarray', 'ctors.h'), |
|
join('src', 'multiarray', 'descriptor.h'), |
|
join('src', 'multiarray', 'getset.h'), |
|
join('src', 'multiarray', 'hashdescr.h'), |
|
join('src', 'multiarray', 'iterators.h'), |
|
join('src', 'multiarray', 'mapping.h'), |
|
join('src', 'multiarray', 'methods.h'), |
|
join('src', 'multiarray', 'multiarraymodule.h'), |
|
join('src', 'multiarray', 'nditer_impl.h'), |
|
join('src', 'multiarray', 'numpymemoryview.h'), |
|
join('src', 'multiarray', 'number.h'), |
|
join('src', 'multiarray', 'numpyos.h'), |
|
join('src', 'multiarray', 'refcount.h'), |
|
join('src', 'multiarray', 'scalartypes.h'), |
|
join('src', 'multiarray', 'sequence.h'), |
|
join('src', 'multiarray', 'shape.h'), |
|
join('src', 'multiarray', 'ucsnarrow.h'), |
|
join('src', 'multiarray', 'usertypes.h'), |
|
join('src', 'private', 'lowlevel_strided_loops.h'), |
|
join('include', 'numpy', 'arrayobject.h'), |
|
join('include', 'numpy', '_neighborhood_iterator_imp.h'), |
|
join('include', 'numpy', 'npy_endian.h'), |
|
join('include', 'numpy', 'arrayscalars.h'), |
|
join('include', 'numpy', 'noprefix.h'), |
|
join('include', 'numpy', 'npy_interrupt.h'), |
|
join('include', 'numpy', 'npy_3kcompat.h'), |
|
join('include', 'numpy', 'npy_math.h'), |
|
join('include', 'numpy', 'halffloat.h'), |
|
join('include', 'numpy', 'npy_common.h'), |
|
join('include', 'numpy', 'npy_os.h'), |
|
join('include', 'numpy', 'utils.h'), |
|
join('include', 'numpy', 'ndarrayobject.h'), |
|
join('include', 'numpy', 'npy_cpu.h'), |
|
join('include', 'numpy', 'numpyconfig.h'), |
|
join('include', 'numpy', 'ndarraytypes.h'), |
|
join('include', 'numpy', 'npy_1_7_deprecated_api.h'), |
|
join('include', 'numpy', '_numpyconfig.h.in'), |
|
|
|
|
|
] + npysort_sources + npymath_sources |
|
|
|
multiarray_src = [ |
|
join('src', 'multiarray', 'alloc.c'), |
|
join('src', 'multiarray', 'arrayobject.c'), |
|
join('src', 'multiarray', 'arraytypes.c.src'), |
|
join('src', 'multiarray', 'array_assign.c'), |
|
join('src', 'multiarray', 'array_assign_scalar.c'), |
|
join('src', 'multiarray', 'array_assign_array.c'), |
|
join('src', 'multiarray', 'buffer.c'), |
|
join('src', 'multiarray', 'calculation.c'), |
|
join('src', 'multiarray', 'common.c'), |
|
join('src', 'multiarray', 'convert.c'), |
|
join('src', 'multiarray', 'convert_datatype.c'), |
|
join('src', 'multiarray', 'conversion_utils.c'), |
|
join('src', 'multiarray', 'ctors.c'), |
|
join('src', 'multiarray', 'datetime.c'), |
|
join('src', 'multiarray', 'datetime_strings.c'), |
|
join('src', 'multiarray', 'datetime_busday.c'), |
|
join('src', 'multiarray', 'datetime_busdaycal.c'), |
|
join('src', 'multiarray', 'descriptor.c'), |
|
join('src', 'multiarray', 'dtype_transfer.c'), |
|
join('src', 'multiarray', 'einsum.c.src'), |
|
join('src', 'multiarray', 'flagsobject.c'), |
|
join('src', 'multiarray', 'getset.c'), |
|
join('src', 'multiarray', 'hashdescr.c'), |
|
join('src', 'multiarray', 'item_selection.c'), |
|
join('src', 'multiarray', 'iterators.c'), |
|
join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), |
|
join('src', 'multiarray', 'mapping.c'), |
|
join('src', 'multiarray', 'methods.c'), |
|
join('src', 'multiarray', 'multiarraymodule.c'), |
|
join('src', 'multiarray', 'nditer_templ.c.src'), |
|
join('src', 'multiarray', 'nditer_api.c'), |
|
join('src', 'multiarray', 'nditer_constr.c'), |
|
join('src', 'multiarray', 'nditer_pywrap.c'), |
|
join('src', 'multiarray', 'number.c'), |
|
join('src', 'multiarray', 'numpymemoryview.c'), |
|
join('src', 'multiarray', 'numpyos.c'), |
|
join('src', 'multiarray', 'refcount.c'), |
|
join('src', 'multiarray', 'sequence.c'), |
|
join('src', 'multiarray', 'shape.c'), |
|
join('src', 'multiarray', 'scalarapi.c'), |
|
join('src', 'multiarray', 'scalartypes.c.src'), |
|
join('src', 'multiarray', 'usertypes.c'), |
|
join('src', 'multiarray', 'ucsnarrow.c')] |
|
|
|
|
|
if not ENABLE_SEPARATE_COMPILATION: |
|
multiarray_deps.extend(multiarray_src) |
|
multiarray_src = [join('src', 'multiarray', 'multiarraymodule_onefile.c')] |
|
multiarray_src.append(generate_multiarray_templated_sources) |
|
|
|
config.add_extension('multiarray', |
|
sources = multiarray_src + |
|
[generate_config_h, |
|
generate_numpyconfig_h, |
|
generate_numpy_api, |
|
join(codegen_dir, 'generate_numpy_api.py'), |
|
join('*.py')], |
|
depends = deps + multiarray_deps, |
|
libraries = ['npymath', 'npysort']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_umath_templated_sources(ext, build_dir): |
|
from numpy.distutils.misc_util import get_cmd |
|
|
|
subpath = join('src', 'umath') |
|
sources = [ |
|
join(local_dir, subpath, 'loops.h.src'), |
|
join(local_dir, subpath, 'loops.c.src'), |
|
join(local_dir, subpath, 'simd.inc.src')] |
|
|
|
|
|
|
|
config.add_include_dirs(join(build_dir, subpath)) |
|
cmd = get_cmd('build_src') |
|
cmd.ensure_finalized() |
|
cmd.template_sources(sources, ext) |
|
|
|
|
|
def generate_umath_c(ext, build_dir): |
|
target = join(build_dir, header_dir, '__umath_generated.c') |
|
dir = os.path.dirname(target) |
|
if not os.path.exists(dir): |
|
os.makedirs(dir) |
|
script = generate_umath_py |
|
if newer(script, target): |
|
f = open(target, 'w') |
|
f.write(generate_umath.make_code(generate_umath.defdict, |
|
generate_umath.__file__)) |
|
f.close() |
|
return [] |
|
|
|
umath_src = [ |
|
join('src', 'umath', 'umathmodule.c'), |
|
join('src', 'umath', 'reduction.c'), |
|
join('src', 'umath', 'funcs.inc.src'), |
|
join('src', 'umath', 'simd.inc.src'), |
|
join('src', 'umath', 'loops.h.src'), |
|
join('src', 'umath', 'loops.c.src'), |
|
join('src', 'umath', 'ufunc_object.c'), |
|
join('src', 'umath', 'ufunc_type_resolution.c')] |
|
|
|
umath_deps = [ |
|
generate_umath_py, |
|
join('src', 'multiarray', 'common.h'), |
|
join('src', 'umath', 'simd.inc.src'), |
|
join(codegen_dir, 'generate_ufunc_api.py'), |
|
join('src', 'private', 'ufunc_override.h')] + npymath_sources |
|
|
|
if not ENABLE_SEPARATE_COMPILATION: |
|
umath_deps.extend(umath_src) |
|
umath_src = [join('src', 'umath', 'umathmodule_onefile.c')] |
|
umath_src.append(generate_umath_templated_sources) |
|
umath_src.append(join('src', 'umath', 'funcs.inc.src')) |
|
umath_src.append(join('src', 'umath', 'simd.inc.src')) |
|
|
|
config.add_extension('umath', |
|
sources = umath_src + |
|
[generate_config_h, |
|
generate_numpyconfig_h, |
|
generate_umath_c, |
|
generate_ufunc_api], |
|
depends = deps + umath_deps, |
|
libraries = ['npymath'], |
|
) |
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('scalarmath', |
|
sources = [join('src', 'scalarmathmodule.c.src'), |
|
join('src', 'private', 'scalarmathmodule.h.src'), |
|
generate_config_h, |
|
generate_numpyconfig_h, |
|
generate_numpy_api, |
|
generate_ufunc_api], |
|
depends = deps + npymath_sources, |
|
libraries = ['npymath'], |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
blas_info = get_info('blas_opt', 0) |
|
|
|
def get_dotblas_sources(ext, build_dir): |
|
if blas_info: |
|
if ('NO_ATLAS_INFO', 1) in blas_info.get('define_macros', []): |
|
return None |
|
return ext.depends[:1] |
|
return None |
|
|
|
config.add_extension('_dotblas', |
|
sources = [get_dotblas_sources], |
|
depends = [join('blasdot', '_dotblas.c'), |
|
join('blasdot', 'cblas.h'), |
|
], |
|
include_dirs = ['blasdot'], |
|
extra_info = blas_info |
|
) |
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('umath_tests', |
|
sources = [join('src', 'umath', 'umath_tests.c.src')]) |
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('test_rational', |
|
sources = [join('src', 'umath', 'test_rational.c.src')]) |
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('struct_ufunc_test', |
|
sources = [join('src', 'umath', 'struct_ufunc_test.c.src')]) |
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('multiarray_tests', |
|
sources = [join('src', 'multiarray', 'multiarray_tests.c.src')]) |
|
|
|
|
|
|
|
|
|
|
|
config.add_extension('operand_flag_tests', |
|
sources = [join('src', 'umath', 'operand_flag_tests.c.src')]) |
|
|
|
config.add_data_dir('tests') |
|
config.add_data_dir('tests/data') |
|
|
|
config.make_svn_version_py() |
|
|
|
return config |
|
|
|
if __name__=='__main__': |
|
from numpy.distutils.core import setup |
|
setup(configuration=configuration) |
|
|