Skip to content
Open
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/cmake/modules/AddLLDB.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ function(add_lldb_executable name)
)

target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS})
if(WIN32)
list(FIND ARG_LINK_LIBS liblldb LIBLLD_INDEX)
if(NOT LIBLLD_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()
Expand Down
4 changes: 4 additions & 0 deletions lldb/tools/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ add_dependencies(lldb
${tablegen_deps}
)

if(DEFINED Python3_VERSION)
target_compile_definitions(lldb PRIVATE Python3_VERSION=${Python3_VERSION})
endif()

if(LLDB_BUILD_FRAMEWORK)
# In the build-tree, we know the exact path to the framework directory.
# The installed framework can be in different locations.
Expand Down
61 changes: 61 additions & 0 deletions lldb/tools/driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
#include "lldb/API/SBStructuredData.h"
#include "lldb/Host/Config.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"
Expand Down Expand Up @@ -423,6 +426,60 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
return error;
}

#ifdef _WIN32
inline std::wstring GetPathToExecutableW() {
// Iterate until we max out the Windows max path length (256*2^7 > 32,767).
static const size_t maximumIterations = 7;
std::vector<WCHAR> buffer;
DWORD bufferSize = MAX_PATH;
for (size_t i = 0; i < maximumIterations; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is better written as:

Suggested change
for (size_t i = 0; i < maximumIterations; i++) {
for (size_t i = 0; buffer.size() < 32767; i++) {

buffer.resize(bufferSize);
if (GetModuleFileNameW(NULL, buffer.data(), buffer.size()) < buffer.size())
return std::wstring(buffer.begin(), buffer.end());
bufferSize *= 2;
}
return L"";
}

// Resolve the Embeddable Python directory bundled with the Swift toolchain.
// If it exists, add it to the list of DLL search directories.
// The installation of Embeddable Python is optional when installing the Swift
// toolchain, therefore the directory might not exist.
void AddPythonDLLToSearchPath() {
std::wstring modulePath = GetPathToExecutableW();
if (modulePath.empty()) {
WithColor::error() << "Unable to find python: " << GetLastError() << '\n';
return;
}

SmallVector<char, MAX_PATH> utf8Path;
if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(),
utf8Path))
return;

SmallString<MAX_PATH> pythonDir(utf8Path.begin(), utf8Path.end());
// Python-${Version} is located in the Swift directory and lldb.exe is in:
// `Swift/Toolchains/x.x.x/usr/bin/lldb.exe`.
for (int i = 0; i < 5; i++) {
sys::path::remove_filename(pythonDir);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can make this a CMake configuration option for a relative path, and then upstream this.

#define TO_STRING_IMPL(x) #x
#define TO_STRING(x) TO_STRING_IMPL(x)
std::string pythonDirName = "Python-" TO_STRING(Python3_VERSION);
#undef TO_STRING_IMPL
#undef TO_STRING

sys::path::append(pythonDir, pythonDirName);

SmallVector<wchar_t, 1> widePythonDir;
if (sys::windows::UTF8ToUTF16(pythonDir.str(), widePythonDir))
return;

if (sys::fs::exists(pythonDir))
SetDllDirectoryW(widePythonDir.data());
}
#endif

std::string EscapeString(std::string arg) {
std::string::size_type pos = 0;
while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) {
Expand Down Expand Up @@ -753,6 +810,10 @@ int main(int argc, char const *argv[]) {
"~/Library/Logs/DiagnosticReports/.\n");
#endif

#ifdef _WIN32
AddPythonDLLToSearchPath();
#endif

// Parse arguments.
LLDBOptTable T;
unsigned MissingArgIndex;
Expand Down