forked from angr/pyvex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup.py
127 lines (105 loc) · 3.82 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# pylint: disable=no-name-in-module,import-error,missing-class-docstring
import os
import subprocess
import sys
import shutil
import glob
import multiprocessing
from distutils.command.build import build as st_build
from setuptools import setup
from setuptools.command.develop import develop as st_develop
from setuptools.command.sdist import sdist as st_sdist
from setuptools.errors import LibError
PROJECT_DIR = os.path.dirname(os.path.realpath(__file__))
LIB_DIR = os.path.join(PROJECT_DIR, 'pyvex', 'lib')
INCLUDE_DIR = os.path.join(PROJECT_DIR, 'pyvex', 'include')
if sys.platform in ('win32', 'cygwin'):
LIBRARY_FILE = 'pyvex.dll'
STATIC_LIBRARY_FILE = 'pyvex.lib'
elif sys.platform == 'darwin':
LIBRARY_FILE = "libpyvex.dylib"
STATIC_LIBRARY_FILE = 'libpyvex.a'
else:
LIBRARY_FILE = "libpyvex.so"
STATIC_LIBRARY_FILE = 'libpyvex.a'
VEX_LIB_NAME = "vex" # can also be vex-amd64-linux
VEX_PATH = os.path.abspath(os.path.join(PROJECT_DIR, 'vex'))
def _build_vex():
if len(os.listdir(VEX_PATH)) == 0:
raise LibError("vex submodule not cloned correctly, aborting.\n"
"This may be fixed with `git submodule update --init`")
e = os.environ.copy()
e['MULTIARCH'] = '1'
e['DEBUG'] = '1'
cmd1 = ['nmake', '/f', 'Makefile-msvc', 'all']
cmd2 = ['make', '-f', 'Makefile-gcc', '-j', str(multiprocessing.cpu_count()), 'all']
cmd3 = ['gmake', '-f', 'Makefile-gcc', '-j', str(multiprocessing.cpu_count()), 'all']
for cmd in (cmd1, cmd2, cmd3):
try:
if subprocess.call(cmd, cwd=VEX_PATH, env=e) == 0:
break
except OSError:
continue
else:
raise LibError("Unable to build libVEX.")
def _build_pyvex():
e = os.environ.copy()
e['VEX_LIB_PATH'] = VEX_PATH
e['VEX_INCLUDE_PATH'] = os.path.join(VEX_PATH, 'pub')
e['VEX_LIB_FILE'] = os.path.join(VEX_PATH, 'libvex.lib')
cmd1 = ['nmake', '/f', 'Makefile-msvc']
cmd2 = ['make', '-j', str(multiprocessing.cpu_count())]
cmd3 = ['gmake', '-j', str(multiprocessing.cpu_count())]
for cmd in (cmd1, cmd2, cmd3):
try:
if subprocess.call(cmd, cwd='pyvex_c', env=e) == 0:
break
except OSError as err:
continue
else:
raise LibError("Unable to build libpyvex.")
def _shuffle_files():
shutil.rmtree(LIB_DIR, ignore_errors=True)
shutil.rmtree(INCLUDE_DIR, ignore_errors=True)
os.mkdir(LIB_DIR)
os.mkdir(INCLUDE_DIR)
pyvex_c_dir = os.path.join(PROJECT_DIR, 'pyvex_c')
shutil.copy(os.path.join(pyvex_c_dir, LIBRARY_FILE), LIB_DIR)
shutil.copy(os.path.join(pyvex_c_dir, STATIC_LIBRARY_FILE), LIB_DIR)
shutil.copy(os.path.join(pyvex_c_dir, 'pyvex.h'), INCLUDE_DIR)
for f in glob.glob(os.path.join(VEX_PATH, 'pub', '*')):
shutil.copy(f, INCLUDE_DIR)
def _clean_bins():
shutil.rmtree(LIB_DIR, ignore_errors=True)
shutil.rmtree(INCLUDE_DIR, ignore_errors=True)
def _build_ffi():
sys.path.append(".") # PEP 517 doesn't include . in sys.path
import make_ffi
sys.path.pop()
try:
make_ffi.doit(os.path.join(VEX_PATH, 'pub'))
except Exception as e:
raise
class build(st_build):
def run(self, *args):
self.execute(_build_vex, (), msg="Building libVEX")
self.execute(_build_pyvex, (), msg="Building libpyvex")
self.execute(_shuffle_files, (), msg="Copying libraries and headers")
self.execute(_build_ffi, (), msg="Creating CFFI defs file")
super().run(*args)
class develop(st_develop):
def run(self):
self.run_command("build")
super().run()
class sdist(st_sdist):
def run(self, *args):
self.execute(_clean_bins, (), msg="Removing binaries")
super().run(*args)
cmdclass = {
'build': build,
'develop': develop,
'sdist': sdist,
}
setup(
cmdclass=cmdclass,
)