/ setup-legacy.py
setup-legacy.py
  1  import sys
  2  import os
  3  
  4  if sys.version.find('MSC') == -1:
  5      windows = False
  6  else:
  7      windows = True
  8  
  9  if windows:
 10      try:
 11          from setuptools import setup, Extension
 12      except ImportError:
 13          from distutils.core import setup, Extension
 14  else:
 15      from distutils.core import setup, Extension
 16  
 17  from distutils.command.clean import clean
 18  from distutils.command.build_ext import build_ext
 19  from distutils.command.install_data import install_data
 20  
 21  def writeln(s):
 22      sys.stdout.write('%s\n' % s)
 23      sys.stdout.flush()
 24  
 25  # Utility function to read the contents of the README file.
 26  def read(fname):
 27      return open(os.path.join(os.path.dirname(__file__), fname)).read()
 28  
 29  # Fail gracefully for old versions of Python.
 30  
 31  if sys.version[:3] < '2.6':
 32      writeln("GMPY2 requires Python 2.6 or later.")
 33      writeln("Please use GMPY 1.x for earlier versions of Python.")
 34      sys.exit()
 35  
 36  # Run python setup.py build_ext --help for build options
 37  
 38  # Notes regarding coverage testing.
 39  #
 40  # The --gcov command line option configures GCC to collect code coverage data
 41  # for testing purposes. The raw collected data can be converted to .gcov files
 42  # with the command "gcov build/temp.linux-x86_64-3.4/src/gmpy2.gcno". To create
 43  # a tidy HTML summary, use "gcovr -s -r . --html -o coverage.html". When tests
 44  # are completed, delete the .gcov and coverage.html files.
 45  #
 46  # The following commands show the use of lcov to analyze the coverage data.
 47  #
 48  #   py34 setup.py clean
 49  #   py34 setup.py install --gcov --force
 50  #   py34 test/runtests.py
 51  #   lcov --capture --directory build/temp.linux-x86_64-3.4/src/gmpy2.gcno --output-file build/coverage.info
 52  #   genhtml build/coverage.info --output-directory build/out
 53  #   firefox build/out/index.html
 54  #
 55  # Remember to remove the *.gcov file and the out sub-directory.
 56  
 57  
 58  # Improved clean command.
 59  
 60  class gmpy_clean(clean):
 61  
 62      def run(self):
 63          self.all = True
 64          clean.run(self)
 65  
 66  build_options = [
 67      ('mpir', None, 'Build using mpir; deprecated'),
 68      ('msys2', None, 'Build in msys2 environment'),
 69      ('gcov', None, 'configure GCC to collect code coverage data for testing purposes'),
 70      ('fast', None, 'depend on MPFR and MPC internal implementations details'),
 71      ('vector', None, 'include the vector_XXX() functions; they are unstable and under active development'),
 72      ('shared', None, 'Build using shared libraries'),
 73      ('static', None, 'Build using static libraries'),
 74  ]
 75  
 76  # Define a custom build class that parses to the defined macros to alter the
 77  # build setup.
 78  
 79  class gmpy_build_ext(build_ext):
 80      default_opts = build_ext.user_options
 81      user_options = list(build_options)
 82      user_options.extend(default_opts)
 83  
 84      def initialize_options(self):
 85          build_ext.initialize_options(self)
 86          self.mpir = False
 87          self.msys2 = False
 88          self.gcov = False
 89          self.fast = False
 90          self.vector = False
 91          self.static = None
 92          self.shared = None
 93  
 94      def doit(self):
 95          # Find the directory specfied for non-standard library location.
 96  
 97          defines = []
 98  
 99          if self.static is None and self.shared is None:
100              self.shared = True
101  
102          if self.gcov:
103              self.extensions[0].libraries.append('gcov')
104              self.extensions[0].extra_compile_args.extend(['-O0', '--coverage'])
105              self.extensions[0].extra_link_args.append('--coverage')
106  
107          if self.vector:
108              defines.append(('VECTOR', 1))
109  
110          if self.fast:
111              defines.append(('FAST', 1))
112  
113          if self.msys2:
114              defines.append(('MSYS2', 1))
115  
116          if self.mpir:
117              defines.append(('MPIR', 1))
118  
119          if self.shared:
120              defines.append(('SHARED', 1))
121  
122          if self.static:
123              defines.append(('STATIC', 1))
124  
125          if self.mpir:
126              self.extensions[0].libraries.extend(['mpir', 'mpfr', 'mpc'])
127          else:
128              self.extensions[0].libraries.extend(['gmp', 'mpfr', 'mpc'])
129  
130          # Add MSVC specific options.
131          if windows and not self.msys2:
132              self.extensions[0].extra_link_args.append('/MANIFEST')
133              defines.append(("MPIR", 1))
134              if not self.static:
135                  defines.append(("MSC_USE_DLL", None))
136  
137          self.extensions[0].define_macros.extend(defines)
138  
139  
140      def finalize_options(self):
141          build_ext.finalize_options(self)
142          gmpy_build_ext.doit(self)
143  
144  # custom install data in order that data_files
145  # get installed together with the .so
146  
147  class gmpy_install_data(install_data):
148      def finalize_options(self):
149          install_data.finalize_options(self)
150          install = self.distribution.get_command_obj('install')
151          self.install_dir = install.install_purelib
152  
153  # prepare the extension for building
154  
155  my_commands = {'clean' : gmpy_clean, 'build_ext' : gmpy_build_ext, 'install_data' : gmpy_install_data}
156  
157  gmpy2_ext = Extension('gmpy2',
158                        sources=[os.path.join('src', 'gmpy2.c')],
159                        include_dirs=['./src'])
160  
161  setup(name = "gmpy2",
162        version = "2.1.0b6",
163        author = "Case Van Horsen",
164        author_email = "casevh@gmail.com",
165        license = "LGPL-3.0+",
166        url = "https://github.com/aleaxit/gmpy",
167        description = "gmpy2 interface to GMP, MPFR, and MPC for Python 2.7 and 3.4+",
168        long_description = read('README'),
169        data_files = [('', ['src/gmpy2.pxd']), ('gmpy2', ['src/gmpy2.h'])],
170        classifiers = [
171          'Development Status :: 4 - Beta',
172          'Intended Audience :: Developers',
173          'Intended Audience :: Science/Research',
174          'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)',
175          'Natural Language :: English',
176          'Operating System :: MacOS :: MacOS X',
177          'Operating System :: Microsoft :: Windows',
178          'Operating System :: POSIX',
179          'Programming Language :: C',
180          'Programming Language :: Python :: 2',
181          'Programming Language :: Python :: 2.7',
182          'Programming Language :: Python :: 3',
183          'Programming Language :: Python :: 3.4',
184          'Programming Language :: Python :: 3.5',
185          'Programming Language :: Python :: 3.6',
186          'Programming Language :: Python :: 3.7',
187          'Programming Language :: Python :: 3.8',
188          'Programming Language :: Python :: Implementation :: CPython',
189          'Topic :: Scientific/Engineering :: Mathematics',
190          'Topic :: Software Development :: Libraries :: Python Modules',
191        ],
192        keywords = "gmp mpir mpfr mpc multiple-precision arbitrary-precision precision bignum",
193        cmdclass = my_commands,
194        ext_modules = [gmpy2_ext]
195  )