aadsm created this revision. aadsm added reviewers: clayborg, JDevlieghere. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
This might be an edge case in regular use but if you're shipping an lldb version with no debugserver lldb will try to use the System one. However, lldb only knows how to find the Xcode one and not the Command Line Tools one. This diff fixes that. We try to find debugserver with `PlatformDarwin::LocateExecutable("debugserver")`, we call `xcode-select -p` to get the path and then assume this path is of Xcode. The changes I did are: - Change `PlatformDarwin::LocateExecutable` to also add the Command Line Tools directory to the list of paths to search for debugserver. - Created a new function to find the Command Line Tools directory named `GetCommandLineToolsLibraryPath`. - Refactored the code that calls `xcode-select -p` into its own function `GetXcodeSelectPath()`. There were 2 identical pieces of code for this so I reduced it to one and used this function everywhere instead. - I also changed `PlatformDarwin::GetSDKDirectoryForModules` to use the `SDKs` directory that exists in the Command Line Tools installation. I'm not sure how to create tests for this. PlatformDarwinTest is really limited and I couldn't find how to mock Filesystem::Instance() so I could create a virtual file system. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D65171 Files: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1107,6 +1107,34 @@ return false; } +static FileSpec GetXcodeSelectPath() { + static FileSpec g_xcode_select_filespec; + + if (!g_xcode_select_filespec) { + FileSpec xcode_select_cmd("/usr/bin/xcode-select"); + if (FileSystem::Instance().Exists(xcode_select_cmd)) { + int exit_status = -1; + int signo = -1; + std::string command_output; + Status status = + Host::RunShellCommand("/usr/bin/xcode-select --print-path", + nullptr, // current working directory + &exit_status, &signo, &command_output, + std::chrono::seconds(2), // short timeout + false); // don't run in a shell + if (status.Success() && exit_status == 0 && !command_output.empty()) { + size_t first_non_newline = command_output.find_last_not_of("\r\n"); + if (first_non_newline != std::string::npos) { + command_output.erase(first_non_newline + 1); + } + g_xcode_select_filespec = FileSpec(command_output); + } + } + } + + return g_xcode_select_filespec; +} + // Return a directory path like /Applications/Xcode.app/Contents/Developer const char *PlatformDarwin::GetDeveloperDirectory() { std::lock_guard<std::mutex> guard(m_mutex); @@ -1164,34 +1192,10 @@ } if (!developer_dir_path_valid) { - FileSpec xcode_select_cmd("/usr/bin/xcode-select"); - if (FileSystem::Instance().Exists(xcode_select_cmd)) { - int exit_status = -1; - int signo = -1; - std::string command_output; - Status error = - Host::RunShellCommand("/usr/bin/xcode-select --print-path", - nullptr, // current working directory - &exit_status, &signo, &command_output, - std::chrono::seconds(2), // short timeout - false); // don't run in a shell - if (error.Success() && exit_status == 0 && !command_output.empty()) { - const char *cmd_output_ptr = command_output.c_str(); - developer_dir_path[sizeof(developer_dir_path) - 1] = '\0'; - size_t i; - for (i = 0; i < sizeof(developer_dir_path) - 1; i++) { - if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || - cmd_output_ptr[i] == '\0') - break; - developer_dir_path[i] = cmd_output_ptr[i]; - } - developer_dir_path[i] = '\0'; - - FileSpec devel_dir(developer_dir_path); - if (FileSystem::Instance().IsDirectory(devel_dir)) { - developer_dir_path_valid = true; - } - } + FileSpec devel_dir = GetXcodeSelectPath(); + if (FileSystem::Instance().IsDirectory(devel_dir)) { + devel_dir.GetPath(&developer_dir_path[0], sizeof(developer_dir_path)); + developer_dir_path_valid = true; } } @@ -1333,29 +1337,11 @@ g_xcode_filespec = CheckPathForXcode(developer_dir_spec); } - // Fall back to using "xcrun" to find the selected Xcode + // Fall back to using "xcode-select" to find the selected Xcode if (!g_xcode_filespec) { - int status = 0; - int signo = 0; - std::string output; - const char *command = "/usr/bin/xcode-select -p"; - lldb_private::Status error = Host::RunShellCommand( - command, // shell command to run - nullptr, // 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 - std::chrono::seconds(3)); - if (status == 0 && !output.empty()) { - 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); - } - output.append("/.."); - - g_xcode_filespec = CheckPathForXcode(FileSpec(output)); - } + FileSpec xcode_select_path(GetXcodeSelectPath()); + xcode_select_path.RemoveLastPathComponent(); + g_xcode_filespec = CheckPathForXcode(xcode_select_path); } } }); @@ -1363,6 +1349,20 @@ return g_xcode_filespec; } +static FileSpec GetCommandLineToolsLibraryPath() { + static FileSpec g_command_line_tools_filespec; + + if (!g_command_line_tools_filespec) { + FileSpec command_line_tools_path(GetXcodeSelectPath()); + command_line_tools_path.AppendPathComponent("Library"); + if (FileSystem::Instance().Exists(command_line_tools_path)) { + g_command_line_tools_filespec = command_line_tools_path; + } + } + + return g_command_line_tools_filespec; +} + bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type, llvm::VersionTuple version) { switch (sdk_type) { @@ -1469,6 +1469,13 @@ if (!version.empty()) { if (SDKSupportsModules(SDKType::MacOSX, version)) { + // If the Xcode SDKs are not available then try to use the + // Command Line Tools one which is only for MacOSX. + if (!FileSystem::Instance().Exists(sdks_spec)) { + sdks_spec = GetCommandLineToolsLibraryPath(); + sdks_spec.AppendPathComponent("SDKs"); + } + // We slightly prefer the exact SDK for this machine. See if it is // there. @@ -1646,6 +1653,20 @@ g_executable_dirs.push_back(dir); } } + // Xcode might not be installed so we also check for the Command Line Tools. + FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath(); + if (command_line_tools_dir) { + FileSpec cmd_line_lldb_resources = command_line_tools_dir; + cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks"); + cmd_line_lldb_resources.AppendPathComponent("LLDB.framework"); + cmd_line_lldb_resources.AppendPathComponent("Resources"); + if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) { + FileSpec dir; + dir.GetDirectory().SetCString( + cmd_line_lldb_resources.GetPath().c_str()); + g_executable_dirs.push_back(dir); + } + } }); // Now search the global list of executable directories for the executable we
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits