diff options
Diffstat (limited to 'setup.py')
| -rw-r--r-- | setup.py | 436 |
1 files changed, 0 insertions, 436 deletions
diff --git a/setup.py b/setup.py deleted file mode 100644 index 3cc7b5a5..00000000 --- a/setup.py +++ /dev/null @@ -1,436 +0,0 @@ -#! /usr/bin/env python2 - -from __future__ import print_function -# Reference: https://stackoverflow.com/a/13468644/1806760 -from setuptools import setup, Extension -from distutils.util import get_platform -from distutils.sysconfig import get_python_lib, get_config_vars -from distutils.dist import DistributionMetadata -from distutils.command.install_data import install_data -import subprocess -from tempfile import TemporaryFile -import fnmatch -import io -import os -import platform -from shutil import copy2, copyfile, rmtree, which -import sys -import tempfile -import atexit -import re - -is_win = platform.system() == "Windows" -is_mac = platform.system() == "Darwin" -is_64bit = platform.architecture()[0] == "64bit" -if is_win: - import winreg - -def set_extension_compile_args(extension): - rel_lib_path = extension.name.replace(".", "/") - abs_lib_path = os.path.join(get_python_lib(), rel_lib_path) - lib_name = abs_lib_path + ".so" - extension.extra_link_args = [ "-Wl,-install_name," + lib_name] - -class smart_install_data(install_data): - """Replacement for distutils.command.install_data to handle - configuration files location. - """ - def run(self): - # install files to /etc when target was /usr(/local)/etc - self.data_files = [ - (path, files) for path, files in self.data_files - if path # skip README.md or any file with an empty path - ] - return install_data.run(self) - -def win_get_llvm_reg(): - REG_PATH = "SOFTWARE\\LLVM\\LLVM" - try: - return winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, REG_PATH, 0, winreg.KEY_READ | winreg.KEY_WOW64_32KEY) - except FileNotFoundError: - pass - return winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, REG_PATH, 0, winreg.KEY_READ) - -def win_find_clang_path(): - try: - with win_get_llvm_reg() as rkey: - return winreg.QueryValueEx(rkey, None)[0] - except FileNotFoundError: - # Visual Studio ships with an optional Clang distribution, try to detect it - clang_cl = which("clang-cl") - if clang_cl is None: - return None - return os.path.abspath(os.path.join(os.path.dirname(clang_cl), "..", "..")) - -def win_get_clang_version(clang_path): - try: - clang_cl = os.path.join(clang_path, "bin", "clang.exe") - stdout = subprocess.check_output("\"{}\" --version".format(clang_cl)) - version = stdout.splitlines(False)[0].decode() - match = re.search(r"version (\d+\.\d+\.\d+)", version) - if match is None: - return None - version = list(map(lambda s: int(s), match.group(1).split("."))) - return version - except FileNotFoundError: - return None - -def win_use_clang(): - # To force python to use clang we copy the binaries in a temporary directory that's added to the PATH. - # We could use the build directory created by distutils for this, but it seems non-trivial to gather - # (https://stackoverflow.com/questions/12896367/reliable-way-to-get-the-build-directory-from-within-setup-py). - - clang_path = win_find_clang_path() - if clang_path is None: - return False - clang_version = win_get_clang_version(clang_path) - if clang_version is None: - return False - tmpdir = tempfile.mkdtemp(prefix="llvm") - - copyfile(os.path.join(clang_path, "bin", "clang-cl.exe"), os.path.join(tmpdir, "cl.exe")) - - # If you run the installation from a Visual Studio command prompt link.exe will already exist - # Fall back to LLVM's lld-link.exe which is compatible with link's command line - if True:#which("link") is None: - # LLVM >= 14.0.0 started supporting the /LTCG flag - # Earlier versions will error during the linking phase so bail out now - if clang_version[0] < 14: - return False - copyfile(os.path.join(clang_path, "bin", "lld-link.exe"), os.path.join(tmpdir, "link.exe")) - - # Add the temporary directory at the front of the PATH and clean up on exit - os.environ["PATH"] = "%s;%s" % (tmpdir, os.environ["PATH"]) - atexit.register(lambda dir_: rmtree(dir_), tmpdir) - print("Found Clang {}.{}.{}: {}".format(clang_version[0], clang_version[1], clang_version[2], clang_path)) - return True - -build_extensions = True -build_warnings = [] -win_force_clang = False -if is_win: - if is_64bit or which("cl") is None: - # We do not change to clang if under 32 bits, because even with Clang we - # do not use uint128_t with the 32 bits ABI. Regardless we can try to - # find it when building in 32-bit mode if cl.exe was not found in the PATH. - win_force_clang = win_use_clang() - if is_64bit and not win_force_clang: - build_warnings.append("Could not find a suitable Clang/LLVM installation. You can download LLVM from https://releases.llvm.org") - build_warnings.append("Alternatively you can select the 'C++ Clang-cl build tools' in the Visual Studio Installer") - build_extensions = False - cl = which("cl") - link = which("link") - if cl is None or link is None: - build_warnings.append("Could not find cl.exe and/or link.exe in the PATH, try building miasm from a Visual Studio command prompt") - build_warnings.append("More information at: https://wiki.python.org/moin/WindowsCompilers") - build_extensions = False - else: - print("Found cl.exe: {}".format(cl)) - print("Found link.exe: {}".format(link)) - -def build_all(): - packages=[ - "miasm", - "miasm/arch", - "miasm/arch/x86", - "miasm/arch/arm", - "miasm/arch/aarch64", - "miasm/arch/msp430", - "miasm/arch/mep", - "miasm/arch/sh4", - "miasm/arch/mips32", - "miasm/arch/ppc", - "miasm/core", - "miasm/expression", - "miasm/ir", - "miasm/ir/translators", - "miasm/analysis", - "miasm/os_dep", - "miasm/os_dep/linux", - "miasm/loader", - "miasm/jitter", - "miasm/jitter/arch", - "miasm/jitter/loader", - ] - ext_modules_all = [ - Extension( - "miasm.jitter.VmMngr", - [ - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/bn.c", - ] - ), - Extension( - "miasm.jitter.arch.JitCore_x86", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_x86.c" - ] - ), - Extension( - "miasm.jitter.arch.JitCore_arm", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_arm.c" - ] - ), - Extension( - "miasm.jitter.arch.JitCore_aarch64", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_aarch64.c" - ] - ), - Extension( - "miasm.jitter.arch.JitCore_msp430", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_msp430.c" - ] - ), - Extension( - "miasm.jitter.arch.JitCore_mep", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_mep.c" - ] - ), - Extension( - "miasm.jitter.arch.JitCore_mips32", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_mips32.c" - ] - ), - Extension( - "miasm.jitter.arch.JitCore_ppc32", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_ppc32.c" - ], - depends=[ - "miasm/jitter/arch/JitCore_ppc32.h", - "miasm/jitter/arch/JitCore_ppc32_regs.h", - "miasm/jitter/bn.h", - ] - ), - Extension( - "miasm.jitter.arch.JitCore_m68k", - [ - "miasm/jitter/JitCore.c", - "miasm/jitter/vm_mngr.c", - "miasm/jitter/vm_mngr_py.c", - "miasm/jitter/op_semantics.c", - "miasm/jitter/bn.c", - "miasm/jitter/arch/JitCore_m68k.c" - ] - ), - Extension( - "miasm.jitter.Jitllvm", - [ - "miasm/jitter/Jitllvm.c", - "miasm/jitter/bn.c", - "miasm/runtime/udivmodti4.c", - "miasm/runtime/divti3.c", - "miasm/runtime/udivti3.c" - ], - depends=[ - "miasm/runtime/export.h", - "miasm/runtime/int_endianness.h", - "miasm/runtime/int_lib.h", - "miasm/runtime/int_types.h", - "miasm/runtime/int_util.h", - ] - ), - Extension("miasm.jitter.Jitgcc", - ["miasm/jitter/Jitgcc.c", - "miasm/jitter/bn.c", - ]), - ] - - if is_win: - # Force setuptools to use whatever msvc version installed - # https://docs.python.org/3/distutils/apiref.html#module-distutils.msvccompiler - os.environ["MSSdk"] = "1" - os.environ["DISTUTILS_USE_SDK"] = "1" - extra_compile_args = ["-D_CRT_SECURE_NO_WARNINGS"] - if win_force_clang: - march = "-m64" if is_64bit else "-m32" - extra_compile_args += [ - march, - "-Wno-unused-command-line-argument", - "-Wno-visibility", - "-Wno-dll-attribute-on-redeclaration", - "-Wno-tautological-compare", - "-Wno-unused-but-set-variable", - ] - for extension in ext_modules_all: - extension.extra_compile_args = extra_compile_args - elif is_mac: - for extension in ext_modules_all: - set_extension_compile_args(extension) - cfg_vars = get_config_vars() - cfg_vars["LDSHARED"] = cfg_vars["LDSHARED"].replace("-bundle", "-dynamiclib") - - # Do not attempt to build the extensions when disabled - if not build_extensions: - ext_modules_all = [] - - print("building") - if not os.path.exists("build"): - os.mkdir("build") - build_ok = False - for name, ext_modules in [("all", ext_modules_all)]: - print("build with", repr(name)) - try: - s = setup( - name = "miasm", - version = "0.1.5", - packages = packages, - data_files=[("", ["README.md"])], - package_data = { - "miasm": [ - "jitter/*.h", - "jitter/arch/*.h", - "runtime/*.h", - "VERSION" - ] - }, - install_requires=["future", "pyparsing>=2.4.1"], - cmdclass={"install_data": smart_install_data}, - ext_modules = ext_modules, - # Metadata - author = "Fabrice Desclaux", - author_email = "serpilliere@droid-corp.org", - description = "Machine code manipulation library", - license = "GPLv2", - long_description=long_description, - long_description_content_type=long_description_content_type, - keywords = [ - "reverse engineering", - "disassembler", - "emulator", - "symbolic execution", - "intermediate representation", - "assembler", - ], - classifiers=[ - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.6", - ], - url = "http://miasm.re", - ) - except SystemExit as e: - print(repr(e)) - continue - build_ok = True - break - if not build_ok: - if len(build_warnings) > 0: - print("ERROR: There was an issue setting up the build environment:") - for warning in build_warnings: - print(" " + warning) - raise ValueError("Unable to build Miasm!") - print("build", name) - # we copy libraries from build dir to current miasm directory - build_base = "build" - if "build" in s.command_options: - if "build_base" in s.command_options["build"]: - build_base = s.command_options["build"]["build_base"] - - print(build_base) - if is_win and build_extensions: - libs = [] - for root, _, files in os.walk(build_base): - for filename in files: - if not filename.endswith(".lib"): - continue - f_path = os.path.join(root, filename) - libs.append(f_path) - - lib_dirname = None - for dirname in os.listdir(build_base): - if not dirname.startswith("lib"): - continue - lib_dirname = dirname - break - - jitters = [] - for lib in libs: - filename = os.path.basename(lib) - dst = os.path.join(build_base, lib_dirname, "miasm", "jitter") - # Windows built libraries may have a name like VmMngr.cp38-win_amd64.lib - if not any([fnmatch.fnmatch(filename, pattern) for pattern in ["VmMngr.*lib", "Jitgcc.*lib", "Jitllvm.*lib"]]): - dst = os.path.join(dst, "arch") - dst = os.path.join(dst, filename) - if not os.path.isfile(dst): - print("Copying", lib, "to", dst) - copy2(lib, dst) - - # Inform the user about the skipped build - if not build_extensions: - print("WARNING: miasm jit extensions were not compiled, details:") - for warning in build_warnings: - print(" " + warning) - -with io.open(os.path.join(os.path.abspath(os.path.dirname("__file__")), - "README.md"), encoding="utf-8") as fdesc: - long_description = fdesc.read() -long_description_content_type = "text/markdown" - - -# Monkey patching (distutils does not handle Description-Content-Type -# from long_description_content_type parameter in setup()). -_write_pkg_file_orig = DistributionMetadata.write_pkg_file - - -def _write_pkg_file(self, file): - with TemporaryFile(mode="w+", encoding="utf-8") as tmpfd: - _write_pkg_file_orig(self, tmpfd) - tmpfd.seek(0) - for line in tmpfd: - if line.startswith("Metadata-Version: "): - file.write("Metadata-Version: 2.1\n") - elif line.startswith("Description: "): - file.write("Description-Content-Type: %s; charset=UTF-8\n" % - long_description_content_type) - file.write(line) - else: - file.write(line) - - -DistributionMetadata.write_pkg_file = _write_pkg_file - - -build_all() - |