Index: include/lldb/Host/macosx/HostInfoMacOSX.h =================================================================== --- include/lldb/Host/macosx/HostInfoMacOSX.h +++ include/lldb/Host/macosx/HostInfoMacOSX.h @@ -37,7 +37,6 @@ static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); static bool ComputeHeaderDirectory(FileSpec &file_spec); - static bool ComputePythonDirectory(FileSpec &file_spec); static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); static bool ComputeUserPluginsDirectory(FileSpec &file_spec); }; Index: include/lldb/Host/posix/HostInfoPosix.h =================================================================== --- include/lldb/Host/posix/HostInfoPosix.h +++ include/lldb/Host/posix/HostInfoPosix.h @@ -39,7 +39,6 @@ protected: static bool ComputeSupportExeDirectory(FileSpec &file_spec); static bool ComputeHeaderDirectory(FileSpec &file_spec); - static bool ComputePythonDirectory(FileSpec &file_spec); }; } Index: include/lldb/Host/windows/HostInfoWindows.h =================================================================== --- include/lldb/Host/windows/HostInfoWindows.h +++ include/lldb/Host/windows/HostInfoWindows.h @@ -39,9 +39,6 @@ static bool GetEnvironmentVar(const std::string &var_name, std::string &var); -protected: - static bool ComputePythonDirectory(FileSpec &file_spec); - private: static FileSpec m_program_filespec; }; Index: source/API/SBHostOS.cpp =================================================================== --- source/API/SBHostOS.cpp +++ source/API/SBHostOS.cpp @@ -18,6 +18,7 @@ #include "lldb/Utility/Log.h" #include "Plugins/ExpressionParser/Clang/ClangHost.h" +#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Path.h" @@ -48,7 +49,7 @@ fspec = HostInfo::GetHeaderDir(); break; case ePathTypePythonDir: - fspec = HostInfo::GetPythonDir(); + fspec = ScriptInterpreterPython::GetPythonDir(); break; case ePathTypeLLDBSystemPlugins: fspec = HostInfo::GetSystemPluginDir(); Index: source/Host/CMakeLists.txt =================================================================== --- source/Host/CMakeLists.txt +++ source/Host/CMakeLists.txt @@ -51,11 +51,6 @@ common/UDPSocket.cpp ) -# Keep track of whether we want to provide a define for the -# Python's architecture-specific lib path (i.e. where a -# Python lldb module would go). -set (get_python_libdir 0) - if (NOT LLDB_DISABLE_LIBEDIT) add_host_subdirectory(common common/Editline.cpp @@ -66,10 +61,6 @@ posix/ConnectionFileDescriptorPosix.cpp ) -if(NOT LLDB_DISABLE_PYTHON) - list(APPEND LLDB_PLUGINS lldbPluginScriptInterpreterPython) -endif() - if (CMAKE_SYSTEM_NAME MATCHES "Windows") add_host_subdirectory(windows windows/ConnectionGenericFileWindows.cpp @@ -86,11 +77,6 @@ windows/Windows.cpp ) else() - if (NOT LLDB_DISABLE_PYTHON) - # We'll grab the arch-specific python libdir on POSIX systems. - set (get_python_libdir 1) - endif() - add_host_subdirectory(posix posix/DomainSocket.cpp posix/FileSystem.cpp @@ -155,19 +141,6 @@ endif() endif() -if (${get_python_libdir}) - # Call a python script to gather the arch-specific libdir for - # modules like the lldb module. - execute_process( - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/get_relative_lib_dir.py - RESULT_VARIABLE get_libdir_status - OUTPUT_VARIABLE relative_libdir - ) - if (get_libdir_status EQUAL 0) - add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}") - endif() -endif() - set(EXTRA_LIBS) if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") list(APPEND EXTRA_LIBS kvm) @@ -194,7 +167,6 @@ lldbSymbol lldbTarget lldbUtility - ${LLDB_PLUGINS} ${EXTRA_LIBS} ${LLDBObjCLibs} Index: source/Host/common/HostInfoBase.cpp =================================================================== --- source/Host/common/HostInfoBase.cpp +++ source/Host/common/HostInfoBase.cpp @@ -58,7 +58,6 @@ FileSpec m_lldb_so_dir; FileSpec m_lldb_support_exe_dir; FileSpec m_lldb_headers_dir; - FileSpec m_lldb_python_dir; FileSpec m_lldb_clang_resource_dir; FileSpec m_lldb_system_plugin_dir; FileSpec m_lldb_user_plugin_dir; @@ -145,17 +144,6 @@ return success ? g_fields->m_lldb_headers_dir : FileSpec(); } -FileSpec HostInfoBase::GetPythonDir() { - static llvm::once_flag g_once_flag; - static bool success = false; - llvm::call_once(g_once_flag, []() { - success = HostInfo::ComputePythonDirectory(g_fields->m_lldb_python_dir); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - LLDB_LOG(log, "python dir -> `{0}`", g_fields->m_lldb_python_dir); - }); - return success ? g_fields->m_lldb_python_dir : FileSpec(); -} - FileSpec HostInfoBase::GetSystemPluginDir() { static llvm::once_flag g_once_flag; static bool success = false; Index: source/Host/macosx/objcxx/HostInfoMacOSX.mm =================================================================== --- source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -#if !defined(LLDB_DISABLE_PYTHON) -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" -#endif - #include "lldb/Host/HostInfo.h" #include "lldb/Host/macosx/HostInfoMacOSX.h" #include "lldb/Utility/Args.h" @@ -188,36 +184,6 @@ return true; } -bool HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec) { -#ifndef LLDB_DISABLE_PYTHON - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) { - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Resources/Python"); - } else { - llvm::SmallString<256> python_version_dir; - llvm::raw_svector_ostream os(python_version_dir); - os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION - << "/site-packages"; - - // We may get our string truncated. Should we protect this with an assert? - raw_path.append(python_version_dir.c_str()); - } - file_spec.GetDirectory().SetString( - llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; -#else - return false; -#endif -} - bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) { FileSpec lldb_file_spec = GetShlibDir(); if (!lldb_file_spec) Index: source/Host/posix/HostInfoPosix.cpp =================================================================== --- source/Host/posix/HostInfoPosix.cpp +++ source/Host/posix/HostInfoPosix.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -#if !defined(LLDB_DISABLE_PYTHON) -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" -#endif - #include "lldb/Host/posix/HostInfoPosix.h" #include "lldb/Utility/Log.h" @@ -172,46 +168,6 @@ return true; } -bool HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec) { -#ifndef LLDB_DISABLE_PYTHON - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - - char raw_path[PATH_MAX]; - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); - -#if defined(LLDB_PYTHON_RELATIVE_LIBDIR) - // Build the path by backing out of the lib dir, then building with whatever - // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL - // x86_64). - char python_path[PATH_MAX]; - ::snprintf(python_path, sizeof(python_path), "%s/../%s", raw_path, - LLDB_PYTHON_RELATIVE_LIBDIR); - - char final_path[PATH_MAX]; - realpath(python_path, final_path); - file_spec.GetDirectory().SetCString(final_path); - - return true; -#else - llvm::SmallString<256> python_version_dir; - llvm::raw_svector_ostream os(python_version_dir); - os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION - << "/site-packages"; - - // We may get our string truncated. Should we protect this with an assert? - ::strncat(raw_path, python_version_dir.c_str(), - sizeof(raw_path) - strlen(raw_path) - 1); - - file_spec.GetDirectory().SetCString(raw_path); - return true; -#endif -#else - return false; -#endif -} - bool HostInfoPosix::GetEnvironmentVar(const std::string &var_name, std::string &var) { if (const char *pvar = ::getenv(var_name.c_str())) { Index: source/Host/windows/HostInfoWindows.cpp =================================================================== --- source/Host/windows/HostInfoWindows.cpp +++ source/Host/windows/HostInfoWindows.cpp @@ -103,18 +103,6 @@ return FileSpec(shell, false); } -bool HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec) { - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - llvm::SmallString<64> path(lldb_file_spec.GetDirectory().AsCString()); - llvm::sys::path::remove_filename(path); - llvm::sys::path::append(path, "lib", "site-packages"); - std::replace(path.begin(), path.end(), '\\', '/'); - file_spec.GetDirectory().SetString(path.c_str()); - return true; -} - bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name, std::string &var) { std::wstring wvar_name; Index: source/Plugins/ScriptInterpreter/Python/CMakeLists.txt =================================================================== --- source/Plugins/ScriptInterpreter/Python/CMakeLists.txt +++ source/Plugins/ScriptInterpreter/Python/CMakeLists.txt @@ -1,3 +1,16 @@ +if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows" AND NOT LLDB_DISABLE_PYTHON) + # Call a python script to gather the arch-specific libdir for + # modules like the lldb module. + execute_process( + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../scripts/get_relative_lib_dir.py + RESULT_VARIABLE get_libdir_status + OUTPUT_VARIABLE relative_libdir + ) + if (get_libdir_status EQUAL 0) + add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}") + endif() +endif() + add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN PythonDataObjects.cpp PythonExceptionState.cpp Index: source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h =================================================================== --- source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -445,6 +445,8 @@ static const char *GetPluginDescriptionStatic(); + static FileSpec GetPythonDir(); + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -509,6 +511,10 @@ static void AddToSysPath(AddLocation location, std::string path); + static void ComputePythonDirForApple(llvm::SmallVectorImpl &path); + static void ComputePythonDirForPosix(llvm::SmallVectorImpl &path); + static void ComputePythonDirForWindows(llvm::SmallVectorImpl &path); + bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); void LeaveSession(); Index: source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp =================================================================== --- source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -347,6 +347,71 @@ return "Embedded Python interpreter"; } +void ScriptInterpreterPython::ComputePythonDirForApple( + llvm::SmallVectorImpl &path) { + auto style = llvm::sys::path::Style::posix; + + llvm::StringRef path_ref(path.begin(), path.size()); + auto rbegin = llvm::sys::path::rbegin(path_ref, style); + auto rend = llvm::sys::path::rend(path_ref); + auto framework = std::find(rbegin, rend, "LLDB.framework"); + if (framework == rend) { + ComputePythonDirForPosix(path); + return; + } + path.resize(framework - rend); + llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python"); +} + +void ScriptInterpreterPython::ComputePythonDirForPosix( + llvm::SmallVectorImpl &path) { + auto style = llvm::sys::path::Style::posix; +#if defined(LLDB_PYTHON_RELATIVE_LIBDIR) + // Build the path by backing out of the lib dir, then building with whatever + // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL + // x86_64). + llvm::sys::path::remove_filename(path, style); + llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR); +#else + llvm::sys::path::append(path, style, + "python" + llvm::Twine(PY_MAJOR_VERSION) + "." + + llvm::Twine(PY_MINOR_VERSION), + "site-packages"); +#endif +} + +void ScriptInterpreterPython::ComputePythonDirForWindows( + llvm::SmallVectorImpl &path) { + auto style = llvm::sys::path::Style::windows; + llvm::sys::path::remove_filename(path, style); + llvm::sys::path::append(path, style, "lib", "site-packages"); + + // This will be injected directly through FileSpec.GetDirectory().SetString(), + // so we need to normalize manually. + std::replace(path.begin(), path.end(), '\\', '/'); +} + +FileSpec ScriptInterpreterPython::GetPythonDir() { + static FileSpec g_spec = []() { + FileSpec spec = HostInfo::GetShlibDir(); + if (!spec) + return FileSpec(); + llvm::SmallString<64> path; + spec.GetPath(path); + +#if defined(__APPLE__) + ComputePythonDirForApple(path); +#elif defined(_WIN32) + ComputePythonDirForWindows(path); +#else + ComputePythonDirForPosix(path); +#endif + spec.GetDirectory().SetString(path); + return spec; + }(); + return g_spec; +} + lldb_private::ConstString ScriptInterpreterPython::GetPluginName() { return GetPluginNameStatic(); } @@ -3098,7 +3163,7 @@ // that use a backslash as the path separator, this will result in executing // python code containing paths with unescaped backslashes. But Python also // accepts forward slashes, so to make life easier we just use that. - if (FileSpec file_spec = HostInfo::GetPythonDir()) + if (FileSpec file_spec = GetPythonDir()) AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false)); if (FileSpec file_spec = HostInfo::GetShlibDir()) AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));