Author: Charles Zablit Date: 2025-10-09T16:50:49+01:00 New Revision: ec28b95b7491bc2fbb6ec66cdbfd939e71255c42
URL: https://github.com/llvm/llvm-project/commit/ec28b95b7491bc2fbb6ec66cdbfd939e71255c42 DIFF: https://github.com/llvm/llvm-project/commit/ec28b95b7491bc2fbb6ec66cdbfd939e71255c42.diff LOG: [lldb][windows] add support for out of PATH python.dll resolution (#162509) This patch adds the `LLDB_PYTHON_DLL_RELATIVE_PATH` Cmake variable which is the relative path to the directory containing `python.dll`. The path is relative to the directory containing `lldb.exe`. If this variable is set and the resolved path points to an existing directory, we call `SetDllDirectoryW` to add `python.dll` to the list of DLL search paths. This, combined with `liblldb.dll` being delay loaded, allows to package `python.dll` with the `llvm` installer. Added: Modified: lldb/cmake/modules/AddLLDB.cmake lldb/tools/driver/CMakeLists.txt lldb/tools/driver/Driver.cpp Removed: ################################################################################ diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index 28bf8d816d89a..bdd6f73238422 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -167,6 +167,12 @@ function(add_lldb_executable name) ) target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS}) + if(WIN32) + list(FIND ARG_LINK_LIBS liblldb LIBLLDB_INDEX) + if(NOT LIBLLDB_INDEX EQUAL -1) + target_link_options(${name} PRIVATE "/DELAYLOAD:$<TARGET_FILE_BASE_NAME:liblldb>.dll") + endif() + endif() if(CLANG_LINK_CLANG_DYLIB) target_link_libraries(${name} PRIVATE clang-cpp) else() diff --git a/lldb/tools/driver/CMakeLists.txt b/lldb/tools/driver/CMakeLists.txt index 446bf68d09622..67956af7fe3fb 100644 --- a/lldb/tools/driver/CMakeLists.txt +++ b/lldb/tools/driver/CMakeLists.txt @@ -34,6 +34,10 @@ add_dependencies(lldb ${tablegen_deps} ) +if(DEFINED LLDB_PYTHON_DLL_RELATIVE_PATH) + target_compile_definitions(lldb PRIVATE LLDB_PYTHON_DLL_RELATIVE_PATH="${LLDB_PYTHON_DLL_RELATIVE_PATH}") +endif() + if(LLDB_BUILD_FRAMEWORK) # In the build-tree, we know the exact path to the framework directory. # The installed framework can be in diff erent locations. diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 16cc736441b59..325533c85e172 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -22,7 +22,10 @@ #include "lldb/Host/MainLoop.h" #include "lldb/Host/MainLoopBase.h" #include "lldb/Utility/Status.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" @@ -30,6 +33,10 @@ #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" +#ifdef _WIN32 +#include "llvm/Support/Windows/WindowsSupport.h" +#endif + #include <algorithm> #include <atomic> #include <bitset> @@ -426,6 +433,47 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { return error; } +#ifdef _WIN32 +/// 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). + std::vector<WCHAR> buffer; + buffer.resize(MAX_PATH /*=260*/); + while (buffer.size() < 32767) { + if (GetModuleFileNameW(NULL, buffer.data(), buffer.size()) < buffer.size()) + return std::wstring(buffer.begin(), buffer.end()); + buffer.resize(buffer.size() * 2); + } + return L""; +} + +/// 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() { + std::wstring modulePath = GetPathToExecutableW(); + if (modulePath.empty()) { + llvm::errs() << "error: unable to find python.dll." << '\n'; + return; + } + + SmallVector<char, MAX_PATH> utf8Path; + if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(), + utf8Path)) + return; + 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; + + if (sys::fs::exists(utf8Path)) + SetDllDirectoryW(widePath.data()); +} +#endif + std::string EscapeString(std::string arg) { std::string::size_type pos = 0; while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) { @@ -728,6 +776,10 @@ int main(int argc, char const *argv[]) { "~/Library/Logs/DiagnosticReports/.\n"); #endif +#if defined(_WIN32) && defined(LLDB_PYTHON_DLL_RELATIVE_PATH) + AddPythonDLLToSearchPath(); +#endif + // Parse arguments. LLDBOptTable T; unsigned MissingArgIndex; _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
