• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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