1import os 2import platform 3import sys 4from distutils import sysconfig 5from distutils.command import build 6from distutils.spawn import spawn 7 8from setuptools import Extension, find_packages, setup 9 10import versioneer 11 12min_python_version = "3.6" 13min_numpy_build_version = "1.11" 14min_numpy_run_version = "1.15" 15min_llvmlite_version = "0.34.0.dev0" 16max_llvmlite_version = "0.35" 17 18if sys.platform.startswith('linux'): 19 # Patch for #2555 to make wheels without libpython 20 sysconfig.get_config_vars()['Py_ENABLE_SHARED'] = 0 21 22 23class build_doc(build.build): 24 description = "build documentation" 25 26 def run(self): 27 spawn(['make', '-C', 'docs', 'html']) 28 29 30versioneer.VCS = 'git' 31versioneer.versionfile_source = 'numba/_version.py' 32versioneer.versionfile_build = 'numba/_version.py' 33versioneer.tag_prefix = '' 34versioneer.parentdir_prefix = 'numba-' 35 36cmdclass = versioneer.get_cmdclass() 37cmdclass['build_doc'] = build_doc 38 39 40GCCFLAGS = ["-std=c89", "-Wdeclaration-after-statement", "-Werror"] 41 42if os.environ.get("NUMBA_GCC_FLAGS"): 43 CFLAGS = GCCFLAGS 44else: 45 CFLAGS = ['-g'] 46 47install_name_tool_fixer = [] 48if sys.platform == 'darwin': 49 install_name_tool_fixer += ['-headerpad_max_install_names'] 50 51 52def is_building(): 53 """ 54 Parse the setup.py command and return whether a build is requested. 55 If False is returned, only an informational command is run. 56 If True is returned, information about C extensions will have to 57 be passed to the setup() function. 58 """ 59 if len(sys.argv) < 2: 60 # User forgot to give an argument probably, let setuptools handle that. 61 return True 62 63 info_commands = ['--help-commands', '--name', '--version', '-V', 64 '--fullname', '--author', '--author-email', 65 '--maintainer', '--maintainer-email', '--contact', 66 '--contact-email', '--url', '--license', '--description', 67 '--long-description', '--platforms', '--classifiers', 68 '--keywords', '--provides', '--requires', '--obsoletes'] 69 # Add commands that do more than print info, but also don't need 70 # any build step. 71 info_commands.extend(['egg_info', 'install_egg_info', 'rotate']) 72 73 for command in info_commands: 74 if command in sys.argv[1:]: 75 return False 76 77 return True 78 79 80def get_ext_modules(): 81 """ 82 Return a list of Extension instances for the setup() call. 83 """ 84 # Note we don't import Numpy at the toplevel, since setup.py 85 # should be able to run without Numpy for pip to discover the 86 # build dependencies 87 import numpy.distutils.misc_util as np_misc 88 89 # Inject required options for extensions compiled against the Numpy 90 # C API (include dirs, library dirs etc.) 91 np_compile_args = np_misc.get_info('npymath') 92 93 ext_dynfunc = Extension(name='numba._dynfunc', 94 sources=['numba/_dynfuncmod.c'], 95 extra_compile_args=CFLAGS, 96 depends=['numba/_pymodule.h', 97 'numba/_dynfunc.c']) 98 99 ext_dispatcher = Extension(name="numba._dispatcher", 100 sources=['numba/_dispatcher.c', 101 'numba/_typeof.c', 102 'numba/_hashtable.c', 103 'numba/_dispatcherimpl.cpp', 104 'numba/core/typeconv/typeconv.cpp'], 105 depends=["numba/_pymodule.h", 106 "numba/_dispatcher.h", 107 "numba/_typeof.h", 108 "numba/_hashtable.h"], 109 **np_compile_args) 110 111 ext_helperlib = Extension(name="numba._helperlib", 112 sources=["numba/_helpermod.c", 113 "numba/cext/utils.c", 114 "numba/cext/dictobject.c", 115 "numba/cext/listobject.c", 116 ], 117 extra_compile_args=CFLAGS, 118 extra_link_args=install_name_tool_fixer, 119 depends=["numba/_pymodule.h", 120 "numba/_helperlib.c", 121 "numba/_lapack.c", 122 "numba/_npymath_exports.c", 123 "numba/_random.c", 124 "numba/mathnames.inc", 125 ], 126 **np_compile_args) 127 128 ext_typeconv = Extension(name="numba.core.typeconv._typeconv", 129 sources=["numba/core/typeconv/typeconv.cpp", 130 "numba/core/typeconv/_typeconv.cpp"], 131 depends=["numba/_pymodule.h"], 132 ) 133 134 ext_np_ufunc = Extension(name="numba.np.ufunc._internal", 135 sources=["numba/np/ufunc/_internal.c"], 136 depends=["numba/np/ufunc/_ufunc.c", 137 "numba/np/ufunc/_internal.h", 138 "numba/_pymodule.h"], 139 **np_compile_args) 140 141 ext_npyufunc_num_threads = Extension(name="numba.np.ufunc._num_threads", 142 sources=[ 143 "numba/np/ufunc/_num_threads.c"], 144 depends=["numba/_pymodule.h"], 145 ) 146 147 ext_np_ufunc_backends = [] 148 149 def check_file_at_path(path2file): 150 """ 151 Takes a list as a path, a single glob (*) is permitted as an entry which 152 indicates that expansion at this location is required (i.e. version 153 might not be known). 154 """ 155 found = None 156 path2check = [os.path.split(os.path.split(sys.executable)[0])[0]] 157 path2check += [os.getenv(n, '') for n in ['CONDA_PREFIX', 'PREFIX']] 158 if sys.platform.startswith('win'): 159 path2check += [os.path.join(p, 'Library') for p in path2check] 160 for p in path2check: 161 if p: 162 if '*' in path2file: 163 globloc = path2file.index('*') 164 searchroot = os.path.join(*path2file[:globloc]) 165 try: 166 potential_locs = os.listdir(os.path.join(p, searchroot)) 167 except BaseException: 168 continue 169 searchfor = path2file[globloc + 1:] 170 for x in potential_locs: 171 potpath = os.path.join(p, searchroot, x, *searchfor) 172 if os.path.isfile(potpath): 173 found = p # the latest is used 174 elif os.path.isfile(os.path.join(p, *path2file)): 175 found = p # the latest is used 176 return found 177 178 # Set various flags for use in TBB and openmp. On OSX, also find OpenMP! 179 have_openmp = True 180 if sys.platform.startswith('win'): 181 cpp11flags = [] 182 ompcompileflags = ['-openmp'] 183 omplinkflags = [] 184 elif sys.platform.startswith('darwin'): 185 cpp11flags = ['-std=c++11'] 186 # This is a bit unusual but necessary... 187 # llvm (clang) OpenMP is used for headers etc at compile time 188 # Intel OpenMP (libiomp5) provides the link library. 189 # They are binary compatible and may not safely coexist in a process, as 190 # libiomp5 is more prevalent and often linked in for NumPy it is used 191 # here! 192 ompcompileflags = ['-fopenmp'] 193 omplinkflags = ['-fopenmp=libiomp5'] 194 omppath = ['lib', 'clang', '*', 'include', 'omp.h'] 195 have_openmp = check_file_at_path(omppath) 196 else: 197 cpp11flags = ['-std=c++11'] 198 ompcompileflags = ['-fopenmp'] 199 if platform.machine() == 'ppc64le': 200 omplinkflags = ['-fopenmp'] 201 else: 202 omplinkflags = ['-fopenmp'] 203 204 # Disable tbb if forced by user with NUMBA_DISABLE_TBB=1 205 if os.getenv("NUMBA_DISABLE_TBB"): 206 print("TBB disabled") 207 else: 208 # Search for Intel TBB, first check env var TBBROOT then conda locations 209 tbb_root = os.getenv('TBBROOT') 210 if not tbb_root: 211 tbb_root = check_file_at_path(['include', 'tbb', 'tbb.h']) 212 213 if tbb_root: 214 print("Using Intel TBB from:", tbb_root) 215 ext_np_ufunc_tbb_backend = Extension( 216 name='numba.np.ufunc.tbbpool', 217 sources=[ 218 'numba/np/ufunc/tbbpool.cpp', 219 'numba/np/ufunc/gufunc_scheduler.cpp', 220 ], 221 depends=['numba/np/ufunc/workqueue.h'], 222 include_dirs=[os.path.join(tbb_root, 'include')], 223 extra_compile_args=cpp11flags, 224 libraries=['tbb'], # TODO: if --debug or -g, use 'tbb_debug' 225 library_dirs=[ 226 # for Linux 227 os.path.join(tbb_root, 'lib', 'intel64', 'gcc4.4'), 228 # for MacOS 229 os.path.join(tbb_root, 'lib'), 230 # for Windows 231 os.path.join(tbb_root, 'lib', 'intel64', 'vc_mt'), 232 ], 233 ) 234 ext_np_ufunc_backends.append(ext_np_ufunc_tbb_backend) 235 else: 236 print("TBB not found") 237 238 # Disable OpenMP if forced by user with NUMBA_DISABLE_OPENMP=1 239 if os.getenv('NUMBA_DISABLE_OPENMP'): 240 print("OpenMP disabled") 241 elif have_openmp: 242 print("Using OpenMP from:", have_openmp) 243 # OpenMP backed work queue 244 ext_np_ufunc_omppool_backend = Extension( 245 name='numba.np.ufunc.omppool', 246 sources=[ 247 'numba/np/ufunc/omppool.cpp', 248 'numba/np/ufunc/gufunc_scheduler.cpp', 249 ], 250 depends=['numba/np/ufunc/workqueue.h'], 251 extra_compile_args=ompcompileflags + cpp11flags, 252 extra_link_args=omplinkflags, 253 ) 254 255 ext_np_ufunc_backends.append(ext_np_ufunc_omppool_backend) 256 else: 257 print("OpenMP not found") 258 259 # Build the Numba workqueue implementation irrespective of whether the TBB 260 # version is built. Users can select a backend via env vars. 261 ext_np_ufunc_workqueue_backend = Extension( 262 name='numba.np.ufunc.workqueue', 263 sources=['numba/np/ufunc/workqueue.c', 264 'numba/np/ufunc/gufunc_scheduler.cpp'], 265 depends=['numba/np/ufunc/workqueue.h']) 266 ext_np_ufunc_backends.append(ext_np_ufunc_workqueue_backend) 267 268 ext_mviewbuf = Extension(name='numba.mviewbuf', 269 extra_link_args=install_name_tool_fixer, 270 sources=['numba/mviewbuf.c']) 271 272 ext_nrt_python = Extension(name='numba.core.runtime._nrt_python', 273 sources=['numba/core/runtime/_nrt_pythonmod.c', 274 'numba/core/runtime/nrt.c'], 275 depends=['numba/core/runtime/nrt.h', 276 'numba/_pymodule.h', 277 'numba/core/runtime/_nrt_python.c'], 278 **np_compile_args) 279 280 ext_jitclass_box = Extension(name='numba.experimental.jitclass._box', 281 sources=['numba/experimental/jitclass/_box.c'], 282 depends=['numba/experimental/_pymodule.h'], 283 ) 284 285 ext_cuda_extras = Extension(name='numba.cuda.cudadrv._extras', 286 sources=['numba/cuda/cudadrv/_extras.c'], 287 depends=['numba/_pymodule.h'], 288 include_dirs=["numba"]) 289 290 ext_modules = [ext_dynfunc, ext_dispatcher, ext_helperlib, ext_typeconv, 291 ext_np_ufunc, ext_npyufunc_num_threads, ext_mviewbuf, 292 ext_nrt_python, ext_jitclass_box, ext_cuda_extras] 293 294 ext_modules += ext_np_ufunc_backends 295 296 return ext_modules 297 298 299packages = find_packages(include=["numba", "numba.*"]) 300 301build_requires = ['numpy >={}'.format(min_numpy_build_version)] 302install_requires = [ 303 'llvmlite >={},<{}'.format(min_llvmlite_version, max_llvmlite_version), 304 'numpy >={}'.format(min_numpy_run_version), 305 'setuptools', 306] 307 308metadata = dict( 309 name='numba', 310 description="compiling Python code using LLVM", 311 version=versioneer.get_version(), 312 classifiers=[ 313 "Development Status :: 4 - Beta", 314 "Intended Audience :: Developers", 315 "License :: OSI Approved :: BSD License", 316 "Operating System :: OS Independent", 317 "Programming Language :: Python", 318 "Programming Language :: Python :: 3", 319 "Programming Language :: Python :: 3.6", 320 "Programming Language :: Python :: 3.7", 321 "Programming Language :: Python :: 3.8", 322 "Topic :: Software Development :: Compilers", 323 ], 324 package_data={ 325 # HTML templates for type annotations 326 "numba.core.annotations": ["*.html"], 327 # Various test data 328 "numba.cuda.tests.cudadrv.data": ["*.ptx"], 329 "numba.tests": ["pycc_distutils_usecase/*.py"], 330 # Some C files are needed by pycc 331 "numba": ["*.c", "*.h"], 332 "numba.pycc": ["*.c", "*.h"], 333 "numba.core.runtime": ["*.c", "*.h"], 334 "numba.cext": ["*.c", "*.h"], 335 # numba gdb hook init command language file 336 "numba.misc": ["cmdlang.gdb"], 337 }, 338 scripts=["numba/pycc/pycc", "bin/numba"], 339 author="Anaconda, Inc.", 340 author_email="numba-users@continuum.io", 341 url="https://numba.github.com", 342 packages=packages, 343 setup_requires=build_requires, 344 install_requires=install_requires, 345 python_requires=">={}".format(min_python_version), 346 license="BSD", 347 cmdclass=cmdclass, 348) 349 350with open('README.rst') as f: 351 metadata['long_description'] = f.read() 352 353if is_building(): 354 metadata['ext_modules'] = get_ext_modules() 355 356setup(**metadata) 357