LLDB mainline
PythonPathSetup.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
12#include "llvm/Support/Windows/WindowsSupport.h"
13
14#include "llvm/ADT/SmallVector.h"
15#include "llvm/Support/ConvertUTF.h"
16#include "llvm/Support/FileSystem.h"
17#include "llvm/Support/Path.h"
18#include <pathcch.h>
19
20using namespace llvm;
21
22static std::string GetModulePath(HMODULE module) {
23 std::vector<WCHAR> buffer(MAX_PATH);
24 while (buffer.size() <= PATHCCH_MAX_CCH) {
25 DWORD len = GetModuleFileNameW(module, buffer.data(), buffer.size());
26 if (len == 0)
27 return "";
28 if (len < buffer.size()) {
29 std::string buffer_utf8;
30 if (convertWideToUTF8(std::wstring(buffer.data(), len), buffer_utf8))
31 return buffer_utf8;
32 return "";
33 }
34 if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
35 buffer.resize(buffer.size() * 2);
36 }
37 return "";
38}
39
40/// Returns the full path to the lldb.exe executable.
41static std::string GetPathToExecutable() { return GetModulePath(NULL); }
42
43#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH
44bool AddPythonDLLToSearchPath() {
45 std::string path_str = GetPathToExecutable();
46 if (path_str.empty())
47 return false;
48
49 SmallVector<char, MAX_PATH> path(path_str.begin(), path_str.end());
50 sys::path::remove_filename(path);
51 sys::path::append(path, LLDB_PYTHON_DLL_RELATIVE_PATH);
52 sys::fs::make_absolute(path);
53
54 SmallVector<wchar_t, 1> path_wide;
55 if (sys::windows::widenPath(path.data(), path_wide))
56 return false;
57
58 if (sys::fs::exists(path))
59 return SetDllDirectoryW(path_wide.data());
60 return false;
61}
62#endif
63
64#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME
65std::optional<std::string> GetPythonDLLPath() {
66#define WIDEN2(x) L##x
67#define WIDEN(x) WIDEN2(x)
68 HMODULE h = LoadLibraryW(WIDEN(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME));
69 if (!h)
70 return std::nullopt;
71
72 std::string path = GetModulePath(h);
73 FreeLibrary(h);
74
75 return path;
76#undef WIDEN2
77#undef WIDEN
78}
79#endif
80
81llvm::Expected<std::string> SetupPythonRuntimeLibrary() {
82#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME
83 if (std::optional<std::string> python_path = GetPythonDLLPath())
84 return *python_path;
85#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH
86 if (AddPythonDLLToSearchPath()) {
87 if (std::optional<std::string> python_path = GetPythonDLLPath())
88 return *python_path;
89 }
90#endif
91 return createStringError(
92 inconvertibleErrorCode(),
93 "unable to find '" LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME "'");
94#elif defined(LLDB_PYTHON_DLL_RELATIVE_PATH)
95 if (!AddPythonDLLToSearchPath())
96 return createStringError(inconvertibleErrorCode(),
97 "unable to find the Python runtime library");
98#endif
99 return "";
100}
static std::string GetPathToExecutable()
Returns the full path to the lldb.exe executable.
llvm::Expected< std::string > SetupPythonRuntimeLibrary()
Attempts to setup the DLL search path for the Python runtime library.
static std::string GetModulePath(HMODULE module)
static llvm::Error createStringError(const char *format, Args &&...args)
Definition Resource.cpp:59