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.

<rdar://problem/23167253>

llvm-svn: 250772
This commit is contained in:
Greg Clayton 2015-10-20 00:22:50 +00:00
parent 88f476b9eb
commit 7449ab9834
1 changed files with 55 additions and 48 deletions

View File

@ -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)
{
output.erase(first_non_newline+1);
}
g_xcode_filespec = CheckPathForXcode(FileSpec(developer_dir_env_var, true));
}
size_t pos = output.rfind(substr);
if (pos != std::string::npos)
// 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(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;