1from __future__ import print_function 2 3# Preliminary checks that cannot be done by setuptools 4# like... the setuptools dependency itself! 5try: 6 import setuptools 7except ImportError: 8 print() 9 print("*****************************************************") 10 print("* Setuptools must be installed before running setup *") 11 print("*****************************************************") 12 print() 13 raise 14 15from setuptools.command.build_py import build_py 16from setuptools.command.develop import develop 17 18from setuptools import setup 19 20import logging 21import os 22import shutil 23import sys 24 25# It appears old versions of setuptools are not supported, see 26# https://github.com/serge-sans-paille/pythran/issues/489 27 28from distutils.version import LooseVersion 29MinimalSetuptoolsVersion = LooseVersion("12.0.5") 30if LooseVersion(setuptools.__version__) < MinimalSetuptoolsVersion: 31 msg = "Setuptools version is {}, but must be at least {}".format( 32 setuptools.__version__, 33 MinimalSetuptoolsVersion) 34 print() 35 print("*" * (len(msg) + 4)) 36 print("*", msg, "*") 37 print("*" * (len(msg) + 4)) 38 print() 39 raise ImportError("setuptools") 40 41if sys.version_info.major < 3: 42 print() 43 print("****************************************************") 44 print("* Python 2 has reached end-of-support *") 45 print("****************************************************") 46 print("* *") 47 print("* Last Pythran version supporting Python2 is 0.9.5 *") 48 print("* *") 49 print("****************************************************") 50 print() 51 52 53logger = logging.getLogger("pythran") 54logger.addHandler(logging.StreamHandler()) 55 56versionfile = os.path.join('pythran', 'version.py') 57exec(open(versionfile).read()) 58 59 60class BuildWithThirdParty(build_py): 61 62 """ 63 Set up Pythran dependencies. 64 65 * install boost dependencies 66 * install xsimd dependencies 67 """ 68 69 third_parties = 'boost', 'xsimd' 70 71 user_options = build_py.user_options + [ 72 ('no-{}'.format(pkg), None, 'Do not distribute {} headers'.format(pkg)) 73 for pkg in third_parties 74 ] 75 76 def initialize_options(self): 77 build_py.initialize_options(self) 78 for pkg in BuildWithThirdParty.third_parties: 79 setattr(self, 'no_' + pkg, None) 80 81 def copy_pkg(self, pkg, src_only=False): 82 "Install boost deps from the third_party directory" 83 84 if getattr(self, 'no_' + pkg) is None: 85 print('Copying', pkg, 'dependencies') 86 to_copy = pkg, 87 else: 88 return 89 90 src = os.path.join('third_party', *to_copy) 91 92 # copy to the build tree 93 if not src_only: 94 target = os.path.join(self.build_lib, 'pythran', *to_copy) 95 shutil.rmtree(target, True) 96 shutil.copytree(src, target) 97 98 # copy them to the source tree too, needed for sdist 99 target = os.path.join('pythran', *to_copy) 100 shutil.rmtree(target, True) 101 shutil.copytree(src, target) 102 103 def run(self, *args, **kwargs): 104 # regular build done by parent class 105 build_py.run(self, *args, **kwargs) 106 if not self.dry_run: # compatibility with the parent options 107 for pkg in BuildWithThirdParty.third_parties: 108 self.copy_pkg(pkg) 109 110 111class DevelopWithThirdParty(develop, BuildWithThirdParty): 112 113 def initialize_options(self): 114 develop.initialize_options(self) 115 BuildWithThirdParty.initialize_options(self) 116 117 def run(self, *args, **kwargs): 118 if not self.dry_run: # compatibility with the parent options 119 for pkg in BuildWithThirdParty.third_parties: 120 self.copy_pkg(pkg, src_only=True) 121 develop.run(self, *args, **kwargs) 122 123 124# Cannot use glob here, as the files may not be generated yet 125boost_headers = ['boost/' + '*/' * i + '*.hpp' for i in range(1, 20)] 126xsimd_headers = ['xsimd/' + '*/' * i + '*.hpp' for i in range(1, 20)] 127pythonic_headers = ['*/' * i + '*.hpp' for i in range(9)] + ['patch/*'] 128 129 130# read longdescr from README 131def longdescr(readme_path): 132 with open(readme_path) as readme: 133 lines = list(readme) 134 start_index = lines.index('What is it?\n') 135 stop_index = lines.index('Installation\n') 136 long_description = "".join(lines[start_index + 2: stop_index]) 137 return long_description 138 139 140setup(name='pythran', 141 version=__version__, 142 description=__descr__, 143 long_description=longdescr("README.rst"), 144 author='Serge Guelton', 145 author_email='serge.guelton@telecom-bretagne.eu', 146 url=__url__, 147 packages=['pythran', 'pythran.analyses', 'pythran.transformations', 148 'pythran.optimizations', 'omp', 'pythran/pythonic', 149 'pythran.types'], 150 package_data={'pythran': (['pythran*.cfg'] 151 + boost_headers 152 + xsimd_headers), 153 'pythran/pythonic': pythonic_headers}, 154 classifiers=[ 155 'Development Status :: 4 - Beta', 156 'Environment :: Console', 157 'Intended Audience :: Developers', 158 'License :: OSI Approved :: BSD License', 159 'Natural Language :: English', 160 'Operating System :: POSIX :: Linux', 161 'Operating System :: MacOS', 162 'Programming Language :: Python :: 2.7', 163 'Programming Language :: Python :: 3', 164 'Programming Language :: Python :: Implementation :: CPython', 165 'Programming Language :: C++', 166 'Topic :: Software Development :: Compilers', 167 'Topic :: Software Development :: Code Generators' 168 ], 169 license="BSD 3-Clause", 170 install_requires=open('requirements.txt').read().splitlines(), 171 entry_points={'console_scripts': 172 ['pythran = pythran.run:run', 173 'pythran-config = pythran.config:run']}, 174 extras_require={ 175 'doc': open('docs/requirements.txt').read().splitlines(), 176 }, 177 test_suite="pythran.tests.test_cases", 178 cmdclass={'build_py': BuildWithThirdParty, 179 'develop': DevelopWithThirdParty}) 180