Home | History | Annotate | Download | only in python
      1 import os
      2 import sys
      3 import shutil
      4 from distutils import log
      5 from distutils.core import setup
      6 from distutils.extension import Extension
      7 from distutils.command.build import build
      8 from Cython.Distutils import build_ext
      9 
     10 
     11 SYSTEM = sys.platform
     12 VERSION = '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
     16 IS_64BITS = sys.maxsize > 2**32
     17 
     18 # are we building from the repository or from a source distribution?
     19 ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
     20 LIBS_DIR = os.path.join(ROOT_DIR, 'pyx', 'lib')
     21 HEADERS_DIR = os.path.join(ROOT_DIR, 'pyx', 'include')
     22 SRC_DIR = os.path.join(ROOT_DIR, 'src')
     23 BUILD_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..')
     24 PYPACKAGE_DIR = os.path.join(ROOT_DIR, 'capstone')
     25 CYPACKAGE_DIR = os.path.join(ROOT_DIR, 'pyx')
     26 
     27 if SYSTEM == 'darwin':
     28     LIBRARY_FILE = "libcapstone.dylib"
     29     STATIC_LIBRARY_FILE = 'libcapstone.a'
     30 elif SYSTEM in ('win32', 'cygwin'):
     31     LIBRARY_FILE = "capstone.dll"
     32     STATIC_LIBRARY_FILE = None
     33 else:
     34     LIBRARY_FILE = "libcapstone.so"
     35     STATIC_LIBRARY_FILE = 'libcapstone.a'
     36 
     37 compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR]
     38 link_args = ['-L' + LIBS_DIR]
     39 
     40 ext_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']
     41 ext_modules = [Extension("capstone.ccapstone",
     42                          ["pyx/ccapstone.pyx"],
     43                          libraries=["capstone"],
     44                          extra_compile_args=compile_args,
     45                          extra_link_args=link_args)]
     46 ext_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 
     52 def clean_bins():
     53     shutil.rmtree(LIBS_DIR, ignore_errors=True)
     54     shutil.rmtree(HEADERS_DIR, ignore_errors=True)
     55 
     56 def 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 
     66 def 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 
    101 class 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 
    120 setup(
    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 (at] 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