* NFC but has some fixes for CMake glitches discovered along the way (things not cleaning properly, co-mingled depends). * Includes previously unsubmitted fix in D98681 and a TODO to fix it more appropriately in a smaller followup. Differential Revision: https://reviews.llvm.org/D101493
60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
# See https://llvm.org/LICENSE.txt for license information.
|
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
import os
|
|
import platform
|
|
|
|
_is_windows = platform.system() == "Windows"
|
|
_this_directory = os.path.dirname(__file__)
|
|
|
|
# The standard LLVM build/install tree for Windows is laid out as:
|
|
# bin/
|
|
# MLIRPublicAPI.dll
|
|
# python/
|
|
# _mlir.*.pyd (dll extension)
|
|
# mlir/
|
|
# _dlloader.py (this file)
|
|
# First check the python/ directory level for DLLs co-located with the pyd
|
|
# file, and then fall back to searching the bin/ directory.
|
|
# TODO: This should be configurable at some point.
|
|
_dll_search_path = [
|
|
os.path.join(_this_directory, ".."),
|
|
os.path.join(_this_directory, "..", "..", "bin"),
|
|
]
|
|
|
|
# Stash loaded DLLs to keep them alive.
|
|
_loaded_dlls = []
|
|
|
|
def preload_dependency(public_name):
|
|
"""Preloads a dylib by its soname or DLL name.
|
|
|
|
On Windows and Linux, doing this prior to loading a dependency will populate
|
|
the library in the flat namespace so that a subsequent library that depend
|
|
on it will resolve to this preloaded version.
|
|
|
|
On OSX, resolution is completely path based so this facility no-ops. On
|
|
Linux, as long as RPATHs are setup properly, resolution is path based but
|
|
this facility can still act as an escape hatch for relocatable distributions.
|
|
"""
|
|
if _is_windows:
|
|
_preload_dependency_windows(public_name)
|
|
|
|
|
|
def _preload_dependency_windows(public_name):
|
|
dll_basename = public_name + ".dll"
|
|
found_path = None
|
|
for search_dir in _dll_search_path:
|
|
candidate_path = os.path.join(search_dir, dll_basename)
|
|
if os.path.exists(candidate_path):
|
|
found_path = candidate_path
|
|
break
|
|
|
|
if found_path is None:
|
|
raise RuntimeError(
|
|
f"Unable to find dependency DLL {dll_basename} in search "
|
|
f"path {_dll_search_path}")
|
|
|
|
import ctypes
|
|
_loaded_dlls.append(ctypes.CDLL(found_path))
|