1import contextlib 2import os 3import re 4import sys 5import platform 6import subprocess 7import glob 8 9from codecs import open # To use a consistent encoding 10from setuptools import setup, Extension 11from setuptools.command.build_ext import build_ext 12from distutils.version import LooseVersion 13import distutils.log 14 15# Get the current directory path. 16dart_root = os.path.abspath(os.path.dirname(__file__)) 17dartpy_root = os.path.join(dart_root, 'python') 18 19with open(os.path.join(dart_root, 'README.md'), encoding='utf-8') as f: 20 long_description = f.read() 21description = 'Python API of Dynamic Animation and Robotics Toolkit.' 22 23distutils.log.set_verbosity(distutils.log.DEBUG) # Set DEBUG level 24 25 26class CMakeExtension(Extension): 27 def __init__(self, name, sourcedir='', sources=[]): 28 Extension.__init__(self, name, sources=sources) 29 self.sourcedir = os.path.abspath(sourcedir) 30 31 32class CMakeBuild(build_ext): 33 """ Wrapper class that builds the extension using CMake. """ 34 35 def run(self): 36 """ Build using CMake from the specified build directory. """ 37 try: 38 out = subprocess.check_output(['cmake', '--version']) 39 except OSError: 40 raise RuntimeError( 41 "CMake must be installed to build the following extensions: " + 42 ", ".join(e.name for e in self.extensions)) 43 44 if platform.system() == "Windows": 45 cmake_version = LooseVersion( 46 re.search(r'version\s*([\d.]+)', out.decode()).group(1)) 47 if cmake_version < '3.8.0': 48 raise RuntimeError("CMake >= 3.8.0 is required on Windows") 49 50 distutils.log.set_verbosity(distutils.log.DEBUG) # Set DEBUG level 51 52 for ext in self.extensions: 53 self.build_extension(ext) 54 55 def build_extension(self, ext): 56 cmake_args = [ 57 '-DDART_BUILD_DARTPY=ON', '-DPYTHON_EXECUTABLE=' + sys.executable 58 ] 59 60 cfg = 'Debug' if self.debug else 'Release' 61 build_args = ['--config', cfg] 62 63 if platform.system() == "Windows": 64 if sys.maxsize > 2**32: 65 cmake_args += ['-A', 'x64'] 66 build_args += ['--', '/m'] 67 else: 68 cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] 69 build_args += ['--', '-j4'] 70 71 env = os.environ.copy() 72 env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format( 73 env.get('CXXFLAGS', ''), self.distribution.get_version()) 74 if not os.path.exists(self.build_temp): 75 os.makedirs(self.build_temp) 76 subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, 77 cwd=self.build_temp, 78 env=env) 79 subprocess.check_call(['cmake', '--build', '.', '--target', 'dartpy'] + 80 build_args, 81 cwd=self.build_temp) 82 subprocess.check_call(['cmake', '--build', '.', '--target', 'install'], 83 cwd=self.build_temp) 84 85 86sources = ['CMakeLists.txt'] 87sources.extend(glob.glob('cmake/**/*', recursive=True)) 88sources.extend(glob.glob('dart/**/*', recursive=True)) 89sources.extend(glob.glob('python/**/*', recursive=True)) 90sources.extend(glob.glob('doxygen/**/*', recursive=True)) 91 92# Set up the python package wrapping this extension. 93setup( 94 name='dartpy', 95 version='0.0.1-10', 96 description=description, 97 long_description=long_description, 98 long_description_content_type='text/markdown', 99 ext_modules=[CMakeExtension('dartpy', sources=sources)], 100 url='https://github.com/dartsim/dart', 101 author='Jeongseok Lee', 102 author_email='jslee02@gmail.com', 103 license='BSD 2-Clause', 104 keywords='dartsim robotics', 105 classifiers=[ 106 'Development Status :: 2 - Pre-Alpha', 107 'Framework :: Robot Framework', 108 'Intended Audience :: Science/Research', 109 'License :: OSI Approved :: BSD License', 110 'Topic :: Scientific/Engineering', 111 ], 112 cmdclass=dict(build_ext=CMakeBuild), 113) 114