diff options
| author | Adrien Guinet <adrien@guinet.me> | 2020-03-05 14:15:07 +0100 |
|---|---|---|
| committer | Adrien Guinet <adrien@guinet.me> | 2020-05-24 12:07:32 +0200 |
| commit | a9768e386759d71de2c58a61e660308552574997 (patch) | |
| tree | ad8b1dffcc7b07b91319afd7b1b780859dd8325c /setup.py | |
| parent | 5dace179283f488f790c5508cf3e3f148b417f01 (diff) | |
| download | miasm-a9768e386759d71de2c58a61e660308552574997.tar.gz miasm-a9768e386759d71de2c58a61e660308552574997.zip | |
Include missing functions from llvm's compiler-rt into Jitllvm
Under Windows, we also need to compile these with clang (because MSVCRT doesn't seem to have proper uint128_t support), so automatically check if clang is installed (through the registry) and force distutils to use it (with a not so nice hack). Last but not least, this only works for 64 bit systems, so disable the mn_div test if this is not the case.
Diffstat (limited to 'setup.py')
| -rw-r--r-- | setup.py | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/setup.py b/setup.py index c85841e4..a20cf9a1 100644 --- a/setup.py +++ b/setup.py @@ -11,11 +11,16 @@ import fnmatch import io import os import platform -from shutil import copy2 +from shutil import copy2, copyfile, rmtree import sys +import tempfile +import atexit 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('.', '/') @@ -23,7 +28,6 @@ def set_extension_compile_args(extension): 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. @@ -36,6 +40,48 @@ class smart_install_data(install_data): ] 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: + return None + +def win_use_clang(): + # Recent (>= 8 ?) LLVM versions does not ship anymore a cl.exe binary in + # the msbuild-bin directory. Thus, we need to + # * copy-paste bin/clang-cl.exe into a temporary directory + # * rename it to cl.exe + # * add that path first in %Path% + # * clean this mess on exit + # 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 + tmpdir = tempfile.mkdtemp(prefix="llvm") + copyfile(os.path.join(clang_path, "bin", "clang-cl.exe"), os.path.join(tmpdir, "cl.exe")) + os.environ['Path'] = "%s;%s" % (tmpdir, os.environ["Path"]) + atexit.register(lambda dir_: rmtree(dir_), tmpdir) + + return True + +win_force_clang = False +if is_win and is_64bit: + # We do not change to clang if under 32 bits, because even with Clang we + # don't have uint128_t with the 32 bits ABI. + win_force_clang = win_use_clang() + if not win_force_clang: + print("Warning: couldn't find a Clang/LLVM installation. Some runtime functions needed by the jitter won't be compiled.") def buil_all(): packages=[ @@ -154,6 +200,9 @@ def buil_all(): Extension("miasm.jitter.Jitllvm", ["miasm/jitter/Jitllvm.c", "miasm/jitter/bn.c", + "miasm/runtime/udivmodti4.c", + "miasm/runtime/divti3.c", + "miasm/runtime/udivti3.c" ]), Extension("miasm.jitter.Jitgcc", ["miasm/jitter/Jitgcc.c", @@ -165,6 +214,10 @@ def buil_all(): # Force setuptools to use whatever msvc version installed os.environ['MSSdk'] = '1' os.environ['DISTUTILS_USE_SDK'] = '1' + if win_force_clang: + march = "-m64" if is_64bit else "-m32" + for extension in ext_modules_all: + extension.extra_compile_args = [march] elif is_mac: for extension in ext_modules_all: set_extension_compile_args(extension) |