summaryrefslogtreecommitdiff
path: root/numpy/core/SConstruct
diff options
context:
space:
mode:
authorDavid Cournapeau <cournape@gmail.com>2008-01-06 14:09:03 +0000
committerDavid Cournapeau <cournape@gmail.com>2008-01-06 14:09:03 +0000
commit6123f389746f0ff187aa4e05fa0c2c5d3e12dc58 (patch)
tree9da32e6a54135a640fa5b72a7c965d7cf9397bfa /numpy/core/SConstruct
parentd57e886e51cccb06807c4e6fdaee280326b91f3c (diff)
downloadnumpy-6123f389746f0ff187aa4e05fa0c2c5d3e12dc58.tar.gz
Adding scons scripts + support for numpy.core (do not work yet)
Diffstat (limited to 'numpy/core/SConstruct')
-rw-r--r--numpy/core/SConstruct272
1 files changed, 272 insertions, 0 deletions
diff --git a/numpy/core/SConstruct b/numpy/core/SConstruct
new file mode 100644
index 000000000..bffdf0d5d
--- /dev/null
+++ b/numpy/core/SConstruct
@@ -0,0 +1,272 @@
+# Last Change: Sun Jan 06 07:00 PM 2008 J
+# vim:syntax=python
+import os
+import sys
+from os.path import join as pjoin, basename as pbasename, dirname as pdirname
+from copy import deepcopy
+
+from numscons import get_python_inc, get_pythonlib_dir
+from numscons import GetNumpyEnvironment
+from numscons import CheckCBLAS
+from numscons.configuration import write_info
+
+from scons_support import CheckBrokenMathlib, define_no_smp, \
+ generate_config_header, generate_config_header_emitter
+
+env = GetNumpyEnvironment(ARGUMENTS)
+env.Append(CPPPATH = [get_python_inc()])
+if os.name == 'nt':
+ # NT needs the pythonlib to run any code importing Python.h, including
+ # simple code using only typedef and so on, so we need it for configuration
+ # checks
+ env.AppendUnique(LIBPATH = [get_pythonlib_dir()])
+
+#=======================
+# Starting Configuration
+#=======================
+# XXX: separate env for configuration
+config = env.NumpyConfigure(custom_tests = {'CheckBrokenMathlib' : CheckBrokenMathlib,
+ 'CheckCBLAS' : CheckCBLAS})
+
+# Convention: list of tuples (definition, value). value:
+# - 0: #undef definition
+# - 1: #define definition
+# - string: #define definition value
+config_sym = []
+
+#---------------
+# Checking Types
+#---------------
+def check_type(type, include = None):
+ st = config.CheckTypeSize(type, includes = include)
+ type = type.replace(' ', '_')
+ if st:
+ config_sym.append(('SIZEOF_%s' % type.upper(), '%d' % st))
+ else:
+ config_sym.append(('SIZEOF_%s' % type.upper(), 0))
+
+check_type('short')
+check_type('int')
+check_type('long')
+check_type('float')
+check_type('double')
+check_type('long double')
+check_type('Py_intptr_t', include = "#include <Python.h>\n")
+check_type('PY_LONG_LONG', include = "#include <Python.h>\n")
+
+# TODO: check python extension can be built (in root or here ?)
+
+#-----------------------
+# Checking configuration
+#-----------------------
+
+#----------------------
+# Checking signal stuff
+#----------------------
+# TODO
+
+#------------------------------------------
+# Checking the mathlib and its capabilities
+#------------------------------------------
+# Function to check:
+mfuncs = [('expl', 'HAVE_LONGDOUBLE_FUNCS'),
+ ('expf', 'HAVE_FLOAT_FUNCS'),
+ ('log1p', 'HAVE_LOG1P'),
+ ('expm1', 'HAVE_EXPM1'),
+ ('asinh', 'HAVE_INVERSE_HYPERBOLIC'),
+ ('atanhf', 'HAVE_INVERSE_HYPERBOLIC_FLOAT'),
+ ('atanhl', 'HAVE_INVERSE_HYPERBOLIC_LONGDOUBLE'),
+ ('isnan', 'HAVE_ISNAN'),
+ ('isinf', 'HAVE_ISINF'),
+ ('rint', 'HAVE_RINT'),
+ ]
+
+# TODO: checklib vs checkfunc ?
+mlibs = [[], ['m'], ['cpml']]
+mathlib = os.environ.get('MATHLIB')
+if mathlib:
+ mlibs.insert(0, mathlib)
+for mlib in mlibs:
+ st = config.CheckBrokenMathlib(mlib)
+ if st:
+ break
+
+if not st:
+ import SCons
+ raise SCons.Errors.UserError("No usable mathlib was found: chose another "\
+ "one using the MATHLIB env variable, eg "\
+ "'MATHLIB=m python setup.py build'")
+# XXX: this is ugly: mathlib has nothing to do in a public header file
+config_sym.append(('MATHLIB', ','.join(mlib)))
+
+def check_lib(f, autoadd = 0):
+ """Check that f is available in mlib, and add the symbol appropriately.
+
+ f is expected to be a tuble (symbol, cpp define)."""
+ st = config.CheckLibWithHeader(mlib, 'math.h', language = 'C', call = '%s;' % f[0], autoadd = autoadd)
+ if st:
+ config_sym.append((f[1], 1))
+ else:
+ config_sym.append((f[1], 0))
+
+check_lib(mfuncs[0], autoadd = 1)
+for f in mfuncs[1:]:
+ check_lib(f)
+
+#-------------------------------------------------------
+# Define the function PyOS_ascii_strod if not available
+#-------------------------------------------------------
+# XXX: would be better to check for PyOS_ascii_strod instead of version
+if sys.version[:3] < '2.4':
+ if config.CheckFunc('strtod'):
+ config_sym.append(('PyOS_ascii_strtod', 'strtod'))
+
+if define_no_smp():
+ config_sym.append(('NPY_NOSMP', '1'))
+else:
+ config_sym.append(('NPY_NOSMP', '0'))
+
+# XXX: this is ugly
+if sys.platform=='win32' or os.name=='nt':
+ from distutils.msvccompiler 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':
+ moredefs.append(('DISTUTILS_USE_SDK', 1))
+
+#--------------
+# Checking Blas
+#--------------
+if config.CheckCBLAS():
+ build_blasdot = 1
+else:
+ build_blasdot = 0
+
+config.Finish()
+write_info(env)
+
+#==========
+# Build
+#==========
+
+#---------------------------------------
+# Generate the public configuration file
+#---------------------------------------
+config_dict = {}
+# XXX: this is ugly, make the API for config.h and numpyconfig.h similar
+for key, value in config_sym:
+ config_dict['@%s@' % key] = str(value)
+env['SUBST_DICT'] = config_dict
+
+include_dir = 'include/numpy'
+env.SubstInFile(pjoin(env['build_dir'], 'numpyconfig.h'),
+ pjoin(env['src_dir'], include_dir, 'numpyconfig.h.in'))
+
+env['CONFIG_H_GEN'] = config_sym
+
+#---------------------------
+# Builder for generated code
+#---------------------------
+from scons_support import do_generate_array_api, do_generate_ufunc_api, \
+ generate_api_emitter,\
+ generate_from_template, generate_from_template_emitter, \
+ generate_umath, generate_umath_emitter
+
+array_api_gen_bld = Builder(action = do_generate_array_api,
+ emitter = generate_api_emitter)
+
+ufunc_api_gen_bld = Builder(action = do_generate_ufunc_api,
+ emitter = generate_api_emitter)
+
+template_bld = Builder(action = generate_from_template,
+ emitter = generate_from_template_emitter)
+
+umath_bld = Builder(action = generate_umath,
+ emitter = generate_umath_emitter)
+
+config_h_bld = Builder(action = generate_config_header,
+ emitter = generate_config_header_emitter)
+
+env.Append(BUILDERS = {'GenerateMultiarrayApi' : array_api_gen_bld,
+ 'GenerateUfuncApi' : ufunc_api_gen_bld,
+ 'GenerateFromTemplate' : template_bld,
+ 'GenerateUmath' : umath_bld,
+ 'GenerateConfigHeader' : config_h_bld})
+
+#------------------------
+# Generate generated code
+#------------------------
+# XXX: the use of env['build_dir'] and env['src_dir'] are really ugly. Will
+# have to think about how removing them (using hierarchical scons and dir
+# option ?)
+from os.path import join as pjoin
+
+config_header = env.GenerateConfigHeader(pjoin(env['build_dir'], 'config.h'), [])
+
+scalartypes_src = env.GenerateFromTemplate(
+ pjoin(env['build_dir'], 'src', 'scalartypes'),
+ pjoin(env['src_dir'], 'src', 'scalartypes.inc.src'))
+
+arraytypes_src = env.GenerateFromTemplate(
+ pjoin(env['build_dir'], 'src', 'arraytypes'),
+ pjoin(env['src_dir'], 'src', 'arraytypes.inc.src'))
+
+sortmodule_src = env.GenerateFromTemplate(
+ pjoin(env['build_dir'], 'src', '_sortmodule'),
+ pjoin(env['src_dir'], 'src', '_sortmodule.c.src'))
+
+umathmodule_src = env.GenerateFromTemplate(
+ pjoin(env['build_dir'], 'src', 'umathmodule'),
+ pjoin(env['src_dir'], 'src', 'umathmodule.c.src'))
+
+scalarmathmodule_src = env.GenerateFromTemplate(
+ pjoin(env['build_dir'], 'src', 'scalarmathmodule'),
+ pjoin(env['src_dir'], 'src', 'scalarmathmodule.c.src'))
+
+umath = env.GenerateUmath(
+ pjoin(env['build_dir'], '__umath_generated'),
+ pjoin(env['src_dir'], 'code_generators', 'generate_umath.py'))
+
+multiarray_api = env.GenerateMultiarrayApi(
+ pjoin(env['build_dir'], 'multiarray_api'),
+ [ pjoin(env['src_dir'], 'code_generators',
+ 'array_api_order.txt'),
+ pjoin(env['src_dir'], 'code_generators',
+ 'multiarray_api_order.txt')])
+
+ufunc_api = env.GenerateUfuncApi(
+ pjoin(env['build_dir'], 'ufunc_api'),
+ pjoin(env['src_dir'], 'code_generators', 'ufunc_api_order.txt'))
+
+env.Append(CPPPATH = [pjoin(env['src_dir'], 'include'), env['build_dir']])
+
+#-----------------
+# Build multiarray
+#-----------------
+multiarray_src = [pjoin('src', 'multiarraymodule.c')]
+multiarray = env.NumpyPythonExtension('multiarray', source = multiarray_src)
+
+#------------------
+# Build sort module
+#------------------
+sort = env.NumpyPythonExtension('_sort', source = sortmodule_src)
+
+#-------------------
+# Build umath module
+#-------------------
+umathmodule = env.NumpyPythonExtension('umath', source = umathmodule_src)
+
+#------------------------
+# Build scalarmath module
+#------------------------
+scalarmathmodule = env.NumpyPythonExtension('scalarmath',
+ source = scalarmathmodule_src)
+
+#----------------------
+# Build _dotblas module
+#----------------------
+if build_blasdot:
+ dotblas_src = [pjoin('blasdot', i) for i in ['_dotblas.c']]
+ blasenv = env.Copy()
+ blasenv.Append(CPPPATH = pjoin(env['src_dir'], 'blasdot'))
+ dotblas = blasenv.NumpyPythonExtension('_dotblas', source = dotblas_src)