mirror of
https://github.com/angr/pyvex
synced 2026-06-21 13:47:01 +00:00
e65dd4de36
* Select a make rather than trying all of them * Fix build and makefile path * Fix lint
140 lines
4.5 KiB
Python
140 lines
4.5 KiB
Python
# pylint: disable=no-name-in-module,import-error,missing-class-docstring
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import shutil
|
|
import glob
|
|
import multiprocessing
|
|
import platform
|
|
from distutils.command.build import build as st_build
|
|
from distutils.util import get_platform
|
|
|
|
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'
|
|
|
|
if sys.platform == 'win32':
|
|
cmd = ['nmake', '/f', 'Makefile-msvc', 'all']
|
|
elif shutil.which('gmake') is not None:
|
|
cmd = ['gmake', '-f', 'Makefile-gcc', '-j', str(multiprocessing.cpu_count()), 'all']
|
|
else:
|
|
cmd = ['make', '-f', 'Makefile-gcc', '-j', str(multiprocessing.cpu_count()), 'all']
|
|
|
|
try:
|
|
subprocess.run(cmd, cwd=VEX_PATH, env=e, check=True)
|
|
except FileNotFoundError as err:
|
|
raise LibError("Couldn't find " + cmd[0] + " in PATH") from err
|
|
except subprocess.CalledProcessError as err:
|
|
raise LibError("Error while building libvex: " + str(err)) from err
|
|
|
|
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')
|
|
|
|
if sys.platform == 'win32':
|
|
cmd = ['nmake', '/f', 'Makefile-msvc']
|
|
elif shutil.which('gmake') is not None:
|
|
cmd = ['gmake', '-f', 'Makefile', '-j', str(multiprocessing.cpu_count())]
|
|
else:
|
|
cmd = ['make', '-f', 'Makefile', '-j', str(multiprocessing.cpu_count())]
|
|
|
|
try:
|
|
subprocess.run(cmd, cwd="pyvex_c", env=e, check=True)
|
|
except FileNotFoundError as err:
|
|
raise LibError("Couldn't find " + cmd[0] + " in PATH") from err
|
|
except subprocess.CalledProcessError as err:
|
|
raise LibError("Error while building libpyvex: " + str(err)) from err
|
|
|
|
|
|
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 # pylint: disable=import-outside-toplevel
|
|
sys.path.pop()
|
|
|
|
make_ffi.doit(os.path.join(VEX_PATH, 'pub'))
|
|
|
|
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,
|
|
}
|
|
|
|
if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
|
|
sys.argv.append('--plat-name')
|
|
name = get_platform()
|
|
if 'linux' in name:
|
|
sys.argv.append('manylinux2014_' + platform.machine())
|
|
else:
|
|
# https://www.python.org/dev/peps/pep-0425/
|
|
sys.argv.append(name.replace('.', '_').replace('-', '_'))
|
|
|
|
setup(cmdclass=cmdclass)
|