Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lldb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ if (LLDB_ENABLE_PYTHON)
set(LLDB_PYTHON_EXT_SUFFIX "_d${LLDB_PYTHON_EXT_SUFFIX}")
endif()
endif()
if(TARGET Python3::Python)
get_target_property(_Python3_LIB_PATH Python3::Python IMPORTED_LIBRARY_LOCATION)
if(_Python3_LIB_PATH)
get_filename_component(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME "${_Python3_LIB_PATH}" NAME)
endif()
endif()
endif ()

if (LLDB_ENABLE_LUA)
Expand Down
3 changes: 3 additions & 0 deletions lldb/tools/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ add_dependencies(lldb
if(DEFINED LLDB_PYTHON_DLL_RELATIVE_PATH)
target_compile_definitions(lldb PRIVATE LLDB_PYTHON_DLL_RELATIVE_PATH="${LLDB_PYTHON_DLL_RELATIVE_PATH}")
endif()
if(DEFINED LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME)
target_compile_definitions(lldb PRIVATE LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME="${LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME}")
endif()

if(LLDB_BUILD_FRAMEWORK)
# In the build-tree, we know the exact path to the framework directory.
Expand Down
68 changes: 56 additions & 12 deletions lldb/tools/driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,8 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
return error;
}

#if defined(_WIN32) && defined(LLDB_PYTHON_DLL_RELATIVE_PATH)
#ifdef _WIN32
#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH
/// Returns the full path to the lldb.exe executable.
inline std::wstring GetPathToExecutableW() {
// Iterate until we reach the Windows API maximum path length (32,767).
Expand All @@ -444,30 +445,73 @@ inline std::wstring GetPathToExecutableW() {
return L"";
}

/// Resolve the full path of the directory defined by
/// \brief Resolve the full path of the directory defined by
/// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL
/// search directories.
void AddPythonDLLToSearchPath() {
/// \return `true` if the library was added to the search path.
/// `false` otherwise.
bool AddPythonDLLToSearchPath() {
std::wstring modulePath = GetPathToExecutableW();
if (modulePath.empty()) {
llvm::errs() << "error: unable to find python.dll." << '\n';
return;
}
if (modulePath.empty())
return false;

SmallVector<char, MAX_PATH> utf8Path;
if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(),
utf8Path))
return;
return false;
sys::path::remove_filename(utf8Path);
sys::path::append(utf8Path, LLDB_PYTHON_DLL_RELATIVE_PATH);
sys::fs::make_absolute(utf8Path);

SmallVector<wchar_t, 1> widePath;
if (sys::windows::widenPath(utf8Path.data(), widePath))
return;
return false;

if (sys::fs::exists(utf8Path))
SetDllDirectoryW(widePath.data());
return SetDllDirectoryW(widePath.data());
return false;
}
#endif

#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME
/// Returns whether `python3x.dll` is in the DLL search path.
bool IsPythonDLLInPath() {
#define WIDEN2(x) L##x
#define WIDEN(x) WIDEN2(x)
WCHAR foundPath[MAX_PATH];
DWORD result =
SearchPathW(nullptr, WIDEN(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME), nullptr,
MAX_PATH, foundPath, nullptr);
#undef WIDEN2
#undef WIDEN

return result > 0;
}
#endif

/// Try to setup the DLL search path for the Python Runtime Library
/// (python3xx.dll).
///
/// If `LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME` is set, we first check if
/// python3xx.dll is in the search path. If it's not, we try to add it and
/// check for it a second time.
/// If only `LLDB_PYTHON_DLL_RELATIVE_PATH` is set, we try to add python3xx.dll
/// to the search path python.dll is already in the search path or not.
void SetupPythonRuntimeLibrary() {
#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME
if (IsPythonDLLInPath())
return;
#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH
if (AddPythonDLLToSearchPath() && IsPythonDLLInPath())
return;
#endif
llvm::errs() << "error: unable to find '"
<< LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME << "'.\n";
return;
#elif defined(LLDB_PYTHON_DLL_RELATIVE_PATH)
if (!AddPythonDLLToSearchPath())
llvm::errs() << "error: unable to find the Python runtime library.\n";
#endif
}
#endif

Expand Down Expand Up @@ -801,8 +845,8 @@ int main(int argc, char const *argv[]) {
"~/Library/Logs/DiagnosticReports/.\n");
#endif

#if defined(_WIN32) && defined(LLDB_PYTHON_DLL_RELATIVE_PATH)
AddPythonDLLToSearchPath();
#ifdef _WIN32
SetupPythonRuntimeLibrary();
#endif

// Parse arguments.
Expand Down