1import os 2import sys 3import shutil 4from distutils import log 5from distutils.core import setup 6from distutils.extension import Extension 7from distutils.command.build import build 8from Cython.Distutils import build_ext 9 10 11SYSTEM = sys.platform 12VERSION = '3.0.5' 13 14# adapted from commit e504b81 of Nguyen Tan Cong 15# Reference: https://docs.python.org/2/library/platform.html#cross-platform 16IS_64BITS = sys.maxsize > 2**32 17 18# are we building from the repository or from a source distribution? 19ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) 20LIBS_DIR = os.path.join(ROOT_DIR, 'pyx', 'lib') 21HEADERS_DIR = os.path.join(ROOT_DIR, 'pyx', 'include') 22SRC_DIR = os.path.join(ROOT_DIR, 'src') 23BUILD_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..') 24PYPACKAGE_DIR = os.path.join(ROOT_DIR, 'capstone') 25CYPACKAGE_DIR = os.path.join(ROOT_DIR, 'pyx') 26 27if SYSTEM == 'darwin': 28 LIBRARY_FILE = "libcapstone.dylib" 29 STATIC_LIBRARY_FILE = 'libcapstone.a' 30elif SYSTEM in ('win32', 'cygwin'): 31 LIBRARY_FILE = "capstone.dll" 32 STATIC_LIBRARY_FILE = None 33else: 34 LIBRARY_FILE = "libcapstone.so" 35 STATIC_LIBRARY_FILE = 'libcapstone.a' 36 37compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR] 38link_args = ['-L' + LIBS_DIR] 39 40ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const'] 41ext_modules = [Extension("capstone.ccapstone", 42 ["pyx/ccapstone.pyx"], 43 libraries=["capstone"], 44 extra_compile_args=compile_args, 45 extra_link_args=link_args)] 46ext_modules += [Extension("capstone.%s" % name, 47 ["pyx/%s.pyx" % name], 48 extra_compile_args=compile_args, 49 extra_link_args=link_args) 50 for name in ext_module_names] 51 52def clean_bins(): 53 shutil.rmtree(LIBS_DIR, ignore_errors=True) 54 shutil.rmtree(HEADERS_DIR, ignore_errors=True) 55 56def copy_pysources(): 57 for fname in os.listdir(PYPACKAGE_DIR): 58 if not fname.endswith('.py'): 59 continue 60 61 if fname == '__init__.py': 62 shutil.copy(os.path.join(PYPACKAGE_DIR, fname), os.path.join(CYPACKAGE_DIR, fname)) 63 else: 64 shutil.copy(os.path.join(PYPACKAGE_DIR, fname), os.path.join(CYPACKAGE_DIR, fname + 'x')) 65 66def build_libraries(): 67 """ 68 Prepare the capstone directory for a binary distribution or installation. 69 Builds shared libraries and copies header files. 70 71 Will use a src/ dir if one exists in the current directory, otherwise assumes it's in the repo 72 """ 73 cwd = os.getcwd() 74 clean_bins() 75 os.mkdir(HEADERS_DIR) 76 os.mkdir(LIBS_DIR) 77 78 # copy public headers 79 shutil.copytree(os.path.join(BUILD_DIR, 'include'), os.path.join(HEADERS_DIR, 'capstone')) 80 81 os.chdir(BUILD_DIR) 82 83 # platform description refers at https://docs.python.org/2/library/sys.html#sys.platform 84 if SYSTEM == "win32": 85 # Windows build: this process requires few things: 86 # - CMake + MSVC installed 87 # - Run this command in an environment setup for MSVC 88 if not os.path.exists("build"): os.mkdir("build") 89 os.chdir("build") 90 # Do not build tests & static library 91 os.system('cmake -DCMAKE_BUILD_TYPE=RELEASE -DCAPSTONE_BUILD_TESTS=0 -DCAPSTONE_BUILD_STATIC=0 -G "NMake Makefiles" ..') 92 os.system("nmake") 93 else: # Unix incl. cygwin 94 os.system("CAPSTONE_BUILD_CORE_ONLY=yes bash ./make.sh") 95 96 shutil.copy(LIBRARY_FILE, LIBS_DIR) 97 if STATIC_LIBRARY_FILE: shutil.copy(STATIC_LIBRARY_FILE, LIBS_DIR) 98 os.chdir(cwd) 99 100 101class custom_build(build): 102 def run(self): 103 log.info('Copying python sources') 104 copy_pysources() 105 log.info('Building C extensions') 106 build_libraries() 107 return build.run(self) 108 109# clean package directory first 110#import os.path, shutil, sys 111#for f in sys.path: 112# if f.endswith('packages'): 113# pkgdir = os.path.join(f, 'capstone') 114# #print(pkgdir) 115# try: 116# shutil.rmtree(pkgdir) 117# except: 118# pass 119 120setup( 121 provides = ['capstone'], 122 package_dir = {'capstone' : 'pyx'}, 123 packages = ['capstone'], 124 name = 'capstone', 125 version = VERSION, 126 cmdclass = {'build_ext': build_ext, 'build': custom_build}, 127 ext_modules = ext_modules, 128 author = 'Nguyen Anh Quynh', 129 author_email = 'aquynh@gmail.com', 130 description = 'Capstone disassembly engine', 131 url = 'http://www.capstone-engine.org', 132 classifiers = [ 133 'License :: OSI Approved :: BSD License', 134 'Programming Language :: Python :: 2', 135 ], 136 include_package_data=True, 137 package_data={ 138 "capstone": ["lib/*", "include/capstone/*"], 139 } 140) 141