setup.py (132 lines of code) (raw):

#!/usr/bin/env python # -*- coding: utf-8 -*- """ Setup script for pybox2d. For installation instructions, see INSTALL. Basic install steps: python setup.py build If that worked, then: python setup.py install """ import os import sys from glob import glob __author__='Ken Lauer' __license__='zlib' __date__="$Date$" __version__="$Revision$" import setuptools from setuptools import (setup, Extension) from setuptools.command.install import install setuptools_version = setuptools.__version__ print('Using setuptools (version %s).' % setuptools_version) if setuptools_version: if (setuptools_version in ["0.6c%d"%i for i in range(1,9)] # old versions or setuptools_version=="0.7a1"): # 0.7a1 py 3k alpha version based on old version print('Patching setuptools.build_ext.get_ext_filename') from setuptools.command import build_ext def get_ext_filename(self, fullname): from setuptools.command.build_ext import (_build_ext, Library, use_stubs) filename = _build_ext.get_ext_filename(self,fullname) if fullname in self.ext_map: ext = self.ext_map[fullname] if isinstance(ext,Library): fn, ext = os.path.splitext(filename) return self.shlib_compiler.library_filename(fn,libtype) elif use_stubs and ext._links_to_dynamic: d,fn = os.path.split(filename) return os.path.join(d,'dl-'+fn) return filename build_ext.build_ext.get_ext_filename = get_ext_filename # release version number box2d_version = '2.3' release_number = 8 # create the version string version_str = "%s.%s" % (box2d_version, release_number) # setup some paths and names library_base='library' # the directory where the egg base will be for setuptools develop command library_name='Box2D' # the final name that the library should end up being library_path=os.path.join(library_base, library_name) # library/Box2D (e.g.) source_dir='Box2D' # where all of the C++ and SWIG source resides swig_source='Box2D.i' # the main SWIG source file use_kwargs=True # whether or not to default creating kwargs for all functions def write_init(): # read in the license header license_header = open(os.path.join(source_dir, 'pybox2d_license_header.txt')).read() # create the source code for the file if sys.version_info >= (2, 6): import_string = "from .%s import *" % library_name else: import_string = "from %s import *" % library_name init_source = [ import_string, "__author__ = '%s'" % __date__ , "__version__ = '%s'" % version_str, "__version_info__ = (%s,%d)" % (box2d_version.replace('.', ','), release_number), "__revision__ = '%s'" % __version__, "__license__ = '%s'" % __license__ , "__date__ = '%s'" % __date__ , ] # and create the __init__ file with the appropriate version string f=open(os.path.join(library_path, '__init__.py'), 'w') f.write(license_header) f.write( '\n'.join(init_source) ) f.close() source_paths = [ os.path.join(source_dir, 'Dynamics'), os.path.join(source_dir, 'Dynamics', 'Contacts'), os.path.join(source_dir, 'Dynamics', 'Joints'), os.path.join(source_dir, 'Common'), os.path.join(source_dir, 'Collision'), os.path.join(source_dir, 'Collision', 'Shapes'), ] # glob all of the paths and then flatten the list into one box2d_source_files = [os.path.join(source_dir, swig_source)] + \ sum( [glob(os.path.join(path, "*.cpp")) for path in source_paths], []) # arguments to pass to SWIG. for old versions of SWIG, -O (optimize) might not be present. # Defaults: # -O optimize, -includeall follow all include statements, -globals changes cvar->b2Globals # -Isource_dir adds source dir to include path, -outdir library_path sets the output directory # -small makes the Box2D_wrap.cpp file almost unreadable, but faster to compile. If you want # to try to understand it for whatever reason, I'd recommend removing that option. swig_arguments = \ '-c++ -I%s -small -O -includeall -ignoremissing -w201 -globals b2Globals -outdir %s' \ % (source_dir, library_path) if use_kwargs: # turn off the warnings about functions that can't use kwargs (-w511) # and let the wrapper know we're using kwargs (-D_SWIG_KWARGS) swig_arguments += " -keyword -w511 -D_SWIG_KWARGS" # depending on the platform, add extra compilation arguments. hopefully if the platform # isn't windows, g++ will be used; -Wno-unused then would suppress some annoying warnings # about the Box2D source. if sys.platform in ('win32', 'win64'): extra_args=['-I.'] else: extra_args=['-I.', '-Wno-unused'] pybox2d_extension = \ Extension('Box2D._Box2D', box2d_source_files, extra_compile_args=extra_args, language='c++') LONG_DESCRIPTION = \ """ 2D physics library Box2D %s for usage in Python. After installing please be sure to try out the testbed demos. They require either pygame or pyglet and are available on the homepage. pybox2d homepage: http://pybox2d.googlecode.com Box2D homepage: http://www.box2d.org """ % (box2d_version,) CLASSIFIERS = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: zlib/libpng License", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Libraries :: pygame", ] class PostInstallHook(install): ''' Describes actions to be executed after the install. In this case, install has the wrong order of operations - it first copies *.py files, then builds *.py files using swig. This class copies new *.py files one more time after install. ''' def run(self): import os import shutil recopy_list = ['Box2D.py', '__init__.py'] install.run(self) dest = os.path.split(self.get_outputs()[0])[0] for fname in recopy_list: local_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), library_base, library_name, fname) installed_path = os.path.join(dest, fname) print('Re-copying {} --> {}'.format(local_path, installed_path)) shutil.copyfile(local_path, installed_path) write_init() setup_dict = dict( name = "box2d-py", version = version_str, author = "Ken Lauer", author_email = "sirkne@gmail.com", description = "Python Box2D", license = "zlib", url = "https://github.com/openai/box2d-py", long_description = LONG_DESCRIPTION, classifiers = CLASSIFIERS, packages = ['Box2D', 'Box2D.b2'], package_dir = {'Box2D': library_path, 'Box2D.b2': os.path.join(library_path, 'b2'), 'Box2D.tests' : 'tests'}, test_suite = 'tests', options = { 'build_ext': { 'swig_opts' : swig_arguments }, 'egg_info' : { 'egg_base' : library_base }, }, ext_modules = [ pybox2d_extension ], cmdclass = {'install': PostInstallHook}, # use_2to3 = (sys.version_info >= (3,)), ) # run the actual setup from distutils setup(**setup_dict)