Skip to content

Commit

Permalink
Windows: automatically compile with clang if available
Browse files Browse the repository at this point in the history
  • Loading branch information
aguinet committed May 23, 2020
1 parent d89f281 commit fde9b81
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
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"
if is_win:
import winreg

def set_extension_compile_args(extension):
rel_lib_path = extension.name.replace('.', '/')
Expand All @@ -36,6 +40,44 @@ def run(self):
]
return install_data.run(self)

def win32_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, "SOFTWARE\\LLVM\\LLVM", 0, winreg.KEY_READ)

def win32_find_clang_path():
try:
with win32_get_llvm_reg() as rkey:
return winreg.QueryValueEx(rkey, None)[0]
except FileNotFoundError:
return None

def win32_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 = win32_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

if is_win:
if not win32_use_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=[
Expand Down

0 comments on commit fde9b81

Please sign in to comment.