diff options
Diffstat (limited to 'capstone/bindings/python/setup_cython.py')
-rw-r--r-- | capstone/bindings/python/setup_cython.py | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/capstone/bindings/python/setup_cython.py b/capstone/bindings/python/setup_cython.py new file mode 100644 index 000000000..d36769a02 --- /dev/null +++ b/capstone/bindings/python/setup_cython.py @@ -0,0 +1,144 @@ +import os +import sys +import shutil + +from distutils import log +from distutils.core import setup +from distutils.extension import Extension +from distutils.command.build import build +from Cython.Distutils import build_ext + +SYSTEM = sys.platform +VERSION = '4.0.0' + +# adapted from commit e504b81 of Nguyen Tan Cong +# Reference: https://docs.python.org/2/library/platform.html#cross-platform +IS_64BITS = sys.maxsize > 2**32 + +# are we building from the repository or from a source distribution? +ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) +LIBS_DIR = os.path.join(ROOT_DIR, 'pyx', 'lib') +HEADERS_DIR = os.path.join(ROOT_DIR, 'pyx', 'include') +SRC_DIR = os.path.join(ROOT_DIR, 'src') +BUILD_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..') +PYPACKAGE_DIR = os.path.join(ROOT_DIR, 'capstone') +CYPACKAGE_DIR = os.path.join(ROOT_DIR, 'pyx') + +if SYSTEM == 'darwin': + VERSIONED_LIBRARY_FILE = "libcapstone.4.dylib" + LIBRARY_FILE = "libcapstone.dylib" + STATIC_LIBRARY_FILE = 'libcapstone.a' +elif SYSTEM in ('win32', 'cygwin'): + VERSIONED_LIBRARY_FILE = "capstone.dll" + LIBRARY_FILE = "capstone.dll" + STATIC_LIBRARY_FILE = None +else: + VERSIONED_LIBRARY_FILE = "libcapstone.so.4" + LIBRARY_FILE = "libcapstone.so" + STATIC_LIBRARY_FILE = 'libcapstone.a' + +compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR] +link_args = ['-L' + LIBS_DIR] + +ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const' ] + +ext_modules = [Extension("capstone.ccapstone", + ["pyx/ccapstone.pyx"], + libraries=["capstone"], + extra_compile_args=compile_args, + extra_link_args=link_args)] +ext_modules += [Extension("capstone.%s" % name, + ["pyx/%s.pyx" % name], + extra_compile_args=compile_args, + extra_link_args=link_args) + for name in ext_module_names] + +def clean_bins(): + shutil.rmtree(LIBS_DIR, ignore_errors=True) + shutil.rmtree(HEADERS_DIR, ignore_errors=True) + +def copy_pysources(): + for fname in os.listdir(PYPACKAGE_DIR): + if not fname.endswith('.py'): + continue + + if fname == '__init__.py': + shutil.copy(os.path.join(PYPACKAGE_DIR, fname), os.path.join(CYPACKAGE_DIR, fname)) + else: + shutil.copy(os.path.join(PYPACKAGE_DIR, fname), os.path.join(CYPACKAGE_DIR, fname + 'x')) + +def build_libraries(): + """ + Prepare the capstone directory for a binary distribution or installation. + Builds shared libraries and copies header files. + + Will use a src/ dir if one exists in the current directory, otherwise assumes it's in the repo + """ + cwd = os.getcwd() + clean_bins() + os.mkdir(HEADERS_DIR) + os.mkdir(LIBS_DIR) + + # copy public headers + shutil.copytree(os.path.join(BUILD_DIR, 'include', 'capstone'), os.path.join(HEADERS_DIR, 'capstone')) + + os.chdir(BUILD_DIR) + + # platform description refers at https://docs.python.org/2/library/sys.html#sys.platform + if SYSTEM == "win32": + # Windows build: this process requires few things: + # - CMake + MSVC installed + # - Run this command in an environment setup for MSVC + if not os.path.exists("build"): os.mkdir("build") + os.chdir("build") + # Do not build tests & static library + os.system('cmake -DCMAKE_BUILD_TYPE=RELEASE -DCAPSTONE_BUILD_TESTS=0 -DCAPSTONE_BUILD_STATIC=0 -G "NMake Makefiles" ..') + os.system("nmake") + else: # Unix incl. cygwin + os.system("CAPSTONE_BUILD_CORE_ONLY=yes bash ./make.sh") + + shutil.copy(VERSIONED_LIBRARY_FILE, os.path.join(LIBS_DIR, LIBRARY_FILE)) + if STATIC_LIBRARY_FILE: shutil.copy(STATIC_LIBRARY_FILE, LIBS_DIR) + os.chdir(cwd) + + +class custom_build(build): + def run(self): + log.info('Copying python sources') + copy_pysources() + log.info('Building C extensions') + build_libraries() + return build.run(self) + +# clean package directory first +#import os.path, shutil, sys +#for f in sys.path: +# if f.endswith('packages'): +# pkgdir = os.path.join(f, 'capstone') +# #print(pkgdir) +# try: +# shutil.rmtree(pkgdir) +# except: +# pass + +setup( + provides = ['capstone'], + package_dir = {'capstone' : 'pyx'}, + packages = ['capstone'], + name = 'capstone', + version = VERSION, + cmdclass = {'build_ext': build_ext, 'build': custom_build}, + ext_modules = ext_modules, + author = 'Nguyen Anh Quynh', + author_email = 'aquynh@gmail.com', + description = 'Capstone disassembly engine', + url = 'http://www.capstone-engine.org', + classifiers = [ + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python :: 2', + ], + include_package_data=True, + package_data={ + "capstone": ["lib/*", "include/capstone/*"], + } +) |