Index: include/lldb/Host/posix/HostInfoPosix.h =================================================================== --- include/lldb/Host/posix/HostInfoPosix.h +++ include/lldb/Host/posix/HostInfoPosix.h @@ -37,6 +37,9 @@ static bool ComputeSupportExeDirectory(FileSpec &file_spec); static bool ComputeHeaderDirectory(FileSpec &file_spec); static bool ComputePythonDirectory(FileSpec &file_spec); + static bool ComputeClangDirectory(FileSpec &file_spec); + static bool ComputePathRelativeToLibrary(FileSpec &file_spec, + llvm::StringRef dir); }; } Index: source/Host/macosx/HostInfoMacOSX.mm =================================================================== --- source/Host/macosx/HostInfoMacOSX.mm +++ source/Host/macosx/HostInfoMacOSX.mm @@ -233,11 +233,13 @@ 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/Clang"); - } + if (framework_pos == std::string::npos) + return HostInfoPosix::ComputeClangDirectory(file_spec); + + framework_pos += strlen("LLDB.framework"); + raw_path.resize(framework_pos); + raw_path.append("/Resources/Clang"); + file_spec.SetFile(raw_path.c_str(), true); return true; } Index: source/Host/posix/HostInfoPosix.cpp =================================================================== --- source/Host/posix/HostInfoPosix.cpp +++ source/Host/posix/HostInfoPosix.cpp @@ -14,7 +14,10 @@ #include "lldb/Core/Log.h" #include "lldb/Host/posix/HostInfoPosix.h" +#include "clang/Basic/Version.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include @@ -124,44 +127,55 @@ FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh", false); } -bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) { +bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec, + llvm::StringRef dir) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); FileSpec lldb_file_spec; if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) return false; - char raw_path[PATH_MAX]; - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + std::string raw_path = lldb_file_spec.GetPath(); + // drop filename and library directory + llvm::StringRef parent_path = + llvm::sys::path::parent_path(llvm::sys::path::parent_path(raw_path)); // Most Posix systems (e.g. Linux/*BSD) will attempt to replace a */lib with - // */bin as the base - // directory for helper exe programs. This will fail if the /lib and /bin - // directories are - // rooted in entirely different trees. + // */bin as the base directory for helper exe programs. This will fail if the + // /lib and /bin directories are rooted in entirely different trees. if (log) log->Printf("HostInfoPosix::ComputeSupportExeDirectory() attempting to " "derive the bin path (ePathTypeSupportExecutableDir) from " "this path: %s", - raw_path); - char *lib_pos = ::strstr(raw_path, "/lib"); - if (lib_pos != nullptr) { + raw_path.c_str()); + + if (!parent_path.empty()) { // Now write in bin in place of lib. - ::snprintf(lib_pos, PATH_MAX - (lib_pos - raw_path), "/bin"); + raw_path = (parent_path + dir).str(); if (log) log->Printf("Host::%s() derived the bin path as: %s", __FUNCTION__, - raw_path); + raw_path.c_str()); } else { if (log) log->Printf("Host::%s() failed to find /lib/liblldb within the shared " "lib path, bailing on bin path construction", __FUNCTION__); } - file_spec.GetDirectory().SetCString(raw_path); + file_spec.GetDirectory().SetString(raw_path); return (bool)file_spec.GetDirectory(); } +bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) { + return ComputePathRelativeToLibrary(file_spec, "/bin"); +} + +bool HostInfoPosix::ComputeClangDirectory(FileSpec &file_spec) { + return ComputePathRelativeToLibrary( + file_spec, + llvm::Twine("/lib/clang/", llvm::StringRef(CLANG_VERSION_STRING)).str()); +} + bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) { FileSpec temp_file("/opt/local/include/lldb", false); file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());