From 7449ab983473b57a5b0980fb1cdbae8f67f43e60 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Tue, 20 Oct 2015 00:22:50 +0000 Subject: [PATCH] Fixed PlatformDarwin to locate Xcode by using HostInfo::GetProgramFileSpec(). This function returns the FileSpec to the program that is running the LLDB.framework or lldb.so and is more reliable than checking the path of LLDB.framework/lldb.so itself since it might not exist within the Xcode.app bundle (DYLD_FRAMEWORK_PATH). Then we check DEVELOPER_DIR, then check the currently installed Xcode with xcrun. llvm-svn: 250772 --- .../Platform/MacOSX/PlatformDarwin.cpp | 103 ++++++++++-------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 6c405ca71eab..f75ca1b12dc1 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1210,6 +1210,24 @@ static const char *const sdk_strings[] = { "iPhoneOS", }; +static FileSpec +CheckPathForXcode(const FileSpec &fspec) +{ + if (fspec.Exists()) + { + const char substr[] = ".app/Contents/"; + + std::string path_to_shlib = fspec.GetPath(); + size_t pos = path_to_shlib.rfind(substr); + if (pos != std::string::npos) + { + path_to_shlib.erase(pos + strlen(substr)); + return FileSpec(path_to_shlib.c_str(), false); + } + } + return FileSpec(); +} + static FileSpec GetXcodeContentsPath () { @@ -1217,48 +1235,50 @@ GetXcodeContentsPath () static std::once_flag g_once_flag; std::call_once(g_once_flag, []() { - const char substr[] = ".app/Contents/"; - - // First, try based on the current shlib's location + FileSpec fspec; - - if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBShlibDir, fspec)) + + // First get the program file spec. If lldb.so or LLDB.framework is running + // in a program and that program is Xcode, the path returned with be the path + // to Xcode.app/Contents/MacOS/Xcode, so this will be the correct Xcode to use. + fspec = HostInfo::GetProgramFileSpec(); + + if (fspec) { - std::string path_to_shlib = fspec.GetPath(); - size_t pos = path_to_shlib.rfind(substr); - if (pos != std::string::npos) - { - path_to_shlib.erase(pos + strlen(substr)); - g_xcode_filespec = FileSpec(path_to_shlib.c_str(), false); - } + g_xcode_filespec = CheckPathForXcode(fspec); } - // Fall back to using xcrun + // Next check DEVELOPER_DIR environment variable if (!g_xcode_filespec) { - int status = 0; - int signo = 0; - std::string output; - const char *command = "xcrun -sdk macosx --show-sdk-path"; - lldb_private::Error error = Host::RunShellCommand (command, // shell command to run - NULL, // current working directory - &status, // Put the exit status of the process in here - &signo, // Put the signal that caused the process to exit in here - &output, // Get the output from the command and place it in this string - 3); // Timeout in seconds to wait for shell program to finish - if (status == 0 && !output.empty()) + const char *developer_dir_env_var = getenv("DEVELOPER_DIR"); + if (developer_dir_env_var && developer_dir_env_var[0]) { - size_t first_non_newline = output.find_last_not_of("\r\n"); - if (first_non_newline != std::string::npos) + g_xcode_filespec = CheckPathForXcode(FileSpec(developer_dir_env_var, true)); + } + + // Fall back to using "xcrun" to find the selected Xcode + if (!g_xcode_filespec) + { + int status = 0; + int signo = 0; + std::string output; + const char *command = "xcrun -sdk macosx --show-sdk-path"; + lldb_private::Error error = Host::RunShellCommand (command, // shell command to run + NULL, // current working directory + &status, // Put the exit status of the process in here + &signo, // Put the signal that caused the process to exit in here + &output, // Get the output from the command and place it in this string + 3); // Timeout in seconds to wait for shell program to finish + if (status == 0 && !output.empty()) { - output.erase(first_non_newline+1); - } - - size_t pos = output.rfind(substr); - if (pos != std::string::npos) - { - output.erase(pos + strlen(substr)); - g_xcode_filespec = FileSpec(output.c_str(), false); + size_t first_non_newline = output.find_last_not_of("\r\n"); + if (first_non_newline != std::string::npos) + { + output.erase(first_non_newline+1); + } + + g_xcode_filespec = CheckPathForXcode(FileSpec(output.c_str(), false)); } } } @@ -1561,20 +1581,7 @@ PlatformDarwin::LocateExecutable (const char *basename) std::call_once(g_once_flag, []() { // When locating executables, trust the DEVELOPER_DIR first if it is set - FileSpec xcode_contents_dir; - const char *developer_dir_env_var = getenv("DEVELOPER_DIR"); - if (developer_dir_env_var && developer_dir_env_var[0]) - { - xcode_contents_dir = FileSpec(developer_dir_env_var, true); - if (xcode_contents_dir.Exists()) - xcode_contents_dir.RemoveLastPathComponent(); - } - if (!xcode_contents_dir) - { - xcode_contents_dir = GetXcodeContentsPath(); - if (!xcode_contents_dir.Exists()) - xcode_contents_dir.Clear(); - } + FileSpec xcode_contents_dir = GetXcodeContentsPath(); if (xcode_contents_dir) { FileSpec xcode_lldb_resources = xcode_contents_dir;