JDevlieghere updated this revision to Diff 250847.
JDevlieghere marked 6 inline comments as done.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76261/new/
https://reviews.llvm.org/D76261
Files:
lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
lldb/unittests/Platform/PlatformDarwinTest.cpp
Index: lldb/unittests/Platform/PlatformDarwinTest.cpp
===================================================================
--- lldb/unittests/Platform/PlatformDarwinTest.cpp
+++ lldb/unittests/Platform/PlatformDarwinTest.cpp
@@ -18,6 +18,8 @@
using namespace lldb_private;
struct PlatformDarwinTester : public PlatformDarwin {
+public:
+ using PlatformDarwin::FindXcodeContentsDirectoryInPath;
static bool SDKSupportsModules(SDKType desired_type,
const lldb_private::FileSpec &sdk_path) {
return PlatformDarwin::SDKSupportsModules(desired_type, sdk_path);
@@ -69,3 +71,64 @@
PlatformDarwin::SDKType::MacOSX,
FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk")));
}
+
+TEST(PlatformDarwinTest, FindXcodeContentsDirectoryInPath) {
+ std::string standard =
+ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/"
+ "Developer/SDKs/MacOSX.sdk";
+ EXPECT_EQ("/Applications/Xcode.app/Contents",
+ PlatformDarwinTester::FindXcodeContentsDirectoryInPath(standard));
+
+ std::string standard_version =
+ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/"
+ "Developer/SDKs/MacOSX10.15.sdk";
+ EXPECT_EQ(
+ "/Applications/Xcode.app/Contents",
+ PlatformDarwinTester::FindXcodeContentsDirectoryInPath(standard_version));
+
+ std::string beta = "/Applications/Xcode-beta.app/Contents/Developer/"
+ "Platforms/MacOSX.platform/"
+ "Developer/SDKs/MacOSX10.15.sdk";
+ EXPECT_EQ("/Applications/Xcode-beta.app/Contents",
+ PlatformDarwinTester::FindXcodeContentsDirectoryInPath(beta));
+
+ std::string no_app =
+ "/Applications/Xcode/Contents/Developer/Platforms/MacOSX.platform/"
+ "Developer/SDKs/MacOSX10.15.sdk";
+ EXPECT_EQ("", PlatformDarwinTester::FindXcodeContentsDirectoryInPath(no_app));
+
+ std::string no_contents =
+ "/Applications/Xcode.app/Developer/Platforms/MacOSX.platform/"
+ "Developer/SDKs/MacOSX10.15.sdk";
+ EXPECT_EQ(
+ "", PlatformDarwinTester::FindXcodeContentsDirectoryInPath(no_contents));
+
+ std::string no_capitalization =
+ "/Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/"
+ "Developer/SDKs/MacOSX10.15.sdk";
+ EXPECT_EQ("", PlatformDarwinTester::FindXcodeContentsDirectoryInPath(
+ no_capitalization));
+}
+
+TEST(PlatformDarwinTest, GetSDKNameForType) {
+ EXPECT_EQ("macosx",
+ PlatformDarwin::GetSDKNameForType(PlatformDarwin::SDKType::MacOSX));
+ EXPECT_EQ("iphonesimulator", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::iPhoneSimulator));
+ EXPECT_EQ("iphoneos", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::iPhoneOS));
+ EXPECT_EQ("appletvsimulator", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::AppleTVSimulator));
+ EXPECT_EQ("appletvos", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::AppleTVOS));
+ EXPECT_EQ("watchsimulator", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::WatchSimulator));
+ EXPECT_EQ("watchos", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::watchOS));
+ EXPECT_EQ("linux",
+ PlatformDarwin::GetSDKNameForType(PlatformDarwin::SDKType::Linux));
+ EXPECT_EQ("unknown", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::numSDKTypes));
+ EXPECT_EQ("unknown", PlatformDarwin::GetSDKNameForType(
+ PlatformDarwin::SDKType::unknown));
+}
Index: lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -185,73 +185,35 @@
ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
ModuleSP exe_module_sp(target.GetExecutableModule());
- if (exe_module_sp) {
- ObjectFile *objfile = exe_module_sp->GetObjectFile();
- if (objfile) {
- std::string xcode_contents_path;
- std::string default_xcode_sdk;
- FileSpec fspec;
- llvm::VersionTuple version = objfile->GetSDKVersion();
- if (!version.empty()) {
- fspec = HostInfo::GetShlibDir();
- if (fspec) {
- std::string path;
- xcode_contents_path = fspec.GetPath();
- size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
- if (pos != std::string::npos) {
- // LLDB.framework is inside an Xcode app bundle, we can locate the
- // SDK from here
- xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
- } else {
- xcode_contents_path.clear();
- // Use the selected Xcode
- int status = 0;
- int signo = 0;
- std::string output;
- const char *command = "xcrun -sdk macosx --show-sdk-path";
- lldb_private::Status error = RunShellCommand(
- command, // shell command to run
- FileSpec(), // 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);
- default_xcode_sdk = output;
-
- pos = default_xcode_sdk.find("/Xcode.app/Contents/");
- if (pos != std::string::npos)
- xcode_contents_path = default_xcode_sdk.substr(
- 0, pos + strlen("/Xcode.app/Contents/"));
- }
- }
- }
-
- if (!xcode_contents_path.empty()) {
- StreamString sdk_path;
- sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/"
- "SDKs/MacOSX%u.%u.sdk",
- xcode_contents_path.c_str(), version.getMajor(),
- version.getMinor().getValue());
- fspec.SetFile(sdk_path.GetString(), FileSpec::Style::native);
- if (FileSystem::Instance().Exists(fspec))
- return ConstString(sdk_path.GetString());
- }
+ if (!exe_module_sp)
+ return {};
+
+ ObjectFile *objfile = exe_module_sp->GetObjectFile();
+ if (!objfile)
+ return {};
+
+ llvm::VersionTuple version = objfile->GetSDKVersion();
+ if (version.empty())
+ return {};
+
+ // First try to find an SDK that matches the given SDK version.
+ if (FileSpec fspec = GetXcodeContentsDirectory()) {
+ StreamString sdk_path;
+ sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/"
+ "SDKs/MacOSX%u.%u.sdk",
+ fspec.GetPath().c_str(), version.getMajor(),
+ version.getMinor().getValue());
+ if (FileSystem::Instance().Exists(fspec))
+ return ConstString(sdk_path.GetString());
+ }
- if (!default_xcode_sdk.empty()) {
- fspec.SetFile(default_xcode_sdk, FileSpec::Style::native);
- if (FileSystem::Instance().Exists(fspec))
- return ConstString(default_xcode_sdk);
- }
- }
- }
+ // Use the default SDK as a fallback.
+ if (FileSpec fspec = GetXcodeSDK(SDKType::MacOSX)) {
+ if (FileSystem::Instance().Exists(fspec))
+ return ConstString(fspec.GetPath());
}
- return ConstString();
+
+ return {};
}
Status PlatformMacOSX::GetSymbolFile(const FileSpec &platform_file,
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -79,15 +79,27 @@
static std::tuple<llvm::VersionTuple, llvm::StringRef>
ParseVersionBuildDir(llvm::StringRef str);
- enum SDKType : unsigned {
+ enum SDKType : int {
MacOSX = 0,
iPhoneSimulator,
iPhoneOS,
+ AppleTVSimulator,
+ AppleTVOS,
+ WatchSimulator,
+ watchOS,
+ bridgeOS,
+ Linux,
+ numSDKTypes,
+ unknown = -1
};
llvm::Expected<lldb_private::StructuredData::DictionarySP>
FetchExtendedCrashInformation(lldb_private::Process &process) override;
+ static llvm::StringRef GetSDKNameForType(SDKType type);
+ static lldb_private::FileSpec GetXcodeSDK(SDKType type);
+ static lldb_private::FileSpec GetXcodeContentsDirectory();
+
protected:
struct CrashInfoAnnotations {
uint64_t version; // unsigned long
@@ -154,13 +166,15 @@
const char *GetDeveloperDirectory();
- lldb_private::Status
- FindBundleBinaryInExecSearchPaths (const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process,
- lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
+ lldb_private::Status FindBundleBinaryInExecSearchPaths(
+ const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
- std::string m_developer_directory;
+ static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path);
+ std::string m_developer_directory;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformDarwin);
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1268,10 +1268,6 @@
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-static const char *const sdk_strings[] = {
- "MacOSX", "iPhoneSimulator", "iPhoneOS",
-};
-
static FileSpec CheckPathForXcode(const FileSpec &fspec) {
if (FileSystem::Instance().Exists(fspec)) {
const char substr[] = ".app/Contents";
@@ -1359,7 +1355,13 @@
return version >= llvm::VersionTuple(10, 10);
case SDKType::iPhoneOS:
case SDKType::iPhoneSimulator:
+ case SDKType::watchOS:
+ case SDKType::WatchSimulator:
+ case SDKType::AppleTVOS:
+ case SDKType::AppleTVSimulator:
return version >= llvm::VersionTuple(8);
+ default:
+ return false;
}
return false;
@@ -1372,10 +1374,12 @@
if (last_path_component) {
const llvm::StringRef sdk_name = last_path_component.GetStringRef();
- if (!sdk_name.startswith(sdk_strings[desired_type]))
+ const std::string sdk_name_lower = sdk_name.lower();
+ llvm::StringRef sdk_string = GetSDKNameForType(desired_type);
+ if (!llvm::StringRef(sdk_name_lower).startswith(sdk_string))
return false;
- auto version_part =
- sdk_name.drop_front(strlen(sdk_strings[desired_type]));
+
+ auto version_part = sdk_name.drop_front(sdk_string.size());
version_part.consume_back(".sdk");
llvm::VersionTuple version;
@@ -1427,13 +1431,6 @@
}
FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
- switch (sdk_type) {
- case SDKType::MacOSX:
- case SDKType::iPhoneSimulator:
- case SDKType::iPhoneOS:
- break;
- }
-
FileSpec sdks_spec = GetXcodeContentsPath();
sdks_spec.AppendPathComponent("Developer");
sdks_spec.AppendPathComponent("Platforms");
@@ -1448,6 +1445,8 @@
case SDKType::iPhoneOS:
sdks_spec.AppendPathComponent("iPhoneOS.platform");
break;
+ default:
+ llvm_unreachable("unsupported sdk");
}
sdks_spec.AppendPathComponent("Developer");
@@ -1656,6 +1655,8 @@
use_current_os_version = false;
#endif
break;
+ default:
+ break;
}
llvm::VersionTuple version;
@@ -1685,6 +1686,9 @@
case SDKType::MacOSX:
minimum_version_option.PutCString("-mmacosx-version-min=");
minimum_version_option.PutCString(version.getAsString());
+ break;
+ default:
+ llvm_unreachable("unsupported sdk");
}
options.push_back(std::string(minimum_version_option.GetString()));
}
@@ -1816,12 +1820,10 @@
return PlatformPOSIX::LaunchProcess(launch_info);
}
-lldb_private::Status
-PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec, Process *process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr, bool *did_create_ptr)
-{
+lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
const FileSpec &platform_file = module_spec.GetFileSpec();
// See if the file is present in any of the module_search_paths_ptr
// directories.
@@ -1892,3 +1894,121 @@
}
return Status();
}
+
+std::string
+PlatformDarwin::FindXcodeContentsDirectoryInPath(llvm::StringRef path) {
+ auto begin = llvm::sys::path::begin(path);
+ auto end = llvm::sys::path::end(path);
+
+ // Iterate over the path components until we find something that ends with
+ // .app. If the next component is Contents then we've found the Contents
+ // directory.
+ for (auto it = begin; it != end; ++it) {
+ if (it->endswith(".app")) {
+ auto next = it;
+ if (++next != end && *next == "Contents") {
+ llvm::SmallString<128> buffer;
+ llvm::sys::path::append(buffer, begin, ++next);
+ return buffer.str().str();
+ }
+ }
+ }
+
+ return {};
+}
+
+llvm::StringRef PlatformDarwin::GetSDKNameForType(SDKType type) {
+ switch (type) {
+ case MacOSX:
+ return "macosx";
+ case iPhoneSimulator:
+ return "iphonesimulator";
+ case iPhoneOS:
+ return "iphoneos";
+ case AppleTVSimulator:
+ return "appletvsimulator";
+ case AppleTVOS:
+ return "appletvos";
+ case WatchSimulator:
+ return "watchsimulator";
+ case watchOS:
+ return "watchos";
+ case bridgeOS:
+ return "bridgeos";
+ case Linux:
+ return "linux";
+ case numSDKTypes:
+ case unknown:
+ return "unknown";
+ }
+ llvm_unreachable("unhandled switch case");
+}
+
+FileSpec PlatformDarwin::GetXcodeSDK(SDKType type) {
+ std::string xcrun_cmd =
+ "xcrun --show-sdk-path -sdk " + GetSDKNameForType(type).str();
+
+ int status = 0;
+ int signo = 0;
+ std::string output_str;
+ lldb_private::Status error =
+ Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo,
+ &output_str, std::chrono::seconds(15));
+
+ // Check that xcrun return something useful.
+ if (status != 0 || output_str.empty())
+ return {};
+
+ // Convert to a StringRef so we can manipulate the string without modifying
+ // the underlying data.
+ llvm::StringRef output(output_str);
+
+ // Remove any trailing newline characters.
+ output = output.rtrim();
+
+ // Strip any leading newline characters and everything before them.
+ const size_t last_newline = output.rfind('\n');
+ if (last_newline != llvm::StringRef::npos)
+ output = output.substr(last_newline + 1);
+
+ // Whatever is left in output should be a valid path.
+ if (!FileSystem::Instance().Exists(output))
+ return {};
+
+ // Find the contents dir in the xcrun provided path.
+ std::string xcode_contents_dir = FindXcodeContentsDirectoryInPath(output);
+ if (xcode_contents_dir.empty())
+ return {};
+
+ return FileSpec(xcode_contents_dir);
+}
+
+FileSpec PlatformDarwin::GetXcodeContentsDirectory() {
+ static FileSpec g_xcode_contents_path;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, [&]() {
+ // Try the shlib dir first.
+ if (FileSpec fspec = HostInfo::GetShlibDir()) {
+ if (FileSystem::Instance().Exists(fspec)) {
+ std::string xcode_contents_dir =
+ FindXcodeContentsDirectoryInPath(fspec.GetPath());
+ if (!xcode_contents_dir.empty()) {
+ g_xcode_contents_path = FileSpec(xcode_contents_dir);
+ return;
+ }
+ }
+ }
+
+ if (FileSpec fspec = GetXcodeSDK(SDKType::MacOSX)) {
+ if (FileSystem::Instance().Exists(fspec)) {
+ std::string xcode_contents_dir =
+ FindXcodeContentsDirectoryInPath(fspec.GetPath());
+ if (!xcode_contents_dir.empty()) {
+ g_xcode_contents_path = FileSpec(xcode_contents_dir);
+ return;
+ }
+ }
+ }
+ });
+ return g_xcode_contents_path;
+}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits