| 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/*"], |
| } |
| ) |